[swift-evolution] Ad hoc enums / options

Matthew Johnson matthew at anandabits.com
Fri Jun 3 19:07:53 CDT 2016



Sent from my iPad

> On Jun 3, 2016, at 6:20 PM, Greg Parker <gparker at apple.com> wrote:
> 
> 
>>> On Jun 1, 2016, at 5:42 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>>> On Jun 1, 2016, at 5:02 PM, Vladimir.S via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> in other words, we could consider allowing this:
>>>>   func foo(bar: (.fit | .fill)) {
>>>>     baz(bar: bar)
>>>>   }
>>>>   func baz(bar: (.fit | .fill | .florp) { ... }
>>>> 
>>>> In other words, an ad hoc enum T can be used wherever an ad hoc enum U is
>>>> expected if T ⊆ U.
>>> 
>>> Can't agree with this. Just because the same analogue with tuples : differently defined tuples are different types. Tuples with different order of types in declaration - are different types. So I expect here instance of (.fit | .fill) `bar` is not of the same type as (.fit | .fill | .florp)
>> 
>> They are not the same type but there is a structural subtype relationship between them.  All values of type (.fit | .fill) are also values of type (.fit | .fill | .florp).
> 
> What about disjoint types? Some values of type (.fit | .fill) are values of type (.fit | .florp) and some are not. I'm not a type system expert but my understanding is that this capability gets very complicated very fast.

It feels like the only sane way to model these is as union types where each member of the union has a single literal value like '.fit'.  This is where structural subtyping would come from.

In your example I would say there is no subtype relationship there, just as a union of 'Fit | Fill' would not have any subtype / supertype relationship with 'Fit | Florp' in a language like Ceylon that has union types.  

Without the structural subtyping these types would be way too fragile to be considered IMO.

> 
> 
> What about the ABI? This sounds expensive to implement.
> 
> Consider this set of ad-hoc enum types:
> 
>   (.a | .b)
>   (.c | .d)
> 
> Naive implementation: we'll represent these things as ints, with .a=1, .b=2, .c=1, .d=2.
> 
> The naive implementation breaks when a newly-loaded shared library or some library evolution adds this type:
> 
>   (.a | .b | .c | .d)
> 
> In order to provide ABI stability in the face of arbitrary ad-hoc enum types we must ensure that every ad-hoc enum value has a globally unique ABI representation. 
> 
> You could constrain ad-hoc enum values to module or class boundaries and prevent creation of types that use values from different places. For example, if Foundation defines (.a | .b) then you can't define your own ad-hoc enum (.a | .b | .c) that is compatible with Foundation's value for .a. Then the implementation could use ordinary symbols. If usage of ad-hoc enums is not constrained then ordinary symbols don't work because there is no universally agreed-upon place where .a is defined.
> 
> An implementation like ObjC's @selector or C/C++ weak definition would work, but those are expensive in memory overhead and launch time. 
> 
> You could give each linkage unit its own copy of the value that includes a string of the value's name plus an == operator that compares the name strings; that would avoid uniquing but would make some operations slow. 
> 
> In any case the performance of these things will not be comparable to ints nor to typical Swift enums that are encoded as ints.

You bring up very good points.  I'm not saying we *should* do this.  Only that if we do introduce ad-hoc enums this seems like the only sane way to do it.  I would want to be able to declare declare variables, etc that use the type without having every mention of the type break when the author of the function adds a new option.

My opinion is that everything you bring up is a pretty solid argument against ad-hoc enums.  Maybe is Swift ever gets union types we could revisit the idea under that umbrella (but that is sounding unlikely, and is definitely not something that will happen soon).

> 
> 
> -- 
> Greg Parker     gparker at apple.com     Runtime Wrangler
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160603/88e71921/attachment.html>


More information about the swift-evolution mailing list