<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 1, 2016, at 5:42 PM, Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div class=""><br class=""><blockquote type="cite" class="">On Jun 1, 2016, at 5:02 PM, Vladimir.S via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""><blockquote type="cite" class="">in other words, we could consider allowing this:<br class=""> func foo(bar: (.fit | .fill)) {<br class=""> baz(bar: bar)<br class=""> }<br class=""> func baz(bar: (.fit | .fill | .florp) { ... }<br class=""><br class="">In other words, an ad hoc enum T can be used wherever an ad hoc enum U is<br class="">expected if T ⊆ U.<br class=""></blockquote><br class="">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)<br class=""></blockquote><br class="">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).</div></div></blockquote><br class=""></div><div>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.</div><div><br class=""></div><div><br class=""></div><div>What about the ABI? This sounds expensive to implement.</div><div><br class=""></div><div>Consider this set of ad-hoc enum types:</div><div><br class=""></div><div> (.a | .b)</div><div> (.c | .d)</div><div><br class=""></div><div>Naive implementation: we'll represent these things as ints, with .a=1, .b=2, .c=1, .d=2.</div><div><br class=""></div><div>The naive implementation breaks when a newly-loaded shared library or some library evolution adds this type:</div><div><br class=""></div><div> (.a | .b | .c | .d)</div><div><br class=""></div><div>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. </div><div><br class=""></div><div>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.</div><div><br class=""></div><div>An implementation like ObjC's @selector or C/C++ weak definition would work, but those are expensive in memory overhead and launch time. </div><div><br class=""></div><div>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. </div><div><br class=""></div><div>In any case the performance of these things will not be comparable to ints nor to typical Swift enums that are encoded as ints.</div><div><br class=""></div><div><br class=""></div><div>-- </div><div>Greg Parker <a href="mailto:gparker@apple.com" class="">gparker@apple.com</a> Runtime Wrangler</div><div><br class=""></div><div><br class=""></div></body></html>