# \[lang-team-minutes\] Const generics

**URL:** <https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090>\
**Category:** language design\
**Created:** [April 14, 2017, 9:58am UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090 "2017-04-14T09:58:37Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [April 14, 2017, 10:58pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/21 "2017-04-14T22:58:54Z")

</div>

> [@est31](#):
>
> Generally, I would really love it if this feature could arrive on stable as early as possible. End of this year is nice, but it would be nicer if it were already stable by that time.

I want to set expectations realistically here: to stabilize we have an FCP which is usually 6 weeks long, then the feature is in the beta branch, then 6 weeks later its stable. There's a release on January 4, 2018. Targeting stability in that release, we would need to have decided we want it to be stable by October 12, 2017, less than six months from today.

That would give us 6 months to finish the RFC process, do the implementation, get experience using it, make sure the implementation is solid & not buggy, be comfortable that it is ergonomic and comprehensible, discover edge cases, decide what to do about them, and so on. Realistically that cannot happen for a feature as large as const generics.

It will likely be will be implemented on nightly by some time in fall, but I would expect several quarters from then until the feature is ready to stabilize.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [April 14, 2017, 11:05pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/22 "2017-04-14T23:05:15Z")

</div>

> [@christophebiocca](#):
>
> As to treating NaNs as equal at compile time, that's the opposite of their behaviour at runtime, which might be surprising behaviour? On the other hand NaN as a constant time parameter is not likely to see much use, I would think.

Yes; if equality isn't reflexive, though, you could never call a method on a `Foo<NaN>`, because it would not be the same type as the `Foo<NaN>` the method is defined on.

In general its better to think in terms of structural equality (which floats don't have defined today). That is, would `if let NaN = NaN { }` enter the conditional? Its not obvious either way, I think. Of course I agree with other posts that this can be dealt with later and separately from const generics.

---

<div class="post-metadata">

**Author:** ![eddyb](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eddyb/32/8411_2.png) [@eddyb](https://internals.rust-lang.org/u/eddyb)\
**Post date:** [April 14, 2017, 11:06pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/23 "2017-04-14T23:06:24Z")

</div>

It’s worse than that! You can encode non-deterministic computation (or dependent on the host compiler) using float _intermediaries_, but with only integer inputs and outputs.

The plan to deal with that, in the long term, is to use something like LLVM’s APFloat, either through bindings (@edef has had some success there) or wholly converting it to Rust, which implements IEEE 754 semantics in an arbitrary but _host-independent deterministic_ manner (for a given specific version of the compiler).

Anything less can end up with trivial unsoundness, which we should _really_ avoid. See [the related Idris issue](https://github.com/idris-lang/Idris-dev/issues/2609) (that was prompted by a #rust-offtopic discussion more than a year ago).

What we can, even without a better way to evaluate floating-point operations, is to ban floating-point expressions that appear in a type (e.g. `[T; float as usize]`) which also refers to const parameters or associated consts/const fn that are type-parametrized (e.g. `[T; (C as f64 / 0.0) as usize]` or `[U; C + (0.0 / 0.0) as usize]`).

The reason behind that is that a flawed floating-point computation _cannot_ create unsoundness if it happens _only once_ and you _always_ cache the result. This can be done for all constant expressions, _except_ those that need any parameters in order to be evaluated.

_Nothing_ like that can successfully end up in a type in current Rust, even on nightly, so we wouldn’t be breaking _any_ code if we introduce that limitation.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [April 14, 2017, 11:11pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/24 "2017-04-14T23:11:17Z")

</div>

> [@aturon](#):
>
> Also, I find that once a struct takes more than a couple of type arguments, I need to refer to its definition regardless any time I am futzing around with some application. YMMV.

What makes this easier for me (I know this is a common pattern) is to give the params consistent names across different impls and types, so `R` is always the type which implements `Resource` & `S` always implements `Service` and so on. My experience is that once I know "which type" `<T, Q, R, S>` are all, I can understand the signature pretty okay without referring back. (Of course implied bounds also helps here in making each impl primarily list the _new_ bounds it adds.)

Reading things that way, I think having some notation for 'threshing out' the consts and types is helpful. `<T, Q, R, S; N, M>` just seems mildly more readable to me than `<T, Q, R, S, N, M>`. But this does seem like YMMV, and I think other people (validly) interpret the `;` in connection to its semantics in other contexts & other languages.

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [April 14, 2017, 11:19pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/25 "2017-04-14T23:19:29Z")

</div>

FYI: The questions about floats here seem related to the question of whether to allow `match`ing on floats. That was originally allowed, but is currently being deprecated:

> <https://github.com/rust-lang/rust/issues/36890>
>
> This is the summary issue for the illegal\_floating\_point\_constant\_pattern
> future-compatibility warning and other related errors. The goal of
> this page is describe why this...

---

<div class="post-metadata">

**Author:** ![mystor](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mystor/32/6542_2.png) [@mystor](https://internals.rust-lang.org/u/mystor)\
**Post date:** [April 15, 2017, 1:09am UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/26 "2017-04-15T01:09:26Z")

</div>

I understand the reason why it seems silly to use `;` to separate the type and const generics. That being said, I do like the idea of being able to write syntax like:

```rust
struct S<T, U=i32; V: usize, W: usize = 10> { ... }

impl<T; V: usize> S<T; V> { ... }

```

It seems elegant to

a) Allow for const parameters to easily at all places where they are defined or used be separated from type parameters and lifetime parameters b) Follow the same syntax as `[u8; 10]` (although I don’t really care about that that much) c) Allow both optional const and type parameters separately.

I’m not super picky though, although I don’t like the idea that you wouldn’t be able to have a optional type parameter if you have a const parameter, which enforcing the order without `;` would require.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [April 15, 2017, 9:42am UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/27 "2017-04-15T09:42:04Z")

</div>

I think what would mitigate the ‘kind apparentness’ issue is not only having a SHOUTY\_SNAKE\_CASE style preference, but also a strong style preference for making const params actual words, instead of single character identifiers. I think this is a good idea regardless, since const params will be fewer in number and more narrowly ‘meaningful’ in the sense that they can operate at the value level.

For example, we should be talking about `[T; LEN]` instead of `[T; N]`. Given a `BindClient<T, KIND>` its sort of obvious that `T` is a type and `KIND` is a const if people abide this style recommendation.

I still kind of want to have the semicolons if we do this, but I can accept not having them if that’s the majority preference.

@mystor We should be checking for omitted defaults in a context in which we know the kind (lifetime, type, or const) of each parameter; for that reason we can always figure out which _types_ are missing instead of just which _params_ (of any kind) are missing.

---

<div class="post-metadata">

**Author:** ![Uther](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/uther/32/6225_2.png) [@Uther](https://internals.rust-lang.org/u/Uther)\
**Post date:** [April 15, 2017, 9:50am UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/28 "2017-04-15T09:50:09Z")

</div>

> [@withoutboats](#):
>
> The reason I like the semicolon is that if you see Foo\<T, N\>, you can't tell from the use site if T or N are types or consts. Today, lifetimes are distinguished at the use site through the ' syntax. The semicolon helps make that distinction.

This is not really a problem if the convention is to have lower case name for consts. I don't think shouting snake case make sense for const parameter (I'm not sure it make sense for normal const anyway but that's another topic).

IMO const parameters are different from normal const : they are not as much 'constant' since they are 'parameters' : they vary for every use. The ; would solve the problem only in the declaration anyway. Since generics are usually one letter long, they would be easily mistaken for types at first sight in the implementation too. It make much more sense to me to visually see const parameters the same way as immutable variables.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [April 15, 2017, 11:01am UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/29 "2017-04-15T11:01:48Z")

</div>

> [@withoutboats](#):
>
> I think what would mitigate the 'kind apparentness' issue is not only having a SHOUTY\_SNAKE\_CASE style preference, but also a strong style preference for making const params actual words, instead of single character identifiers. I think this is a good idea regardless, since const params will be fewer in number and more narrowly 'meaningful' in the sense that they can operate at the value level.

Just as a data point, in Rayon I used to use words for type parameters (e.g., `ITEM` instead of `T`), but this [was eventually removed](https://github.com/nikomatsakis/rayon/pull/261). It's worth looking over the PR just to get a feeling for what generic code with `UPPERCASE_WORDS` looks like. (I have mixed feelings about changing to single letters; but I'll note that I did try `SnakeCase` as well and I found that actively confusing, since it was hard to distinguish type parameters from actual types.)

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [April 15, 2017, 11:25am UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/30 "2017-04-15T11:25:17Z")

</div>

> [@nikomatsakis](#):
>
> Just as a data point, in Rayon I used to use words for type parameters (e.g., ITEM instead of T), but this was eventually removed.

My first impression from looking through the diff - huge regression in readability.

Maybe it's not so noticeable if you are the code author and know it by heart, but these kind of things are very important when you see the code first time in you life and need to fix it urgently (for some reason this happens with me all the time at work :().

(`ALL_CAPS` types were strange though, I'd use `SnakeCase` as usual for types.)

---

<div class="post-metadata">

**Author:** ![matthieum](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matthieum/32/4023_2.png) [@matthieum](https://internals.rust-lang.org/u/matthieum)\
**Post date:** [April 15, 2017, 11:50am UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/31 "2017-04-15T11:50:59Z")

</div>

I agree with you that lower-case for constants would make distinguishing types and constants a non-issue.

However, it would make using existing `const` values, which have `SHOUTY_SNAKE_CASE`, inconsistent.

The problem is not so much the declaration site as it is the use site: in the use site you have to use an existing constant, and constants today are `SHOUTY_SNAKE_CASE`.

I’d be in favor of moving away from this constant style toward regular `snake_case` (I really don’t see the point of distinguishing them so), but that should be a separate RFC, and seems pretty annoying at this point.

---

<div class="post-metadata">

**Author:** ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)\
**Post date:** [April 15, 2017, 12:15pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/32 "2017-04-15T12:15:31Z")

</div>

I’m also weakly in favor of not using SHOUTY\_SNAKE\_CASE for constants, mostly because in my C++ world shouty snake case is not used for constants, it’s used for macros. To me that usage is as much a warning as it is a disambiguator, and neither Rust macros nor const generics are features that inherently require a warning the way C++ macros are. For me actual constants have always been camel case and I can’t recall it causing any ambiguity problems. While I do use all caps for my type parameters, my type parameters are usually 1-3 letters and never multiple words, so it doesn’t _really_ feel like shouty snake case.

I was on the fence about semicolon-as-kind-separator for a while, but I think I’m convinced now that I’d rather _not_ imbue the semicolon with that special meaning. It doesn’t even work in the single parameter case, there’s a risk of not composing well/being consistent with other kinds, it can’t do nearly as much to disambiguate which parameters are which as good names and a standard style could (both of which are probably mandatory with or without the semicolon rule), I don’t see a need to forbid parameter lists like `Foo<T1, LEN1, T2, LEN2>`, and perhaps most importantly, it feels largely orthogonal to everything else being proposed (unlike the curly braces syntax).

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [April 15, 2017, 3:11pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/33 "2017-04-15T15:11:34Z")

</div>

Yeah I agree. If anything deserves to be `SHOUTEY_SNAKEY`, it’s `static mut`s and `static`s containing some flavor of \*`Cell`: i.e., global mutable variables. Immutable `static`s and `const`s seem totally benign with no reason to attract attention to themselves by loudness. (FWIW, I expressed the same opinion back when the convention was adopted.)

This is somewhat confounded by modules and lifetimes being lowercase, but one convention that might make sense is if `CamelCase` were for “compile-time things”. That would mean normal `const`s, associated `const`s, as well as `const` parameters would be `CamelCase` - _just like types_ - while immutable `static`s would be `snake_case`.

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [April 15, 2017, 3:17pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/34 "2017-04-15T15:17:03Z")

</div>

> [@aturon](#):
>
> We could probably do something like that backwards-compatibly, and the introduction of const parameters would provide a good impetus for doing so. (We'd then also want to allow type for being explicit about type parameters, and just say that leaving off the qualifier defaults to type, and ' implies lifetime.)
> 
> In particular, as we continue to improve elision so that you need explicit lifetimes less often (the lang team has some early thoughts about this), having the explicit syntax become more verbose is not such a big deal.

Yeah, these are _exactly_ the thoughts I had in mind back when I first proposed this syntax. (Together with things like `type<type> F` for higher-kinded types, if/when we get them, and maybe `[type] Ts` for variadic ones, so that all kinds have a consistent prefix notation.)

I'm not sure it would be worth all of the communicational friction to actually _change_ the lifetime syntax at this point, though? (To be honest that possibility hadn't even occurred to me.) It seems like quite a large amount of pain for a rather smallish gain.

---

<div class="post-metadata">

**Author:** ![yazaddaruvala](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/yazaddaruvala/32/4927_2.png) [@yazaddaruvala](https://internals.rust-lang.org/u/yazaddaruvala)\
**Post date:** [April 15, 2017, 9:37pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/35 "2017-04-15T21:37:45Z")

</div>

One thing I feel this thread is lacking is a good/great reason for adding this new syntax to support this feature. The feature itself sounds great, but what benefit does the additional syntax provide? i.e. `impl<T; const N: usize>` vs `impl<T, N: usize>`

It seems like this additional syntax `const` is just unneeded baggage surrounding this feature. If the generic param is a "sized type", then it is very intuitive to know we need to supply a const value of that type. Additionally, if it is not as intuitive as I think, it seems a case where we can have really good error messages and in general docs.

Tying my argument to the [ergonomics inititive](https://blog.rust-lang.org/2017/03/02/lang-ergonomics.html):

> Applicability. Where are you allowed to elide implied information? Is there any heads-up that this might be happening?

While not the most frequently used feature, it will still be used often enough to add unneeded friction while learning but especially as an experienced developer.

> Power. What influence does the elided information have? Can it radically change program behavior or its types?

The proposed syntax has zero influence on program behavior. Regardless of the additional syntax, if the user of this particular generic puts in the wrong value, there would be a compile time error with _hopefully_ good error messages.

> Context-dependence. How much of do you have to know about the rest of the code to know what is being implied, i.e. how elided details will be filled in? Is there always a clear place to look?

Regardless of the additional syntax, the user needs to know the signature of the generic they are trying to use, and likely already has its rustdoc open. The only additional context is that when a "sized type" is a generic parameter it requires a const value during use. While arguably intuitive, this is a very simple rule which only needs to be learned once.

Finally, if a developer has a personal preference to have this distinction in their code: They are not restricted from using comments to add this distinction to their source files. eg. `impl<T, /* const */ N: usize>`

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [April 15, 2017, 10:49pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/36 "2017-04-15T22:49:26Z")

</div>

> [@yazaddaruvala](#):
>
> The feature itself sounds great, but what benefit does the additional syntax provide? i.e. `impl<T; const N: usize>` vs `impl<T, N: usize>`

For one thing, `impl<Foo: SomeTrait>` could mean either a type parameter bounded on `SomeTrait`, or a const parameter whose type is a trait object for `SomeTrait`. Not that the latter is especially useful...

---

<div class="post-metadata">

**Author:** ![notriddle](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/notriddle/32/14082_2.png) [@notriddle](https://internals.rust-lang.org/u/notriddle)\
**Post date:** [April 15, 2017, 11:13pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/37 "2017-04-15T23:13:24Z")

</div>

More importantly, types and constants need to be distinguished at name resolution, before type checking (which relies on data from name resolution) can be performed. You need type check to run before you can tell the difference between a sized type and an unsized type.

---

<div class="post-metadata">

**Author:** ![repax](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/repax/32/1342_2.png) [@repax](https://internals.rust-lang.org/u/repax)\
**Post date:** [April 15, 2017, 11:24pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/38 "2017-04-15T23:24:11Z")

</div>

They are all const parameters, just of different kinds (types, values, lifetimes).

How about another sigil? 😁

```rust
Foo<T=u32, #V=42, 'a>

```

* * *

```rust
Foo<T: Bar, #V: u32>

```

---

<div class="post-metadata">

**Author:** ![bjadamson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjadamson/32/52_2.png) [@bjadamson](https://internals.rust-lang.org/u/bjadamson)\
**Post date:** [April 15, 2017, 11:27pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/39 "2017-04-15T23:27:27Z")

</div>

I’m on a plane on mobile about to take off, but I wanted to add a request for this feature. I would hope it is possible to abstract over const and non-const functions / data structures. Specifically I wouldn’t have to write two versions of a function, one for const parameters and one for normal function parameters (non-const parameters).

I had this thought after reading @yazaddaruvala comment above.

---

<div class="post-metadata">

**Author:** ![marcianx](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/marcianx/32/3249_2.png) [@marcianx](https://internals.rust-lang.org/u/marcianx)\
**Post date:** [April 15, 2017, 11:36pm UTC](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090/40 "2017-04-15T23:36:35Z")

</div>

Wouldn’t that need be supported by [`const fn`](https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md) or some other form of [CTFE](https://users.rust-lang.org/t/what-do-you-want-to-do-with-ctfe/599)?

[Previous page](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090.md?page=1)

[Next page](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090.md?page=3)
