Protocols Should Have Set Features and Aliasing

  1. Why do protocols mimic some properties of sets but not others? We can create empty protocols, conditional conforming protocols , inherited protocols.

  2. We have missing stuff like intersecting protocols where we can conform to the intersection or union of two protocols (edit: typealias Codable = Encodable & Codable) ? Theres no aliasing so if I have a generalized base protocol thats applicable across multiple contexts where the variable name is different, I still have to use the name defined in my base protocol which may actually be not intuitive in code . Yea if I'm conforming to codable , I can change the coding key so I guess thats the best current solution.

  3. How come circular protocols are not part of the protocol design philosophy?

If I understand you correctly then union exists, e.g. typealias Codable = Decodable & Encodable. I don't know what you would use the intersection for, though.

1 Like

I wish I could say more but would be giving too much away.


Codable already provides amazing compile time and run time safety overhead that I think its likely the next steps in the evolution to improve upon generic coding structures (that come with its own set of optimization methods like trees, graphs, strings, etc) whom most of the time have intersecting protocols of use, encryptable/hashable coding keys, aliasing methods , reflectable and deflectable mirrors to streamline the propagation of coded information across any stack whether its mobile, embeddable, server, os, mathematical and web software. The kind of future I see for Swift is nothing more but imagination. Until its express in problems occuring code creation, I don't think what I am saying with make sense. I wish I had a job to do this full-time and ask questions but for now, I can only focus on projects I am doing.

Isn’t the ampersand the intersection? It specifies a type that is a member of both specified types simultaneously. Something like a pipe (|) would be the union and specify, essentially, an Either<T, U> type.

Sure, what you say is correct in the context of union/sum types, but I was thinking of it in terms of, e.g.typealias Codable = Decodable & Encodable meaning that a conforming type has to satisfy the union of the protocol requirements from Decodable and Encodable. The original post implied that meaning to me (“conform to the intersection or union of two protocols”), but perhaps they meant it in the sense you mention, i.e. in terms of the sets of conforming types.

1 Like

Given the use of & it seems obvious to me that the correct meaning is that Codable is the intersection of Encodable and Decodable i.e. it is the set of all types that conform to both protocols.

The other side i.e. the fictional Encodable | Decodable would be the set of types that conform either to Encodable or to Decodable or both. I think the reason it doesn't exist in the language is that it isn't really that useful.

I think it's very useful (although not the example of Encodable | Decodable ;-), and afaik, we just don't have that sort of union types because enums are similar (some might add "more powerful", but I personally think enums with associated values are overrated).

Well one of the ideas for a Int | String syntax that has been pitched before is to have that create some sort of ad-hoc enum with a .int and .string cases. This is similar to what Scala is about to add.

My personal opinion is that that kind of feature is pretty useful. The main argument I saw when going back and rereading the pitches (I was going to pitch the idea after seeing how Scala did it) was that most people thought it would just be better to explicitly declare those kinds of enums.

Can you give a concrete example of where it might be useful?

The issue here is there no automatic promotion of the values into the enum cases:

_: Int | String = "test" // not supported
_: Int | String = .String("test") // the pipe becomes useless

IIRC it might be the case that Swift does not want to allow automatic promotions like this other then for Optional, but I'm not fully sure here.

Now if we had automatic promotion what happens to nested types like:

typealias Test<T> = Int | T
Test<Int | String> // this one has a duplicate
1 Like

Ceylon uses them as base for their optionals.
Because Void | Void | T equals Void | T, they don't have issues like Make try? + optional chain flattening work together

1 Like

Unfortunately, showing what a different language does for optionals is not a concrete example of the use of union protocols. To be clear, I was looking for an example of real world Swift code where this feature would result in better code.

Furthermore, if you read my contributions on the thread you referenced, you'l see I don't regard the current behaviour of try? + optional chaining as being an issue. How it works now is perfectly logical.