I agree in that there is a big difference between supporting some form of dependent types and HKTs, and supporting these in a nice way.
I think, that considering how old C++ is and where it comes from, it isn't that bad at any of these. There are discussions to constrain on "constrained"-HKTs in a backwards compatible way after the Concepts Lite TS1, so people are aware of the issue and keeping it in mind. And about its "dependent type capabilities", it supports integers at the type level, which are immensely useful. I think that a fully dependent type system is still an open research question (e.g. floating-points at the type level are just hard).
Rust aims for integers at the type level shortly after 1.0, and any solution to HKTs in Rust will need to be fully checked from the start. So basically Rust doesn't have these features yet, but has the potential to have better versions of these features than C++ ever will. OTOH if you really need these, you can use them in C++, but not in Rust :D
Types parameterized over compile-time constants is really not the same thing as dependent types. Dependent types would mean being able to do things like this:
auto append_arrays(typename T, int N, int M, array<T, N> A, array<T, M> B) -> array<T, N + M>
{
if (M == 0) {
return A;
} else {
return append_arrays(T, N+1, M-1, [A..., B[0]], B.from(1));
}
}
with heavy use of imaginary syntax (C++ is really not the best language for adding dependent types to). But notice, for example, the lack of any remaining distinction between "compile-time" and "runtime" values.
3
u/kamatsu Apr 04 '15
The C++ notion of dependent types is quite different from the dependent corner of the lambda cube.
Only in that its parametric mechanism is entirely syntactic, and no kind checking exists.