<div dir="ltr">Since this seems to have some interest, I&#39;ve made a gist.<div><br></div><div><a href="https://gist.github.com/griotspeak/963bc87a0c244c120264b11fb022d78c">https://gist.github.com/griotspeak/963bc87a0c244c120264b11fb022d78c</a></div><div><h2 id="introduction" style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif">Introduction</h2><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">This proposal adds/creates syntax to allow ad hoc creation of enums whose members are strict subsets of explicitly defined enums.</p><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Swift-evolution thread: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160530/020025.html" style="color:rgb(13,110,161);text-decoration:none"><ins id="firstdiff" style="display:inline-block;text-decoration:none!important;border:none!important;background-image:none!important"></ins>Discussion thread topic for that proposal</a></p><h2 id="motivation" style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif">Motivation</h2><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Consider a situation where we have an enum <code style="line-height:1">Color</code> which represents the entire set of colors relevant to your application with many salient methods and operations. We have also declared an enum <code style="line-height:1">LCDColorModel</code> with only three colors, <code style="line-height:1">red, blue, green</code> .</p><pre style="margin-top:21px;margin-bottom:21px;color:rgb(17,17,17);font-size:15px;height:183px;background-color:rgb(248,248,248)"><code class="" style="line-height:inherit;display:block;padding:0.5em;color:rgb(51,51,51);height:auto"><span class=""><span class="" style="font-weight:bold">enum</span> <span class="" style="color:rgb(68,85,136);font-weight:bold">Color</span> </span>{
    <span class="" style="font-weight:bold">case</span> red, orange, yellow, green, blue, indigo, violet
    …
}

<span class=""><span class="" style="font-weight:bold">enum</span> <span class="" style="color:rgb(68,85,136);font-weight:bold">LCDColor</span> </span>{
    <span class="" style="font-weight:bold">case</span> red, green, blue
}</code></pre><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">The cases in <code style="line-height:1">LCDColor</code> in our scenario do not require different behavior from their similarly named cases in <code style="line-height:1">Color</code>. We would like, simply stated, to explicitly restrict the cases allowed within a specific portion of our software. There are, currently, a few approaches<br>1. Duplicate functionality in <code style="line-height:1">LCDColor</code><br>- Completely manually<br>- Protocols with ‘minimal’ manual duplication<br>2. Avoid duplication by allowing conversion to <code style="line-height:1">Color</code>. </p><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Neither of these solutions make the subset relationship between <code style="line-height:1">Color</code> and <code style="line-height:1">LCDColor</code> clear or strict.</p><h2 id="proposedsolution" style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif">Proposed solution</h2><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Add syntax to describe a restricted set of cases from an enum. </p><pre style="margin-top:21px;margin-bottom:21px;color:rgb(17,17,17);font-size:15px;height:36px;background-color:rgb(248,248,248)"><code class="" style="line-height:inherit;display:block;padding:0.5em;color:rgb(51,51,51);height:auto"><span class="" style="font-weight:bold">typealias</span> <span class="">LCDColor</span> = <span class="">Color</span>.(red|green|blue)</code></pre><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em"><code style="line-height:1">LCDColor</code> has all of the type and instance methods of <code style="line-height:1">Color</code>.</p><ul style="margin-top:21px;margin-bottom:21px;padding-left:1.5em;color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;font-size:15px"><li style="font-size:17px">Barring any technical reason, the ‘actual’ name of the type, in this example, is <code style="line-height:1">Color.(red|green|blue)</code> This makes the relationship to <code style="line-height:1">Color</code>syntactically clear. If a typealias is not desired, <code style="line-height:1">Color.(red|green|blue)</code> should refer to the same type as <code style="line-height:1">LCDColor</code></li><li style="font-size:17px">Switching over <code style="line-height:1">Color.(red|green|blue)</code> should only need to be exhaustive for the three cases <code style="line-height:1">.red</code>, <code style="line-height:1">.green</code>, and <code style="line-height:1">.blue</code>.</li><li style="font-size:17px">Two initializers should be implicitly created<ul style="margin-top:0px;margin-bottom:0.4em;padding-left:1.5em"><li><code style="line-height:1">Color</code> to <code style="line-height:1">LCDColor?</code><ul style="margin-top:0px;margin-bottom:0.4em;padding-left:1.5em"><li>returns nil for all cases not in <code style="line-height:1">LCDColor</code></li></ul></li><li><code style="line-height:1">LCDColor</code> to <code style="line-height:1">Color</code><ul style="margin-top:0px;margin-bottom:0.4em;padding-left:1.5em"><li>Obvious and trivial implementation mapping cases from <code style="line-height:1">LCDColor</code> to <code style="line-height:1">Color</code></li></ul></li></ul></li><li style="font-size:17px">Casting should be allowed<ul style="margin-top:0px;margin-bottom:0.4em;padding-left:1.5em"><li>from superset to subset only using <code style="line-height:1">as?</code> or <code style="line-height:1">as!</code> syntax.</li><li>from subset to superset using <code style="line-height:1">as</code></li></ul></li><li style="font-size:17px">Creating subsets of subsets is not allowed but reasonable conversions among subsets should be allowed if technically feasible such that:<ul style="margin-top:0px;margin-bottom:0.4em;padding-left:1.5em"><li>Given subsets of <code style="line-height:1">C</code> <code style="line-height:1">A</code> and <code style="line-height:1">B</code>, where A is a superset of B, the casting relationship between <code style="line-height:1">A</code> and <code style="line-height:1">B</code> should be similar to that between <code style="line-height:1">C</code> and either of the other two named subsets.</li></ul></li></ul><h2 id="detaileddesign" style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif">Detailed design</h2><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">While I am unsure of the entirety of the design, I propose that name mangling be used which, along with the declaration order restriction should mean that all possible subsets have a stable and predictable name which contains all of the information necessary to infer cases.<br>If a mangled name approach is taken, the ordering of cases should be sorted to ensure stability.</p><h2 id="alternativesconsidered" style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif">Alternatives considered</h2><ul style="margin-top:21px;margin-bottom:21px;padding-left:1.5em;color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;font-size:15px"><li style="font-size:17px">Do nothing. This feature is not strictly necessary but does allow for expressivity not currently available in the language.</li><li style="font-size:17px">implicitly create properties which convert to superset type.</li></ul><h2 id="impactonexistingcode" style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif">Impact on existing code</h2><p style="color:rgb(17,17,17);font-family:&#39;Helvetica Neue&#39;,Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">This is an additive change which should have no breaking change to existing code.</p></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 3, 2016 at 4:57 PM, Austin Zheng <span dir="ltr">&lt;<a href="mailto:austinzheng@gmail.com" target="_blank">austinzheng@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I really like the idea behind this proposal.<div><br></div><div>Some questions:</div><div><br></div><div>- Would the enum &#39;slice&#39; be a distinct type relative to the base enum?</div><div>- On a related note, would shared cases between the sliced enum and the base enum be implicitly convertible?</div><div>- If they aren&#39;t implicitly convertible between each other, would there be an affordance to perform conversions (e.g. a &quot;parentEnumType&quot; property and an &quot;init?(parentEnumType:)&quot; initializer)/</div><div>- Would you be able to further slice a sliced enum? If so, would they share the same parent, or would the &#39;parent&#39; of the sliced sliced enum be the sliced enum?</div><div>- If the parent enum has members that switch on &#39;self&#39;, would those members be available to the child automatically?</div><div>- What happens if you have two (or more) slices with disjoint members? (e.g. &#39;LCDColors&#39; and &#39;TrafficLightColors&#39;) Would they be considered completely separate &#39;sub-types&#39;?</div><div><br></div><div>Best,</div><div>Austin</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Fri, Jun 3, 2016 at 6:22 AM, T.J. Usiyan via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr"><div>This is loosely related to but not meant to &#39;compete&#39; with the ad hoc enum proposal.</div><div><br></div><div>## Introduction</div><div><br></div><div>This proposal adds/creates syntax to allow ad hoc creation of enums whose members are strict subsets of explicitly defined enums.</div><div><br></div><div>Swift-evolution thread: [Discussion thread topic for that proposal](<a href="http://news.gmane.org/gmane.comp.lang.swift.evolution" target="_blank">http://news.gmane.org/gmane.comp.lang.swift.evolution</a>)</div><div><br></div><div>## Motivation</div><div>Consider a situation where we have an enum `Colors` which represents the entire set of colors relevant to your application with many salient methods and operations. We have also declared an enum `LCDColorModel` with only three colors, `red, blue, green` .</div><div><br></div><div>``` swift</div><div>enum Colors {</div><div><span style="white-space:pre-wrap">        </span>case red, orange, yellow, green, blue, indigo, violet</div><div><span style="white-space:pre-wrap">        </span>…</div><div>}</div><div><br></div><div>enum LCDColors {</div><div><span style="white-space:pre-wrap">        </span>case red, green, blue</div><div>}</div><div>```</div><div><br></div><div>The cases in `LCDColors` in our scenario do not require different behavior from their similarly named cases in `Colors`. We would like, simply stated, to explicitly restrict the cases allowed within a specific portion of our software. There are, currently, a few approaches </div><div><span style="white-space:pre-wrap">        </span>1. Duplicate functionality in `LCDColors` </div><div><span style="white-space:pre-wrap">                </span>- Completely manually</div><div><span style="white-space:pre-wrap">                </span>- Protocols with &#39;minimal&#39; manual duplication</div><div><span style="white-space:pre-wrap">        </span>2. Avoid duplication by allowing conversion to `Colors`. </div><div><br></div><div>Neither of these solutions make the subset relationship between `Colors` and `LCDColors`  clear or strict.</div><div><br></div><div>## Proposed solution</div><div><br></div><div>Add syntax to describe a restricted set of cases from an enum. </div><div><br></div><div>```swift</div><div>typealias LCDColors = Colors.(red|green|blue)</div><div>```</div><div><br></div><div>`LCDColors ` has all of the type and instance methods of `Colors`. Cases must appear in the same order as their original declaration. </div><div><br></div><div><br></div><div>## Detailed design</div><div><br></div><div>While I am unsure of the entirety of the design, I propose that name mangling be used which, along with the declaration order restriction should mean that all possible subsets have a stable and predictable name which contains all of the information necessary to infer cases. </div><div><br></div><div>## Impact on existing code</div><div><br></div><div>This is an additive change which should have no breaking change to existing code.</div><div><br></div><div><br></div></div>
<br></div></div><span class="">_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></span></blockquote></div><br></div>
</blockquote></div><br></div>