I'm new here. My apologies if I make any mistakes.
I saw this proposal on the Swift evolution list on github, and joined just so I could contribute.
Happily, I see that @orobio is already saying much the same thing I was planning to say, though I'd prefer a slightly different syntax.
But it seems to me that a lot of people are ignoring what he's really getting at.
To me, the crux of his suggestion is that it inherently includes a name for the opaque type. Without that, it's difficult to make it clear whether two instances of the opaque type are the same or not. And I believe both answers are sometimes what's desired. Also, without a name for the type, it is difficult to include all the things you might want to say in a where clause.
The main problem I have with his syntax is that using a caret "^" is visually lightweight. Opaque types aren't going to be very common, and I would prefer that they stand out visually. (On my first reading of @orobio's suggestion, I failed to notice the "^" at all.)
In addition, if this is in some sense a dual of a regular generic argument, I think it would be easier for people to understand if it looks's both like and unlike regular generics. So I'd suggest something like:
func makeFoo<<T: Foo>>() -> T { /* ... */}
(In fairness, @orobio did mention something a little like this as a possibility, but it seems to have gone by the wayside.)
This would show that it's similar to regular generics, but different from them. That would be my preference.
It would make is easy to implement the usual where clause syntax, to constrain the type in all the usual ways. And it becomes simple to say both:
func makeTwoTheSame<<T: Foo>>() -> (T, T) { /* ... */}
and
func makeTwoPotentiallyDifferent<<T: Foo, U: Foo>>() -> (T, U) { /* ... */}
It also allows:
func convenienceFunction<<Something: Foo>>() -> Something {
let aFoo = makeFoo()
return aFoo
}
And, perhaps even better, you can say:
struct SomeType<<T: Foo>> {
typealias MyFoo T
static func makeFoo() -> MyFoo { /* ... */}
}
let anotherFoo: Sometype.MyFoo = SomeType.makeFoo()
(I think this will be more commonly used inside a type like this, rather than in a free function.)
I don't show any examples with a where clause, or something like returning two possibly different kinds of collections, which have the same element types, and so forth, but I think it's clear how you could say things like that. It gives the author of a function returning an opaque type the flexibility to be very clear about what is (and is not) being promised.
Now, I currently know nothing about the inside of the compiler, so I don't know how hard this would be to implement, but if this is really just about the same thing as a regular generic, except with the "inside" and the "outside" roles reversed, it doesn't seem to me that it should be unreasonably difficult. (Famous last words!)
I do understand @Chris_Lattner3's preference for something that's easy to search for, but I still prefer this to having any keyword at all. But if it's felt that there absolutely does need to be a keyword, how about something like:
func makeFoo() -> sometype T: Foo { /* ... */}
where a type name must be provided. And then additional uses of the same type could just refer to "T".
<><><><><>
Answering the initial question that started this thread...
I think the general idea is OK if it's extended to always include a name for the type, but without that I think it would paint Swift into a corner. I'd also prefer that it include all the where clause syntax from the start, because otherwise it feels too limited.
As to whether it's really important enough to be worth the change, I'm really not certain. I think folks who have worked on something like the standard library would have a better perspective on that than I do.
I think it fits fairly well with Swift, especially if it used something similar to the syntax I suggested.
I spent several days thinking about this before writing this. I'd think for longer if the deadline weren't fast approaching.