I'd like to drill into this point with a specific example of how this will be confusing. With this proposal, some P
takes on a new meaning that does not overlap with opaque return types and is now context dependent. Imagine the following two function declarations:
// opaque return type, known only to the callee
func makeSomething() -> some P
// sugar for a type variable that you'd normally find in angle brackets
func takeSomething(value: some P)
Depending on which of these functions a user encounters first, they'll decide on what they think some P
means, but later they'll bump their head and realize that it actually depends on the context.
If they encounter makeSomething
first, they'll decide that some P
means a single, concrete, callee-specified type. When they later encounter takeSomething
, they'll realize this can't be true as the callee doesn't construct argument values, so can't possibly be the one to specify their types. some P
must mean something different here, more learning is required.
If they encounter takeSomething
first, they'll decide that some P
de-sugars to a type variable in the function declaration, as if it were written func takeSomething<T: P>(value: T)
. Later when they encounter makeSomething
, they might assume that they could write something like:
let value: MyType = makeSomething()
Which won't compile because some P
in the return position does not de-sugar to a type variable at all. It's not the same as writing func makeSomething<T: P>() -> T
. Head == bonked and queue more learning.
So the idea that users "will need to learn the some
syntax anyways" is false. They'll need to learn two different features which, very unfortunately, share the same keyword.
Putting myself in the shoes of someone who is new to Swift, I think my head would be swimming at this point. Then I inevitably encounter angle bracket type variables (see previous post, they're not going away nor are they "advanced") and I've got to learn that too?? I don't think we're doing them any favors with this proposal.
Side note about the name of the proposal
I think that "Opaque Parameter Declarations" is a misnomer. Generic arguments types are already opaque to the callee, sugaring from <T: P>(value: T)
to value: some P
does nothing to make the type of value
more opaque than it already was. A more appropriate name might be Anonymous Argument Type Variables
, because all we're doing here is obviating the need to name a generic type before you can use it (but only for arguments, not for a return type, because that would clash with opaque return types and will never be possible using the word some
).