> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution > <swift-evolution@swift.org> wrote: > The typed throws discussion brought me back to an old thought. > > I would really like to see a new structural type, similar to tuples, which > act as an anonymous enum. These would actually be a distinct type from enums > (not sure what to call them), in the same way that structs and tuples are > different. They would have a very similar syntax to enums though, so they > would be easy to learn.
This is the commonly-rejected "Disjunctions in type constraints" feature. John. > > There would be two major difference from enums: > > 1) Because they are structural, they can’t have associated functions or > extensions > > 2) They can concatenate with one another freely > > For example: > > func foo( speed: .slow | .med | .fast ){ > bar(speed: speed) > } > > func bar(speed: .slow | .med | .fast | .ludicrous) { > //but we couldn't call foo here because it doesn’t take > .ludicrous > } > > Each case is it’s own mini-type in a way. One ‘.slow’ is equivalent to any > ‘.slow’ (even one from a regular enum). Essentially, it is a loosely bound > group of cases, and type checking just means seeing if the list/value being > passed is a subset of the list of possible cases. > > I’d also like to see sugar for quick conversion from normal Swift enums: > > enum Speed { > case slow > case med > case fast > } > > func foo(speed: Speed | .ludicrous) { > //we can’t call any functions/extensions of Speed, just like we > can’t call a func from int on (Int, Int) > } > > In the above case, Speed gets converted via sugar to “.speed(Speed)” and then > gets concatenated with .ludicrous. Ideally, it would have the added ability > to truly convert to ".slow | .med | .fast | .ludicrous” when passed to > something that doesn’t know about Speed: > > func foo(speed: Speed | .ludicrous) { > switch speed { > case .speed(let s): //Do something with the Speed value > case .ludicrous: //Do something ludicrous > } > bar(speed: speed) //This can convert to pass by unwrapping > Speed to a bag of cases > } > > func bar(speed: .slow | .med | .fast | .ludicrous) { > switch speed { > case .slow: // > case .med: // > case .fast: // > case .ludicrous: // > } > //We can’t reference Speed above because we just passed a bag > of potential cases > } > > > The end result here is that in addition to building one-off enums quickly, it > lets us concatenate and extend enums for use in a limited scope. I don’t > know about you, but I run into the situation of “I want exactly this enum, > but with one extra case” all the time. > > I don’t know if we want typed throws, but this type of quick concatability > would be very useful for adding/merging potential errors. With the same > sugar used on Speed above, it would also allow something similar to Union > types, but without the most of the implementation headache that would cause. > You can take in multiple types, and you get back something you can switch on > to recover the type which was passed: > > func myFakeUnion(_ intOrStr: Int | String){ > switch intOrStr { > case .int(let i): //Do something with int > case .string(let s): //Do something with string > } > } > > myFakeUnion(12) //Sugar! > myFakeUnion(.string(“Hey”)) //This works too > > > Finally, I would love to see the switch equivalent of ‘a ? b : c’ in Swift. > I am not sure what the best syntax would be, but it would essentially work a > bit like like a dictionary: > > let mph = speed ? [.slow:10, .med:35, .fast:75] > > > Thanks, > Jon > > > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution