+1 for the concept, but -1 for the syntax because it doesn't allow explicit constraints, and doesn't scale to multiple opaque types. I quite liked the syntax proposed in the original discussion thread by @anthonylatsis (here: Opaque result types - #88 by anthonylatsis) which explicitly named the opaque "thing" so it could be constrained in a where clause. To summarize what I think the linked post was getting at, it would look like:
func foo() -> some T
where T: Collection, T.Element == Int
{
return [1, 2, 3]
}
This has several advantages. For one, it doesn't require any new syntax for the constraints and instead re-uses the existing where clause that is already familiar. This allows it to scale to multiple types:
func foo() -> (some T, some Q)
where T: Collection, T.Element == Int, Q: Numeric
{
return ([1, 2, 3], 4)
}
And finally it allows opaque constraints to mix with generic constraints (composability!) which I think will be really important for the opaque type concept in general:
func foo<R>(input: R) -> some T
where T: Collection, T.Element == R
{
return [input]
}
I would of course support type inference to allow omission of some or all of the above constraints if they can be inferred from the return type:
func foo() -> some T: Collection
{
// T.Element == Int is inferred
return [1, 2, 3]
}