[swift-evolution] [Pre-Proposal-Discussion] Union Type - Swift 4

Sean Heber sean at fifthace.com
Fri Aug 12 10:16:16 CDT 2016


As an aside, you could use an enum instead of a protocol to avoid the problem of not having exhaustive switches:

enum GeometryValue {
  case point(Point)
  case line(Line)
}

And perhaps (depending on circumstances) you might not even need a Point and Line struct, so you could just put those values inside the enum:

enum GeometryValue {
  case point(x: Float, y: Float)
  case line(x: Float, y: Float, angle: Float)
}

However personally, I think using a protocol is the more Swifty approach to this problem. If I end up not having any common properties or functions that apply to that one umbrella protocol, then I consider that a signal that I’m modeling my solution incorrectly.

l8r
Sean


> On Aug 12, 2016, at 6:24 AM, Maximilian Hünenberger via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi Cao,
> 
> I would be in favor until I find another approach to this problem:
> 
> Consider you have a geometry framework and two types: Point and Line
> 
> An intersection between two lines can be either none, a point or a line (if both are identical).
> 
> The return type would probably be (Point | Line)?
> 
> I've modeled it with an empty protocol "GeometryType". However this has a major disadvantage:
> If you have a general "GeometryType?" you have to cast it in a switch to the specific type.
> In case of (Point| Line)? the switch statement can be checked for exhaustiveness.
> 
> For future directions:
> 
> There should also be a subtype relationship:
> 
> let tu: (T | U) = T()
> let tuv: (T | U | V) = tu // works
> 
> 
> Overloaded functions/operators could also take Union types based on their overloads:
> 
> func take(_ i: Int) -> String { ... }
> 
> func take(_ s: String) -> Int? { ... }
> 
> let value: (Int | String) = "1234"
> let value2 = take(value) // returns (String | Int?)
> 
> Best regards
> Maximilian
> 
> Am 11.08.2016 um 03:28 schrieb Cao Jiannan via swift-evolution <swift-evolution at swift.org>:
> 
>> Hi all,
>> 
>> I want to make a discussion about union type for swift 4.
>> See https://github.com/frogcjn/swift-evolution/blob/master/proposals/xxxx-union-type.md
>> 
>> Add union type grammar, represents the type which is one of other types.
>> 
>> var stringOrURL: String | URL = "https://www.apple.com"
>> Now, if we using the new union type feature, we can declare type conveniently, No other type declaration, and compiler will automatically calculate the common interface.
>> 
>> func input(value: A | B |
>>  C) {
>>     
>> print(value.commonProperty) // type checker will calculate the common interface, developer just use it out of box
>> 
>>     
>> switch
>>  value {
>>     
>> case let value as
>>  A:
>>         
>> // value is type A
>> 
>>         
>> print(value.
>> propertyInA)
>>     
>> case let value as
>>  B:
>>         
>> // value is type B
>> 
>>         
>> print(value.
>> propertyInB)
>>     
>> case let value as
>>  C:
>>         
>> // value is type C
>> 
>>         
>> print(value.
>> propertyInC)
>>     }
>>     
>> // there is no default case other than A, B or C. we already declared that.
>> 
>> }
>> 
>> Note: A, B, C can be either class or protocol, or any other types. This leaves developer more freedom.
>> 
>> 
>> Impact on existing code
>> 
>> 	• This is a new feature, developer who need declare common type will alter to this new grammar.
>> 	• Enum based version optional or IUO will be replaced by Union-based ones. Any optional type will automatically replaced by union type
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list