I like:
enum Option<type T> { ... }
struct Array<type T, const N: usize> { ... }
struct GraphSearch<type<type> T> { frontier: T<Node> }
// and/or:
struct GraphSearch<type T<type>> { frontier: T<Node> }
// and/or:
struct GraphSearch<T<type>> { frontier: T<Node> }
If we wanted perfect symmetry with the value level, the syntax would be Type: Kind
(e.g. T: type
), mirroring Value: Type
(e.g. foo: T
), but that’s already used for trait bounds. I believe the best remaining possibility is this vaguely C+±ish prefix syntax. Here the symmetry is with the syntax of type declarations, which is quite nice in its own right.
Even Haskell is moving away from *
in kind syntax as overly cryptic, introducing the name Type
for the same thing in GHC 8. In Rust the kind of types should just be called type
.
It’s also the default, so the explicit type
kind-annotation in the first two examples is of course purely optional. It also meshes well with const
-generics, as in the second example.
The last three are all equivalent. N.B. I am not suggesting that all three should be supported. They are possibilities. The equivalence between the first two of them can be thought of as currying: the first one being analogous to fn T() -> fn(type) -> type
, and the second one to fn T(type) -> type
. (This extends consistently to types with more parameters, so that e.g. type T<type, type>
, type<type> T<type>
and type<type, type> T
are also all equivalent.) The last two are equivalent simply by extending the "the default kind is type
" rule to "the default ‘return kind’ is type
".
Probably we should choose whether we like the first or second form better, and support only one of them, and if we choose the second then we should also allow the third.
I’m not sure what to do about lifetimes. Maybe we should just introduce the lifetime
keyword and have it work the same way. (So struct Blah<type RefType<lifetime, type>> { blah: RefType<'static, i32> }; type BlahMut = Blah<&mut>;
.) That’s inconsistent with lifetime syntax in the non-higher-kinded case, but type RefType<', type>
is… really bad. (If we had adopted my preferred syntax for lifetimes this wouldn’t be an issue. Alas.)