[HN Gopher] Rust const generics MVP hits beta
___________________________________________________________________
Rust const generics MVP hits beta
Author : mfsch
Score : 240 points
Date : 2021-02-26 16:25 UTC (6 hours ago)
(HTM) web link (blog.rust-lang.org)
(TXT) w3m dump (blog.rust-lang.org)
| simias wrote:
| This is one of my big frustration with Rust and probably the only
| feature from C++ I rally missed (C++ templates having "non-type
| parameters"). I'm very happy to soon see it lifted.
|
| There were workarounds for some common scenarios already, but
| it's just so much more simple and convenient to be able to write
| `fn foo<const N: u32>()`.
|
| I'll finally be able to simplify a significant portion of my
| code.
| tspiteri wrote:
| Lucky you :) In my case the only thing I could to do was to
| change the README of my crate from saying that I plan to
| migrate from typenum to const generics "when they are supported
| by the Rust compiler" to now saying "when the Rust compiler
| support for them is powerful enough". (I need constraints on
| which ranges are allowed, and that is a little hairier than the
| MVP; though typenum is perfectly adequate.)
| jlrubin wrote:
| This is amazing. Kudos rust team for nearing this milestone.
|
| I use rust for a (to be released -- comment with your github if
| you want early access) Bitcoin Smart Contract embedded domain
| specific language (edsl) that operates sort of like a circuit
| meta-programming language. Having const generics will drastically
| simplify my code and enable greater "structural type safety"
| (checked at the rust level rather than as a part of my edsl).
|
| They're not wrong when they say that this is the most highly
| anticipated feature :)
| iamatologist wrote:
| It must be hard to design a zero-cost abstractions language. It
| seems that there are more and more terms and concepts that come
| up in order to support more directly-pragmatic PL features.[1]
| Reminds me a bit of how Haskell comes across to me from the
| outside with all its GHC extensions. Haskell is a research
| language but other more specialized functional languages have the
| luxury of being able to theorize and implement more orthogonal
| and perhaps more "elegant" concepts and approaches. (Again,
| merely an impression from the outside.)
|
| Consider the design effort behind parametric memory allocators.
| That seems like a pretty cutting-edge problem. And yet I bet the
| Rust folks knew that they would want/need to do this way before
| they started doing that work in earnest, because people from C++
| seem to want the same thing (if they don't have it already?).
|
| I idly wonder if one could, if one was in a similar position as
| Rust was some years ago, just go ahead and design a full-on
| unapologetic type-level programming language from the start.
| Because you _know_ that your type-level terms will be worthy of
| the moniker "language" eventually (and it might not be a
| compliment as such).
|
| Just a nice, high-level language that doesn't bother with the
| "bare metal" concepts that Rust the value-level language has to
| deal with. (Can it even be done? Don't ask the peanut gallery
| about that.)
|
| Either that or you accidentally build an emergent language that
| Gankro can write an article about one day titled, I don't know,
| Shitting Your Pants With Higher-Order Unsafe Unwind Type-Level
| Allocator Escape-Suppressing Storm Cellars.
|
| [1] In this case: you have more use for compile-time integers
| than something more general like being able to describe that two
| nat-indexed lists are of the same length, like you can in Idris.
| steveklabnik wrote:
| You might like https://without.boats/blog/revisiting-a-smaller-
| rust/, written by someone on the language team, on this topic.
| doggodaddo78 wrote:
| Super frickn cool! I was dying for this feature.
| sam0x17 wrote:
| This is so huge that it might actually relieve enough of my
| frustration with Rust that I would try using it again <3
|
| Very needed and cool
| CodesInChaos wrote:
| I'm really happy that this finally landed. Unfortunately the
| limitations of the MVP are severe.
|
| For example you can't use associated constant as generic
| arguments, preventing constructions like this:
| trait HashFunction { const OUTPUT_SIZE: usize;
| fn hash(input: &[u8]) -> [u8; Self::OUTPUT_SIZE]; }
| rmdashrfstar wrote:
| What's the progress on supporting something like this in future
| versions?
| steveklabnik wrote:
| https://github.com/rust-lang/rust/issues/76560 is the
| tracking issue for this specific feature.
| SuperFluffy wrote:
| Having const generics will also permit much more elegant
| implementations of low level linear algebra.
|
| For example, when writing a `GEMM` (general matrix
| multiplication) routine, the core building block is a so called
| kernel, which gets moved over the matrices like a stencil. The
| size of the kernel however depends on a) the numerical precision
| (float, double), b) the available SIMD intrinsics, and c) the
| architecture the code is executed on (haswell, skylake or zen
| have different latency and throughput for different intrinsics).
|
| Right now it's surprisingly painful to write an optimal kernel
| and buffer, which is different for every architecture and which
| you need to kind of hardcode. With const generics this should
| become much easier.
| porphyra wrote:
| Yes!!! Linear algebra!
|
| I am a huge fan of nalgebra and having const generics would
| make the API and implementation much nicer.
|
| Hopefully the robotics industry can move towards implementing
| stuff in Rust. Having low level robotics algorithms like state
| estimation and SLAM in Rust makes perfect sense.
| est31 wrote:
| Users of the serde-big-array crate can already opt into using
| min_const_generics by enabling the const-generics feature. The
| advantage: you no longer have to list a bunch of needed array
| sizes (or rely on the builtin defaults), but can use whatever
| size you want.
|
| Serde proper needs something like const_evaluatable_checked
| before it can offer large array support.
| steveklabnik wrote:
| I am extremely excited for this feature, especially now that I
| live in "absolutely no allocations" embedded land.
|
| But also, beyond that, this is pretty much the last major feature
| that I've wanted in Rust. I've got some long-form writing in my
| head about this, but previously, I would have cast it as two or
| 2.5 features:
|
| * const generics
|
| * GATs
|
| * specialization (this is the half)
|
| However, when I've started to think about explaining these sorts
| of things, GATs (and to some degree specialization) feel much
| more to me like a removal of a restriction on combinations of
| features, more than "new features" strictly speaking. I think the
| line between these two perspectives is fascinating. On some
| level, you can even cast const generics in this way too: what
| it's really doing is making arrays a first-class feature of the
| language. I think that's a bigger stretch than GATs though, so I
| am not fully sure I'd make that argument. (The minimum feature
| we're stabilizing now basically does only this, but we do plan on
| going farther, so it feels true on a technicality now but not
| later.)
|
| Regardless, it's been nice to see how much we've slowed down in
| adding major things. November of 2019 was the last time we had a
| feature this large hit stable. 18 months between huge things
| feels much more like the cadence of more mature languages that
| have been around a lot longer than Rust.
|
| There is still a lot of work to do removing restrictions on
| existing features, especially const fn and const generics. But
| Rust is really starting to feel "done" to me, personally.
| thenewwazoo wrote:
| After writing embedded Rust, loving it, and then losing that
| job, I've gotta ask what you're up to these days (mostly so I
| can live vicariously through you). I am _dying_ to write Rust
| in the embedded space again. :)
| cpeterso wrote:
| Steve works at Oxide Computer and they are hiring. :)
|
| https://oxide.computer/careers/software-engineering/
| doggodaddo78 wrote:
| TY, probable Moz Rustacean. :hands together emoji:
|
| I've been living on savings in self-sabbatical mode while
| catching-up on life, projects, and reading while keeping
| current with Rust.
|
| I'm soo itching to jump back into workaholism mode.
| steveklabnik wrote:
| Oh no! Hope you can get back to it soon.
|
| https://oxide.computer/
|
| https://news.ycombinator.com/item?id=23975445 is probably the
| most accessible thing we've talked about publicly with what
| we're doing. (This talk was what made me decide to apply.)
| Still early enough the focus is on building the product
| rather than talking about it to broad audiences like HN.
| doggodaddo78 wrote:
| Hire me! Jumps-up-and-down over-eagerly like a nerdy new
| college grad. I'll wave around cheerleading pompoms or
| aircraft marshaling wands until you do. ; D
|
| Excessive, horn-tooting quasi- resume/cover letter in an HN
| comment (maybe I should've compressed and uuencoded?).
|
| Home: Austin downtown, via much of NorCal { Chico,
| Sacramento, and Bay Area }, from San Jose.
|
| Experience with embedded systems on many architectures and
| different types of RT deadlines, SMT electronics (PCB
| design and fabrication, stuffing, and repair), Rust (I sure
| hope so!), C/C++ (autodidacted at 15), LLVM, several
| assembly languages (ARM, X86, MIPS), microcontrollers,
| large-scale industrial firmware development (automotive,
| mining, & agriculture).
|
| I periodically throw 3D printing and Arduino or ESP32 at
| personal use-cases. And trinocular microscope, Siglent
| scope, and knock-off compatible JBC solder station. The
| Fluke 289 DMM is real though.
|
| Can do everything from sales engineering, on-prem/remote
| custom client integration, customer training, feature
| development, tools support, customer bug forensics,
| subgroup lead SWE, systems architecture/engineering,
| customer solutions development. Make the office more funner
| now and then (especially internal funny 404 pages and
| easter eggs, tape your chair up, orbeez explosion, get your
| wife/SO and kids in on a gaslighting long-con). 5C/ charge
| per instance. Wooden nickels not accepted. No refunds. :)
|
| Did one or two minor humblebragging things:
|
| - Ported a ridiculous nuclear reactor simulator in Fortran
| from UNIX to Windows.
|
| - IBM Almaden offered me a dark matter research assistant
| job when I was 15, but my parents weren't supportive and it
| would've been illegal. :Y U No moon meme here:
|
| - Wrote a Java-- to native MIPS (non-JIT, compile-time)
| compiler from scratch with symmetrical implementations in
| Java and C++.
|
| - Refactored the heck out of a UDP 900 MHz packet radio
| firmware C++ codebase and added telemetry logging with
| error tolerance of Flash EEPROM wear beyond mfgr specs.
|
| - Restoring & modding a VW camper and getting into
| paramotoring (parachute wing and motor on your back).
| steveklabnik wrote:
| Oh hi neighbor! I also live in downtown Austin.
|
| Please apply! We are hiring.
| doggodaddo78 wrote:
| Heck ya! : D I could work on embedded and datacenter gear
| for free if I didn't have bills and a spinning circular
| vinyl noise-makers addiction.
|
| Yeah, I've been pining for highly-integrated, hyperscale
| datacenter metal. Only Fortune 50 corporations and
| partakers of OEMs/ODMs like Quanta QCT / Dell DCS deliver
| somewhat okay customized gear, but not a completely-
| integrated, managed fleet. I remember eGenera BladeFrame,
| but it's still nothing like a hyperscale, intermodal-
| container LEGO datacenter solution.
|
| Oh hey from I-35 and 5th!
|
| Here's your "I probably survived the 2021 ATX
| Icepocalypse" tie-dyed hoodie with black light effects.
| 4ad wrote:
| > Please apply! We are hiring.
|
| You certainly aren't replying to you applicants, though.
| steveklabnik wrote:
| Hm, we should be! Sorry about that. The aim is to reply
| to literally everyone. If you wanna email me, I'm happy
| to look into it.
|
| EDIT: I decided to take a look, and it seems like you
| applied before I joined. My apologies, it must have been
| a mistake.
| 4ad wrote:
| > My apologies, it must have been a mistake.
|
| Well that mistake seems to keep repeating itself then.
|
| Oxide has been silent even after subsequent contact, and
| even after this issue has already been raised internally
| once.
| akavel wrote:
| For me, a feature I'd really hope for is the elusive "if not
| let" (or however this gets named eventually), to let me escape
| the currently unavoidable clutches of Rust's rightwards drift
| and accruing mental context.
| NobodyNada wrote:
| Swift has had 'guard' statements since 2015, and it's the
| biggest thing I miss when programming in Rust:
| guard let x = ... else { // must not fall
| through, so a return, break, throw, non-returning function
| call, etc. is required } // do something with
| x
| yazaddaruvala wrote:
| Lol it would be kinda funny to have this:
| let input: Option<usize> = Some(1); if let
| Some(value) != input { return 0; }
| // use value; such that value: usize = 1
| the__alchemist wrote:
| Could you please post an example of how it helps in embedded /
| no allocator code? I do a good deal of embedded on Rust, but am
| having a tough time figuring out when or why to use this from
| the abstract examples in the article.
|
| Tangent: What's your take on the Rust HALs? (eg `stm32l4xx-
| hal`) etc? I'm curious what the take is of someone outside the
| Github and Matrix communities. They strike me as... remarkably
| underdeveloped, but have big potential.
| steveklabnik wrote:
| > Could you please post an example of how it helps in
| embedded / no allocator code?
|
| In today's Rust, data structures often need to be a fixed
| size, or dynamically allocate. This will let you write a data
| structure that has a variable size, but set at compile time.
| I knocked out a quick ringbuffer recently; I picked a size
| that seemed fine, but that size is fixed at the moment. If I
| had used const generics, it could have been more flexible
| here, I could have written it more easily for any size, where
| the size is written at compile time. This is _not_ my work
| code, but back when I was working on a hobby x86 kernel, I
| did this for a VGA buffer: https://github.com/intermezzOS/ker
| nel/blob/master/vga/src/li... it's generic over "something
| that can be converted to a slice," so that it uses a slice in
| production, but a Vec in tests. This also leads to runtime
| checks https://github.com/intermezzOS/kernel/blob/master/vga/
| src/li... to make sure that the slice is the right size. This
| would be much better written with const generics today. The
| slice trick is neat, but awkward. (This code is also awkward
| because it grew an internal "frame buffer," so it kinda has
| both going on. This example needs const generics less since
| VGA has one single size at compile time ever, but sometimes,
| you need something where this isn't the case, and this was
| the first example of code I personally wrote that springs to
| mind.)
|
| > What's your take on the Rust HALs?
|
| I haven't used them enough. We use the layer below them, for
| example, the stm32f4 crate rather than the stm32f4xx-hal
| crate. That doesn't mean they're bad, I just literally have
| not used them enough to form an opinion. The namesake of this
| space is diversity, and so different people make different
| tradeoffs; we don't really need what those crates are
| offering right now.
| RcouF1uZ4gsC wrote:
| So excited about const generics. Is there any work on variadic
| templates. That is one of the big things I miss from c++.
| Macros can fulfill some of the needs, but not always.
| glittershark wrote:
| I think it probably falls more into the category of removing a
| restriction rather than a new feature, but I'm still waiting on
| HKTs - not for traits (as a former die-hard haskeller, I have
| been gradually converted to the side of "rust doesn't need a
| Monad trait") but for data types. There's a design pattern in
| haskell called "Higher-Kinded-Data"[0] where you parametrize a
| datatype on a type-constructor, and use that to generically
| define either partial or total versions of that data type-
| something like (in rust syntax): struct
| Person<F> { pub name: F<String>, pub
| age: F<u32>, }
|
| where you can then have `Person<Option>` be a person that may
| or may not have all fields filled, and `Person<Box>` be a
| person with all fields definitely filled. This is something I
| find myself reaching for surprisingly frequently when writing
| rust, and I feel like it's a missed benefit of implementing
| higher-kinded types.
|
| [0]: https://reasonablypolymorphic.com/blog/higher-kinded-data/
|
| All that said, I'm really excited to have const generics land!
| Props to all the amazing work by withoutboats and the entire
| rust team.
| adamch wrote:
| Wow, higher-kinded data. I've never heard of that, but it
| would absolutely be useful. E.g. for converting JSON inputs,
| where any field might be missing, into a version of the data
| which definitely has values for all the fields. Or a version
| of the struct where the values are actually read from a
| cache/database.
| twic wrote:
| I proposed using it to model lifecycles of entities:
|
| https://github.com/tim-group/higher-kinded-
| lifecycle/blob/ma...
|
| (in this code, "idea" is a domain concept from the firm i
| worked for at the time - basically a recommendation to buy
| a stock, which is 'opened' on a certain date, and 'closed'
| when it no longer seems like a good recommendation)
|
| My collegues didn't like it, and stuck to using separate
| types for objects in different stages of the lifecycle!
| IggleSniggle wrote:
| TypeScript (as you might expect from a lang built for
| dealing with JS Objects), has really great tooling for this
| kind of type narrowing these days (including on string
| template matching now) and I miss it _so much_ now that I'm
| writing Go.
| glittershark wrote:
| yes! once you use it you start wanting it everywhere, which
| is a big part of why I wish I could do it in Rust
| michael_j_ward wrote:
| This might be of interest to you (this is the second article
| in the series, and they've been good so far)
|
| https://rustyyato.github.io/type/system,type/families/2021/0.
| ..
| meetups323 wrote:
| In TS this would be flipped: type Person =
| { name: string; age: number; }
| type SomeFieldsMissing = Partial<Person>; type
| AllFieldsRequired = Required<Person>; // No real change in
| this case
|
| Where Partial and Required are defined like:
| type Partial<T> = { [P in keyof T]?: T[P] | undefined; }
| type Required<T> = { [P in keyof T]-?: T[P]; }
|
| What would you think of something like this ("mapped types")?
| They can get fairly powerful:
| https://www.typescriptlang.org/docs/handbook/2/mapped-
| types....
| glittershark wrote:
| that seems like something that would only really work with
| a type system that's as structural as TS (vs rust, which is
| very nominal)
| kazoomonger wrote:
| What would happen if I wanted only some fields to be
| required? To borrow from the GP example, something like
| this: struct Person<F> { pub
| name: F<String>, pub age: Option<u32>,
| }
|
| With `Person<Box>` still leaving `age` as optional.
| IggleSniggle wrote:
| Yes, you can do this in typescript, but you can also lie
| about it in typescript. To do it provably, you would
| construct a function that accepted the more generic
| version and then, using type assertions (ie the
| typescript compiler infers the type from declared runtime
| behavior), it would return a narrowed type.
|
| If one caller passes our type narrower with {age:F<u32>}
| then the return value of the function will be narrowed to
| that type, but a broader criteria can still be specified
| for the generic instance.
| meetups323 wrote:
| Yeah there's going to be tradeoffs either way, the
| question is how often they come up in the situations the
| language is designed to target (versus random examples
| designed to showcase some obscure corner of PLT)... In
| this case for TS you might craft your own mappings that
| work like AllButXOptional<Person, 'age'>, or similar. So
| it's controlled externally versus internally, which who
| knows if thats better or not. One benefit of the TS
| approach is that it's a bit more composable... you can
| imagine things like
| OptionalIfRequiredInOther<ComplexPerson, SimplePerson>.
| wizzwizz4 wrote:
| Add an extra generic parameter.
|
| (Also, it shouldn't be Box; you'd want a bog-standard
| generic newtype for this, not an extra heap allocation.)
| glittershark wrote:
| yeah, I picked Box mostly as a pedagogical instance of
| the identity functor that already exists in the stdlib -
| in the real world you'd definitely want `struct
| Identity<F>(F)` instead.
| steveklabnik wrote:
| I like and enjoy HKTs in other languages, but don't feel a
| super strong need for them in Rust. I know some other people
| differ. It is very unclear when, if ever, Rust will get HKTs
| proper. GATs cover a lot of the same ground. We'll see :)
| mamcx wrote:
| I also wish for extensible enums and enum subset:
| pub enum Expr { Int, Str }
| pub enum Expr2 : Expr{ Bool, }
| fn check(??)-> Expr.Int
| mamcx wrote:
| And struct extend!: struct Person {
| id:i32 } struct Customer: Person {
| }
|
| P.D: This is not subclassing, is not redefine all the same
| attributes again and again. Is partially supported to copy
| the values but not defining them.
| proverbialbunny wrote:
| This is a pretty big deal. One benefit it gives is it's much
| easier to write code evaluated at compile time. Most Rust
| libraries use generics, so if you use a library, compile time
| support isn't usually available. By adding support for const
| generics compile time support can become widespread.
___________________________________________________________________
(page generated 2021-02-26 23:01 UTC)