That syntax declares the value of newCount as a default argument for the value parameter, so we can't use literally this syntax. This only works for type parameters indirectly, because a metatype T.Type already exists for every type T, and it only has one possible value T.self, so the metatype parameter acts as a way to force T to be a specific type at a call site. It might be nice to revisit the ability to explicitly provide generic arguments instead of coming up with something bespoke.
Could you clarify what you mean? If Vector has a static var count member, then StrongType.Bytes.count would already work.
The reason I specifically like the current syntax with generic type parameters is that it allows library authors to provide fluent API like a hypothetical:
let new = myVector.padded(toLength: 10, with: 0x5a)
let new2: Vector<10, _> = myVector.padded(with: 0x5a)
whereas with explicitly specified parameters you get the following:
myVector.padded<10>(with: 0x5a)
Which I think is harder to read/understand at a glance.
Yeah I'm suggesting this should be a behavior of all generic parameters not an opt in by each type.
This would at least be a behavioral change for existing code:
struct Generic<Element> {
// This could be a typealias or a nested type
typealias Element = String
}
func take<T>(_: T.Type) {}
// We pass String.self here, not Int.self
take(Generic<Int>.Element.self)
It would also probably be a source break because you couldn't reference Generic.Element anymore because of the generic parameter showing up...? We could make this behavior the default for value generics since they are new, but we couldn't do it immediately for existing generic parameter kinds.
We might not have to go so 'bespoke' for a fluent syntax....
Even if we don't solve the problem here, we should clarify the behavior when we have this sort of thing:
func foo<let x: Int>(_ x: Int) { ... }
Presumably, as proposed, the integer generic parameter is immediately shadowed? Or do we have some sort of weirdness where x means two context-dependent things?
func foo<let x: Int /* x1 */>(_ x: Int /* x2 */) {
let y = Vector<x /* x1 */, Int>(repeating: x /* x2 */)
}
That...might be a bit counterintuitive. Maybe we should forbid it at minimum, and at some later point let it mean the thing that @rauhul is asking for.
This is getting off-topic, but I would take what you have written here as a strong argument in favor of the change.
The act of making a typealias with the same name as a generic parameter, but referring to a different type, is actively hostile to users. It is an anti-pattern.
The fact that making Rauhul’s change would break that type of code, is by itself a good reason to do so, on top of all the other reasons. That type of code is harmful, and ought to be broken.