[swift-evolution] [Pitch] merge types and protocols back together with type<Type, Protocol, ...>

Adrian Zubarev adrian.zubarev at devandartist.com
Fri May 13 11:38:16 CDT 2016

As Thorstan forgot to resend his message to the list, here it is (read below). It should make things about `any<>` more clear.


func f(obj: class<SomeClass,SomeProtocl>) {..}
if obj is class<SomeClass,SomeProtocl> {..}
obj2 = obj as! class<SomeClass,SomeProtocol>
and yes, probably struct<SomeStruct,SomeProtocol>
Why would you want to add all of these different formats where only one could serve them all. This is redundant in my opinion. 

`struct<>` and `enum<>` would have same rules, only the first element would be a different value-type. I might consider this as an alternative.

Correct me if I’m wrong with the redundancy.


The & type operator would produce a “flattened" all<> with its operands.  It could be overloaded to accept either a concrete type or a protocol on the lhs and would produce `type` for an lhs that is a type and `all` when lhs is a protocol.   "Type operators” would be evaluated during compile time and would produce a type that is used where the expression was present in the code.  This is a long-term idea, not something that needs to be considered right now.  It would be way out of scope for Swift 3.  
Which part of your statement is exactly out of scope for Swift 3, “Type operators“ I guess? 

So is it a good idea to add `&` operator for "flattened“ `all<>` whereas “Type operators“ would be a better way to go (for Swift 4 maybe)? As far as I understand the idea behind `&` operator I’m not sure how it could be overloaded, because I thought it would be baked right into the language.

If I mixed something up here please feel free to correct me.


Would you mind to give me some feedback for the rules I've summarized.


The overall feedback seems to be positive so for and my fingers are crossed for this feature to be accepted.

Adrian Zubarev
Sent with Airmail

Am 13. Mai 2016 bei 08:16:51, Thorsten Seitz (tseitz42 at icloud.com) schrieb:

Am 12. Mai 2016 um 22:08 schrieb Adrian Zubarev via swift-evolution <swift-evolution at swift.org>:

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

`all<>` and `any<>` form a pair of complementary type operators, one creating the intersection of the given types (your proposal) and the other creating the union of the given types. As Ceylon has demonstrated that both are really useful I'd like to have both in Swift and therefore would prefer that both should be named such that this duality is visible. Having `type<>` and `any<>` would certainly be possible technically but the naming would not be good.

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

You are right, `any<>` is something different and could be proposed in its own thread. I just wanted to extend the context for finding a good name for `type<>`.

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

    // how would one use value here?
    // what about its properties
    // what will foo return and how to use the result

Ceylon uses flow typing for that (if (is String value) { /* value has type String here */ }).
In Swift the equivalent would be `if let string = value as? String { ... }`:

func foo(value: any<Strint, Int>) -> any<String, Int> {
   if let string = value as? String {
      return string.characters.count
   else if let int= value as? Int {
      return String(int)

A more sensical example using a type union would be the union of two sets:

func union<T, U>(a: Set<T>, b: Set<U>) -> Set<any<T, U>> { ... }

And for type intersection the intersection of two sets:

func intersection<T, U>(a: Set<T>, b: Set<U>) -> Set<all<T, U>> { ... }

(Ceylon's type operators just read better there...)

Another example for type unions:
Ceylon like Swift makes heavy use of optionals but where Swift has a generic wrapper Optional<T> Ceylon just makes use of type unions: in Ceylon T? is syntactic sugar for the type union T | Null where Null is the type having the singleton value null.

FWIW Microsoft's Typescript gained union and intersection types about (I think) a year ago.

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.


`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

Right, `all<>` is just an alternative name for `type<>`. There is no change in functionality.

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

More information about the swift-evolution mailing list