As an interesting data point:
Swift doesn’t support const generics, but even for type parameters, it has a mechanism specifically to avoid the need for explicit function specialization (i.e. turbofish), which it doesn’t support at all.
For example, to do the equivalent of
transmute, you can write:
let transmuted = unsafeBitCast(foo, to: Int32.self)
unsafeBitCast function is declared as
public func unsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U
This works because
Int32.Type is a singleton type with
Int32.self as the sole instance (and that works for any type). However, it requires some special-casing, because
T.Type looks like an associated type, but normally you can’t do type inference backwards from an associated type to the base type. (Associated types in Swift have similar semantics as in Rust.) And for that matter, I find it a bit strange: why can’t you just write
to: Int32? In Rust, the reason you can’t just write a type in expression position is to avoid parser ambiguities with angle brackets, but adding
.self at the end doesn’t help with that (and Swift has a different solution to the angle bracket issue).
But anyway, you can see how it’s nice to put generic parameters into the regular flow of function arguments, allowing for a more natural ordering. Swift probably benefits more from this than Rust would, due to its pervasive use of argument labels - i.e.
cast(value, to: Type) clearly flows better than
cast<Type>(value), but you couldn’t say the same for
cast(value, Type). Still - getting back on topic - when it comes to value parameters (const generics), I think there are more cases where it would be useful.