Simpler syntax for exact-type extensions of generic types

Yes, I think it very much makes sense to have this feature in every case where there's no possibility of confusion between : and ==!

It's particularly problematic that we don't have the feature for type aliases for the reasons outlined by @davedelong.

As I said, I didn't believe it was a likely point of confusion either. However, one must be ready to discard one's preconceptions on the basis of empiric evidence. That it came up here, among users who are quite experienced in Swift, and in short order after the notation was first proposed, indicates to me that this is likely to be a common misunderstanding.

Reading through the previous thread, I find exactly one post asking whether it would mean “Element == Foo” or “Element: Foo”.

The person who wrote that post did not have a misinterpretation, they simply asked what was being proposed.

This entire objection about “misinterpretation” is without basis, and I think it is time to accept the empirical evidence that there is no misinterpretation.

3 Likes

You're quite right--I am not accurately recalling the conversation. There wasn't someone in that thread who mistook A for B, but they were not sure whether the notation meant A or B. That's...not great when the alternative is to require A and B to be spelled out explicitly.

@davedelong and @Slava_Pestov are right in pointing out that in the case of type aliases that used to be concrete types, requiring things to be spelled out sometimes isn't an option.

2 Likes

That person was me.

I did ask that question, but I have my preferred answer. To me, it would be interesting that those declarations were made equivalent:

extension Foo<Bar> { ... }
extensiion Foo where T == Bar { ... }

That is because I see a great interest in following a simple syntactic rule: if a value can have the type T, then extensions to T should apply to this value. Here T should be understood syntactically, as any suite of Swift tokens that can form an expressible type (sorry I lack the précise compiler vocabulary). For example:

let a: Array<Int> = ...
extension Array<Int> { func f() { ... } }
a.f()

// As generally as possible
let x: [Some Type]
extension [Some Type] { ... }

This gemerak rule would have to be specialized for each kind of type declarations, simple types, existentials, gemerics, etc, until as many wrtitable types as possible are covered.

Some extensions would still need to be written with where clause, such as:

extension Foo where T: Bar { ... }

The reason for those orphans extensions is that they can not be covered by the main rule: Foo<Bar> means Foo where T == Bar, period.

The advantage of the rule is that it is extremely easy to understand, because it is syntactic. One does not have to know about the subtleties of the type system. If you can write let x: T, then you can write an extension T that will apply to x. Simple.

10 Likes

Has there been any further motion, or did this peter out? Just hit a place today I would have loved to use extension Range<Int> rather than the more verbose version.