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

Vladimir.S svabox at gmail.com
Fri Aug 19 08:36:10 CDT 2016


On 19.08.2016 14:51, Haravikk via swift-evolution wrote:
> When dealing with your own types, sure, but if you're talking about
> standard types or types from other libraries then it would mean extending
> them with whatever it is you actually need, which I'm not sure is the best
> way to do it. Type unions are much simpler, and keep all of the code within
> a single function.
>
> To give a simplistic example, consider a method for adding a property to a
> property list file. I'm going to trim this down considerably, but it'll
> give an idea hopefully:

FWIW, This reminds me a discussion about ad-hoc(anonymous) enums, we had in 
the list. There were also examples when such ad-hoc enums could be useful 
within a function/small block of code:

  func scaleAndCropImage(
      image: UIImage,
      toSize size: CGSize,
      *operation: (.fit | .fill) = .fit*
      ) -> UIImage {


var codePath : (.one | .two | .three) = .one
switch codePath {
   case .one : ...
   case .two : ...
   case .three : ...
}

etc..

And AFAIR there was no wide support for this feature.
I don't feel like we need the union type as proposed, but I do would like 
to see such ad-hoc enums in Swift probably with support of associated type 
for cases, like here:

func addProperty(key:String, value: (.int(Int) | .string(String) | 
.text(String)), file:NSFile) {
..
}

so, value will be a standard enum with 3 cases .int/.string/.text, with 
associated types. IMO this approach is more powerful and useful, *probably* 
easily to implement than Union types, use already existed abstraction of 
'enum' etc.

Opinions?

>
> func addProperty(key:String, value:Int | String, file:NSFile) {
> var xml = "<key>\(key)</key>\n"
> switch value {
> case value as Int:
> xml += "<number>\(value)</number>\n"
> case value as String:
> xml += "<string>\(value)</string>\n"
> }
>
> // Actually store the xml string in the file here
> }
>
> Currently you might instead do this like:
>
> func addProperty(key:String, value:Int, file:NSFile) {
> addProperty(key: key, rawValue: "<number>\(value)</number>", file: file)
> }
> func addProperty(key:String, value:String, file:NSFile) {
> addProperty(key: key, rawValue: "<string>\(value)</string>", file: file)
> }
> func addProperty(key:String, rawValue:String, file:NSFile) {
> var xml = "<key>\(key)</key>\n\(rawValue\)\n"
> // Actually store the xml string in the file here
> }
>
> (apologies for typos, not at my main computer right now, this is just for
> illustration anyway)
>
> Of course if I were doing a complex property list bridge I would extract
> some of this out, but if the above is all I need then IMO the union example
> is more convenient to work with, and produces less pollution of the
> addProperty signature, while the compiler can still optimise it out into
> separate functions (by eliminating the switch for each type).
>
> I could alternatively use a protocol to add a .plistValue computed property
> to all plist compatible types, but again that seems like overkill, and
> moves the code out of my single function even though that may be all I
> really need, it also makes it less clear what all of those types are
> (without building docs to do so). Or I could use an enum, but again, for
> small use cases that can be a bit overkill, and isn't as convenient in
> cases that have similar, but different, union types.
>
>
> Ultimately it's an issue of choice; not every case will be better using or
> not using union types, they're just a convenience that can benefit some
> cases. If you find yourself using the same union types a lot then, yes,
> probably time to think about a protocol or an enum, but that's a big step
> in simpler cases.
>
>> On 19 Aug 2016, at 08:42, Xiaodi Wu <xiaodi.wu at gmail.com
>> <mailto:xiaodi.wu at gmail.com>> wrote:
>>
>> But you can do that already with protocols, can't you?
>> On Fri, Aug 19, 2016 at 2:24 AM Haravikk via swift-evolution
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>
>>     I'm a +1 for union types.
>>
>>     My main reason for wanting it is to eliminate (some) function
>>     overloads; behind the scenes the compiler may still produce one
>>     compiled function per union type (for performance), but at a high
>>     level we only need to worry about one implementation, and one call
>>     signature, which I think is a good thing.
>>
>>>     On 11 Aug 2016, at 02:28, Cao Jiannan via swift-evolution
>>>     <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>
>>>     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 <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
>>>
>>>
>>>         ________
>>>         <https://github.com/frogcjn/swift-evolution/blob/master/proposals/xxxx-union-type.md#detailed-design>
>>>
>>>     _______________________________________________
>>>     swift-evolution mailing list
>>>     swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>     https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>     _______________________________________________
>>     swift-evolution mailing list
>>     swift-evolution at swift.org <mailto: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