Generic Protocols
Generic protocols are a major gap in Swift's current generics and opportunistically giving them up in favor of a syntactic sugar for a completely different feature that could be expressed syntactically at a minimal cost using existing syntactic elements via <.T == …>
would be a huge mistake, imho.
Unification
That's because the T
of Array<T>
and Array.Element
are two completely different things serving two completely different purposes and roles in the language, which are strictly orthogonal to each other. Of course they are used and spelled differently. It would be bad if they weren't.
- Generic arguments are passed in by the user of a generic type and provided at the time of its instantiation (i.e.
Array<T>
->Array<Int>
). - Associated types are returned out by the specific instantiation of a generic type at the time of its declaration (i.e.
typealias = …
).
If generic types/kinds were functions of the type system, mapping from a generic abstract type to a concrete type, then …
- … generic arguments would be the inputs of such a function.
- … associated types would be the outputs of such a function.
So not only would such a unification conflate two orthogonal concepts that cannot be used interchangeably into a single syntax, it also introduces a major inconsistency by doing so:
Every existing use of "instantiate a generic type" (i.e. pass a set of types as its input) in Swift (that I'm aware of) is using <T>
.
Every existing use of "constrain a generic type" (i.e. retrieve a set of types as its output) in Swift (that I'm aware of) is using where T == _
.
Just imagine for a second a hypothetical and admittedly silly proposal that wanted to unify the passing of inputs and the returning of outputs for a function into a single syntax and went something like this:
We propose that instead of passing values to a function via
foo(42, "bar")
and obtaining its output vialet baz = foo(…)
you can now dolet foo(42, "bar", baz)
, where42
and"bar"
are the inputs tofoo(…)
andbaz
is its output (i.e. a local binding), resulting in a unified syntax.
A proposal like this would be shut down immediately, if not outright ridiculed, as it would be conflating two orthogonal concepts (inputs vs. outputs) into a shared syntax and effectively would make it impossible to know the semantics implied by (…)
without looking up the function signature. Even though it effectively proposes the same thing proposed here: unify syntax of inputs and outputs of a function (on a kind), making them look the same, even though they are orthogonal. It's just that the semantics of "function of types" is familiar to most us, while the semantics of "function of kinds" is somewhat more obscure, yet rally not that different. What's bad in one context is similarly bad in the other.