[swift-evolution] Ad hoc enums / options

Greg Parker gparker at apple.com
Fri Jun 3 18:20:18 CDT 2016


> 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.


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.


-- 
Greg Parker     gparker at apple.com <mailto:gparker at apple.com>     Runtime Wrangler


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160603/445b49d7/attachment.html>


More information about the swift-evolution mailing list