[swift-evolution] Making `.self` After `Type` Optional

Joe Groff jgroff at apple.com
Thu Mar 10 11:19:04 CST 2016

> On Mar 9, 2016, at 3:03 PM, Tanner Nelson <me at tanner.xyz> wrote:
> "our type system is sufficiently stronger than that other language..."
> I was just writing a response that said exactly this. It's really impossible in Swift to be unknowingly sending the wrong types around. 
> If the agreement seems to be leaning toward figuring out a way to remove `.self`, what would the next steps be to start concretely seeing which implementations might work / be realistic?

I see two problems to solve:

A) Decide a grammar rule to distinguish the operator '<' from the generic parameter bracket, and
B) Decide a semantic rule to distinguish type "operators" like '[T]', 'T?', etc. from value operations.

For (A), we should look at the new places a generic type might appear in expressions:

- By itself:

let x = Foo< T >
bar() // following statement

let y = Foo< T, U >
bar() // following statement

This doesn't strike me as a huge problem to parse as a type reference, since 'a < b > c' is unlikely as an expression, and we don't have commas in the top level of the grammar, so 'a < b, c > d' is impossible as a top-level expression. Extending the lookahead rule to include `>;` or `> *token on next line*` as disambiguators is probably OK.

- As a function parameter, or array or dictionary element:

load(Foo<T>, atOffset: 8)
let types = [Foo<T>, Bar<U>]
let factories = [Foo<T>: makeFoo, Bar<U>: makeBar]

This is probably the most common use case for type references, and the easiest to support, since the parameters are always followed by a token that can't start an expression by itself. We could extend the current lookahead rule to ensure it includes `>)`, `>,` and `>:`.

- As the parameter to an operator:

++Foo<T> // prefix
Foo<T>++ // postfix
Foo<T>+Bar<U> // infix
Foo<T> + Bar<U>
let foo = Bar<U>

This one's a bit interesting since `>+` or `>++` could be operators themselves. Applying operators to types might not be a compelling enough reason to block the other changes, though.

For (B), as I mentioned before, it makes the choice between [T] becoming 'Array<T>' or becoming an array containing 'T' a bit of an overload resolution problem. In most cases we can probably favor the type sugar, either by argument type context or by syntactically recognizing `T` as a static type reference and favoring the type sugar interpretation over the array literal implementation. Doug or Joe Pamer probably have opinions here.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160310/55265a81/attachment.html>

More information about the swift-evolution mailing list