<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=""><div class="">Where I’m going with my line of though is:</div><div class=""><br class=""></div><div class="">1. Extensible enums probably aren’t going to happen, for reasons mentioned earlier.</div><div class=""><br class=""></div><div class="">2. I don’t really see the protocol+structs approach as “emulating enums” at all. IMO, separate types are a more accurate model of what’s going on with the example you gave. (The computed properties insight is a clue that they’re different types.)</div><div class=""><br class=""></div><div class="">…BUT…</div><div class=""><br class=""></div><div class="">3. If there is indeed a situation where the protocol+structs approach falls short, then we should identify it, because there might be a good language proposal in it.</div><div class=""><br class=""></div><div class="">Cheers, P</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 30, 2016, at 5:32 PM, Dan Appel &lt;<a href="mailto:dan.appel00@gmail.com" class="">dan.appel00@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Paul,<div class=""><br class=""></div><div class="">I should have came with an example where enums with associated types beat out a protocol-oriented approach, but I can't think of any off the top of my head. My gut tells me that trying to emulate enums through other constructs to get more functionality means that the language has failed you, but maybe this is not one of those cases.&nbsp;</div><div class=""><br class=""></div><div class="">Really I just want to use enums as much as possible, and I enjoy the first-class support they get in the Swift language (especially compared to other languages). If I can use an enum instead of a struct or class, I almost always will, and I'm just trying to fix one of the cases where its simply not possible due to language limitations.<br class=""></div><div class=""><br class=""></div><div class="">Dan</div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, Jun 30, 2016 at 3:14 PM Paul Cantrell &lt;<a href="mailto:cantrell@pobox.com" class="">cantrell@pobox.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 30, 2016, at 4:43 PM, Dan Appel &lt;<a href="mailto:dan.appel00@gmail.com" target="_blank" class="">dan.appel00@gmail.com</a>&gt; wrote:</div><br class=""><div class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class=""><blockquote type="cite" class="">If you’re looking to have associated type-like behavior _and_ open cases, then yes, this “unique instances” approach breaks down. At that point, though, why not just use a collection of separate struct types implementing a shared protocol?</blockquote></div><div class=""><br class=""></div></div><div dir="ltr" class=""><div class="">Yes, as I mentioned in the draft, this is as close as you get to associated values on enum cases. However, I think that enums better represent user intent + have better language support.</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">You could make the case that they better represent intent. Not totally sold on that, but I could see the argument.</div><div class=""><br class=""></div><div class="">What’s an example of “better language support?” Is there a specific situation where this approach doesn’t work well, but would if it were instead an enum with associated types?</div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">public</span><span class="">&nbsp;</span><span style="color:rgb(50,62,125)" class="">protocol</span><span class="">&nbsp;FileError:&nbsp;</span><span style="color:rgb(88,126,168)" class="">ErrorProtocol</span><span class="">&nbsp;{ }</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;min-height:12px" class=""><span class=""></span><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">struct</span><span class="">&nbsp;FileNotFound:&nbsp;</span><span style="color:rgb(88,126,168)" class="">FileError</span><span class="">&nbsp;{</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">let</span><span class="">&nbsp;path:&nbsp;</span><span style="color:rgb(88,126,168)" class="">String</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;min-height:12px" class=""><span class=""></span><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">struct</span><span class="">&nbsp;CorruptedFile {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">let</span><span class="">&nbsp;bytes: [</span><span style="color:rgb(88,126,168)" class="">Int8</span><span class="">]</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;min-height:12px" class=""><br class=""><span class=""></span></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">The guarantee of exhaustive case matching is the only big difference I can think of. Remove that, and there’s not much difference in practice with this:</div><div class=""><br class=""></div><div class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""></div></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span style="color:#323e7d" class="">func</span><span class=""> handleFileError(error: </span><span style="color:#587ea8" class="">FileError</span><span class="">) {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; </span><span style="color:#323e7d" class="">switch</span><span class="">(error) {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;color:rgb(88,126,168)" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:#323e7d" class="">case</span><span style="" class=""> </span><span style="color:#323e7d" class="">is</span><span style="" class=""> </span><span class="">CorruptedFile</span><span style="" class="">:</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:#587ea8" class="">print</span><span class="">(</span><span style="color:#843e64" class="">"Bummer"</span><span class="">)</span></div></div></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:#323e7d" class="">case</span><span class=""> </span><span style="color:#323e7d" class="">let</span><span class=""> error </span><span style="color:#323e7d" class="">as</span><span class=""> </span><span style="color:#587ea8" class="">FileNotFound</span><span class="">:</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:#587ea8" class="">print</span><span class="">(</span><span style="color:#843e64" class="">"Can’t find </span><span class="">\</span><span style="color:#843e64" class="">(</span><span class="">error.</span><span style="color:#587ea8" class="">path</span><span style="color:#843e64" class="">)"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:#323e7d" class="">default</span><span class="">:</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:#323e7d" class="">break</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; }</span></div><div class=""><span class=""><br class=""></span></div></div></div><div class="">…vs this:</div><div class=""><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">func</span><span class="">&nbsp;handleFileError(error:&nbsp;</span><span style="color:rgb(88,126,168)" class="">FileError</span><span class="">) {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">switch</span><span class="">(error) {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">case</span><span style="" class="">&nbsp;</span><span class=""><font color="#323e7d" class="">.</font></span><span style="color:rgb(88,126,168)" class="">corruptedFile</span><span style="" class="">:</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span style="color:rgb(132,62,100)" class="">"Bummer"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">case</span><span class="">&nbsp;<font color="#323e7d" class="">.</font></span><span style="color:rgb(88,126,168)" class="">fileNotFound(let path)</span><span class="">:</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span style="color:rgb(132,62,100)" class="">"Can’t find&nbsp;</span><span class="">\</span><span style="color:rgb(132,62,100)" class="">(</span><span style="color:rgb(88,126,168)" class="">path</span><span style="color:rgb(132,62,100)" class="">)"</span><span class="">)</span></div><div style="font-family:Menlo;font-size:10.5px;margin:0px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">default</span><span class="">:</span></div><div style="font-family:Menlo;font-size:10.5px;margin:0px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">break</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; }</span></div><div class=""><span class=""><br class=""></span></div><div class=""><span class="">But maybe there’s a situation I’m missing where things really would be much easier if it were an enum?</span></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><span class=""><br class=""></span></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class="">You can definitely emulate the extensible feature using other language constructs, but after all you can also emulate generics using Any (how java does it).</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">That’s not a good analogy. Leave aside “emulate generics using Any” is not really a good description of Java’s compile-time-only generic types. In the case of using different struct types for error, you’re not sacrificing any sort of compile-time safety over enums with associated types, whereas [Any] everywhere inevitably involves unsafe casting.</div><div class=""><br class=""></div><div class="">Cheers, P</div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class="">In this case I think its helpful to have first-class language support.</div><div class=""><br class=""></div><div class="">Dan</div><div class=""><br class=""></div><div class=""><br class=""></div></div><div class="gmail_quote"><div dir="ltr" class="">On Thu, Jun 30, 2016 at 2:27 PM Dan Appel &lt;<a href="mailto:dan.appel00@gmail.com" target="_blank" class="">dan.appel00@gmail.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="">David,&nbsp;</div><div class=""><br class=""></div>Yeah, that's what I'm worried about. I was meaning to ask some engineers about the implementation of this during WWDC (hence why I didn't send it out), but didn't get a chance to do so.&nbsp;</div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, Jun 30, 2016 at 2:09 PM David Waite &lt;<a href="mailto:david@alkaline-solutions.com" target="_blank" class="">david@alkaline-solutions.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 30, 2016, at 2:54 PM, Dan Appel via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">Paul,<div class=""><br class=""></div><div class="">That is the current workaround (as the proposal mentions), but it is still missing support for enum features such as associated values and the pattern matching power that they bring.</div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class="">I don’t believe a developer would be able to extend an enum to support arbitrary associated values, the same as the limitation that one cannot extend a type today to have extra members. Value types need to have an understood size and structure at compile time of the file/module that they are in.</div></div><div style="word-wrap:break-word" class=""><div class=""><br class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class=""><br class=""></div><div class="">Dan</div></div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr" class="">On Thu, Jun 30, 2016 at 1:42 PM Paul Cantrell &lt;<a href="mailto:cantrell@pobox.com" target="_blank" class="">cantrell@pobox.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">While it doesn’t give all the “raw value” functionality of enum, it’s possible to use object instance uniqueness to get enum-like behavior that can be extended:</div><div class=""><br class=""></div><div class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">public</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">protocol</span><span class=""><span class="">&nbsp;</span>OpenEnum:<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">class</span><span class="">,<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Hashable</span><span class=""><span class="">&nbsp;</span>{ }</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;min-height:12px" class=""><span class=""></span><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;color:rgb(50,62,125)" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span></span><span class="">extension</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">OpenEnum</span><span class=""><span class="">&nbsp;</span>{</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">public</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">var</span><span class=""><span class="">&nbsp;</span>hashValue:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Int</span><span class=""><span class="">&nbsp;</span>{</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;color:rgb(88,126,168)" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">return</span><span class=""><span class="">&nbsp;</span></span><span class="">ObjectIdentifier</span><span class="">(</span><span style="color:rgb(50,62,125)" class="">self</span><span class="">).</span><span class="">hashValue</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;min-height:12px" class=""><span class=""></span><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">public</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">func</span><span class=""><span class="">&nbsp;</span>==&lt;T:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">OpenEnum</span><span class="">&gt;(lhs:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">T</span><span class="">, rhs:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">T</span><span class="">) -&gt;<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Bool</span><span class=""><span class="">&nbsp;</span>{</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">return</span><span class=""><span class="">&nbsp;</span>lhs === rhs</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div></div><div class=""><span class=""><br class=""></span></div><div class=""><span class="">A library can provide:</span></div><div class=""><span class=""><br class=""></span></div><div class=""><span class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;color:rgb(88,126,168)" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span style="color:rgb(50,62,125)" class="">public</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">final</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">class</span><span class=""><span class="">&nbsp;</span>Color:<span class="">&nbsp;</span></span><span class="">OpenEnum</span><span class="">,<span class="">&nbsp;</span></span><span class="">CustomStringConvertible</span><span class=""><span class="">&nbsp;</span>{</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">public</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">let</span><span class=""><span class="">&nbsp;</span>description:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">String</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;min-height:12px" class=""><span class=""></span><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">public</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">init</span><span class="">(description:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">String</span><span class="">) {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">self</span><span class="">.</span><span style="color:rgb(88,126,168)" class="">description</span><span class=""><span class="">&nbsp;</span>= description</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;min-height:12px" class=""><span class=""></span><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;color:rgb(50,62,125)" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span class="">static</span><span class=""><span class="">&nbsp;</span></span><span class="">let</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>black =<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Color</span><span class="">(description:<span class="">&nbsp;</span></span><span style="color:rgb(132,62,100)" class="">"black"</span><span class="">),</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>white =<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Color</span><span class="">(description:<span class="">&nbsp;</span></span><span style="color:rgb(132,62,100)" class="">"white"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div><div class=""><span class=""><br class=""></span></div><div class=""><span class="">And then in a client project:</span></div><div class=""><span class=""><br class=""></span></div><div class=""><span class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;color:rgb(50,62,125)" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span class="">extension</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Color</span><span class=""><span class="">&nbsp;</span>{</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo;color:rgb(50,62,125)" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span class="">static</span><span class=""><span class="">&nbsp;</span></span><span class="">let</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>puce =<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Color</span><span class="">(description:<span class="">&nbsp;</span></span><span style="color:rgb(132,62,100)" class="">"puce"</span><span class="">),</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>mauve =<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Color</span><span class="">(description:<span class="">&nbsp;</span></span><span style="color:rgb(132,62,100)" class="">"mauve"</span><span class="">),</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>fuchsia =<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">Color</span><span class="">(description:<span class="">&nbsp;</span></span><span style="color:rgb(132,62,100)" class="">"fuchsia"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div><div class=""><span class=""><br class=""></span></div><div class="">(This is how Siesta provides an extensible set of pipeline stages.<span class="">&nbsp;</span><a href="https://github.com/bustoutsolutions/siesta/pull/64" target="_blank" class="">https://github.com/bustoutsolutions/siesta/pull/64</a>)</div><div class=""><span class=""><br class=""></span></div><div class=""><span class="">With this approach, you still get the .member shortcut in some circumstances:</span></div><div class=""><span class=""><br class=""></span></div><div class=""><span class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><span style="color:rgb(50,62,125)" class="">&nbsp; &nbsp;<span class="">&nbsp;</span>let</span><span class=""><span class="">&nbsp;</span>eyebleedPalette: [</span><span style="color:rgb(88,126,168)" class="">Color</span><span class="">] = [.fuchsia, .black, .mauve]</span></div></span></div><div class=""><span class=""><br class=""></span></div><div class=""><span class="">…but not in others:</span></div></span></div></span></div><div class=""><br class=""></div><div class=""><div style="margin:0px;font-size:10.5px;line-height:normal;font-family:Menlo" class=""><div style="margin:0px;font-size:10.5px;line-height:normal;color:rgb(102,139,73)" class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span class="">// Compiles</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">switch</span><span class="">(</span><span style="color:rgb(88,126,168)" class="">color</span><span class="">) {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">case</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class=""><b class="">Color</b></span><span class="">.red:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span style="color:rgb(132,62,100)" class="">"Danger!"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">case</span><span class=""><span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class=""><b class="">Color</b></span><span class="">.mauve:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span style="color:rgb(132,62,100)" class="">"Dancing!"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;color:rgb(132,62,100)" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">default</span><span class="">:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span class="">"Nothing notable"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;min-height:12px" class=""><span class=""></span><br class=""></div><div style="margin:0px;font-size:10.5px;line-height:normal;color:rgb(102,139,73)" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span></span><span class="">// Does not compile</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">switch</span><span class="">(</span><span style="color:rgb(88,126,168)" class="">color</span><span class="">) {</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">case</span><span class=""><span class="">&nbsp;</span>.red:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span style="color:rgb(132,62,100)" class="">"Danger!"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">case</span><span class=""><span class="">&nbsp;</span>.mauve:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span style="color:rgb(132,62,100)" class="">"Dancing!"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal;color:rgb(132,62,100)" class=""><span class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span></span><span style="color:rgb(50,62,125)" class="">default</span><span class="">:<span class="">&nbsp;</span></span><span style="color:rgb(88,126,168)" class="">print</span><span class="">(</span><span class="">"Nothing notable"</span><span class="">)</span></div><div style="margin:0px;font-size:10.5px;line-height:normal" class=""><span class="">&nbsp; &nbsp;<span class="">&nbsp;</span>}</span></div><div class=""><span class=""><br class=""></span></div></div></div><div class="">Given that this already comes close to giving the sort of functionality one would want out of an extensible enum, perhaps it’s better to fill out the gaps in this approach instead of adding a new language feature? This would have the advantage of not adding a keyword, and presumably provide useful behaviors that generalize to patterns other than extensible enums.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class=""><br class=""></div><div class="">Paul</div></div><div style="word-wrap:break-word" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 30, 2016, at 3:23 PM, Guillermo Peralta Scura via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class=""><div class=""><div dir="ltr" class="">I think the approach taken by your proporsal is really good. Would love to have that feature for the language.<div class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">El jue., 30 jun. 2016 a las 16:19, Edward Valentini via swift-evolution (&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;) escribió:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="auto" class=""><div class=""></div><div class=""><br class=""></div><div class="">I really like the idea of making it opt in with the extensible keyword as opposed to opt out with final so this way there is no impact on existing code&nbsp;</div></div><div dir="auto" class=""><div class=""><br class="">On Jun 30, 2016, at 16:15, Dan Appel &lt;<a href="mailto:dan.appel00@gmail.com" target="_blank" class="">dan.appel00@gmail.com</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">I've had a draft of a proposal lying around for a while which addresses exactly this, but I haven't gotten around to sending it out for comments yet.<span class="">&nbsp;</span><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5" target="_blank" class="">Link</a>.<div class=""><br class=""></div><div class="">Would appreciate if you guys took a look.</div><div class="">Dan Appel<br class=""></div><div class=""><br class=""><div class="">Pasted inline below<br class=""><div class=""><br class=""></div><div class=""><h1 style="font-size:2.25em;margin:0px 0px 16px;line-height:1.2;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol'" class="">Extensible Enums</h1><ul style="padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class=""><li class="">Proposal:&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">SE-NNNN</a></li><li class="">Author:&nbsp;<a href="https://github.com/danappelxx" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">Dan Appel</a></li><li class="">Status:&nbsp;<span class=""><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5#rationale" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">Awaiting review</a></span></li><li class="">Review manager: TBD</li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol'" class=""><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5#introduction" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""></a>Introduction</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">This proposal introduces a new keyword that can be applied to enums which allows new cases to be introduced in extensions.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">Swift-evolution thread:&nbsp;<a href="https://lists.swift.org/pipermail/swift-evolution" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">[RFC] Extensible Enums</a></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol'" class=""><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5#motivation" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""></a>Motivation</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">Enums are a powerful feature which provides a lot of benefit if you have a limited number of behaviors. For example, associated values provide the ability to make every case essentially a separate type. However, due to the static nature of enums, they cannot be used in situations where they would otherwise be a perfect fit.&nbsp;</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">An example of this would be the use of an Error enum like so:</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class=""><pre style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal" class=""><span style="color:rgb(167,29,93)" class="">enum</span> FileError: ErrorProtocol {
    <span style="color:rgb(167,29,93)" class="">case</span> fileNotFound(path: <span style="color:rgb(0,134,179)" class="">String</span>)
    <span style="color:rgb(167,29,93)" class="">case</span> corruptedFile(bytes: [<span style="color:rgb(0,134,179)" class="">Int8</span>])
}
<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">readFile</span>() throws { <span style="color:rgb(167,29,93)" class="">...</span> }

<span style="color:rgb(150,152,150)" class="">// elsewhere in the codebase</span>
<span style="color:rgb(167,29,93)" class="">do</span> {
    <span style="color:rgb(167,29,93)" class="">try</span> readFile()
} <span style="color:rgb(167,29,93)" class="">catch</span> <span style="color:rgb(167,29,93)" class="">let</span> error <span style="color:rgb(167,29,93)" class="">as</span> FileError {
    <span style="color:rgb(167,29,93)" class="">switch</span> error {
        <span style="color:rgb(167,29,93)" class="">case</span> <span style="color:rgb(167,29,93)" class="">.</span>fileNotFound(<span style="color:rgb(167,29,93)" class="">let</span> path): <span style="color:rgb(150,152,150)" class="">// handle error</span>
        <span style="color:rgb(167,29,93)" class="">case</span> <span style="color:rgb(167,29,93)" class="">.</span>corruptedFile(<span style="color:rgb(167,29,93)" class="">let</span> bytes): <span style="color:rgb(150,152,150)" class="">// handle error</span>
    }
} <span style="color:rgb(167,29,93)" class="">catch</span> { <span style="color:rgb(167,29,93)" class="">...</span> }</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">While this is generally a good approach, it can be very dangerous for library consumers if the author exposes the error to the user. This is due to the fact that the&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">switch</code>&nbsp;statement has to be exhaustive and is only satisfied when all enum cases have been accounted for. What this means for library authors is that every time they add a new case to a public enum, they are breaking the exhaustivity of the&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">switch</code>&nbsp;and making their library backwards-incompatible.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">Currently, the best workaround is to use a&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">struct</code>&nbsp;with static instances and overloading the&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">~=</code>&nbsp;operator. This allows for similar&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">switch</code>&nbsp;behavior but overall is much less flexible, missing key features such as associated values.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">Another example is when the library is split into multiple modules, where the error is defined in the first module and the second module wants to add some error cases. An enum is very rarely used in this case because you cannot add cases in other modules. Instead, library authors either use an error protocol, and add more types that conform to it, or use the struct approach shown above. While this is not terrible, adding cases in extensions would better translate the intention of the author and adds more flexiblity.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol'" class=""><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5#proposed-solution" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""></a>Proposed solution</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">The solution proposed is quite simple: add an&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">extensible</code>&nbsp;keyword/modifier that can be applied to enums, which would require the&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">default</code>&nbsp;case when switched on and allow new cases to be added in extensions.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">Here is the translation of the very first example to the use an&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">extensible</code>&nbsp;enum instead, with a new case added:</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class=""><pre style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal" class="">extensible <span style="color:rgb(167,29,93)" class="">enum</span> ThingError: ErrorProtocol {
    <span style="color:rgb(167,29,93)" class="">case</span> fileNotFound(path: <span style="color:rgb(0,134,179)" class="">String</span>)
    <span style="color:rgb(167,29,93)" class="">case</span> corruptedFile(bytes: [<span style="color:rgb(0,134,179)" class="">Int8</span>])
    <span style="color:rgb(167,29,93)" class="">case</span> failedReadingFile
}
<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">readFile</span>() throws { <span style="color:rgb(167,29,93)" class="">...</span> }

<span style="color:rgb(150,152,150)" class="">// elsewhere in the codebase</span>
<span style="color:rgb(167,29,93)" class="">do</span> {
    <span style="color:rgb(167,29,93)" class="">try</span> readFile()
} <span style="color:rgb(167,29,93)" class="">catch</span> <span style="color:rgb(167,29,93)" class="">let</span> error <span style="color:rgb(167,29,93)" class="">as</span> ThingError {
    <span style="color:rgb(167,29,93)" class="">switch</span> error {
        <span style="color:rgb(167,29,93)" class="">case</span> <span style="color:rgb(167,29,93)" class="">.</span>fileNotFound(<span style="color:rgb(167,29,93)" class="">let</span> path): <span style="color:rgb(150,152,150)" class="">// handle error</span>
        <span style="color:rgb(167,29,93)" class="">case</span> <span style="color:rgb(167,29,93)" class="">.</span>corruptedFile(<span style="color:rgb(167,29,93)" class="">let</span> bytes): <span style="color:rgb(150,152,150)" class="">// handle error</span>
        <span style="color:rgb(167,29,93)" class="">default</span>: <span style="color:rgb(150,152,150)" class="">// handle future errors that don't exist yet</span>
    }
} <span style="color:rgb(167,29,93)" class="">catch</span> { <span style="color:rgb(167,29,93)" class="">...</span> }</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">For the second example, we can simply extend the enum in the higher-level module.</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class=""><pre style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal" class=""><span style="color:rgb(150,152,150)" class="">// Module FileProtocol</span>

extensible <span style="color:rgb(167,29,93)" class="">enum</span> FileError: ErrorProtocol {
    <span style="color:rgb(167,29,93)" class="">case</span> fileNotFound(path: <span style="color:rgb(0,134,179)" class="">String</span>)
}

<span style="color:rgb(167,29,93)" class="">protocol</span> FileProtocol {
    <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">read</span>() throws
}

<span style="color:rgb(150,152,150)" class="">// Module File</span>

<span style="color:rgb(167,29,93)" class="">extension</span> FileError {
    <span style="color:rgb(167,29,93)" class="">case</span> corruptedFile(bytes: [<span style="color:rgb(0,134,179)" class="">Int8</span>])
    <span style="color:rgb(167,29,93)" class="">case</span> failedReadingFile
}

<span style="color:rgb(167,29,93)" class="">struct</span> File: FileProtocol {
    <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">read</span>() throws { <span style="color:rgb(167,29,93)" class="">...</span> }
}</pre></div><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol'" class=""><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5#detailed-design" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""></a>Detailed design</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">A new keyword would be added to the language which is only allowed in front of the&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">enum</code>&nbsp;keyword. When an enum is marked&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">extensible</code>, new cases can be added in extensions and switches that are performed on it require a&nbsp;<code style="font-family:consolas,'liberation mono',menlo,courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">default</code>case.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol'" class=""><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5#impact-on-existing-code" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""></a>Impact on existing code</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">There is no impact on existing code since this is purely an additive feature.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol'" class=""><a href="https://gist.github.com/Danappelxx/41b7c2e86787f75698bd48135cc616f5#alternatives-considered" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""></a>Alternatives considered</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class="">No alternatives have been considered (yet).</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'helvetica neue',helvetica,'segoe ui',arial,freesans,sans-serif,'apple color emoji','segoe ui emoji','segoe ui symbol';font-size:16px" class=""><br class=""></p></div></div></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, Jun 30, 2016 at 1:04 PM David Sweeris via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">By itself, this would break switch statements, since they have to be exhaustive.<br class=""><br class="">If anyone has any ideas about how to fix that, I'm all ears.<br class=""><br class="">- Dave Sweeris<br class=""><br class="">&gt; On Jun 30, 2016, at 14:58, Edward Valentini via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">&gt;<br class="">&gt;<br class="">&gt; I am finding myself in a situation where the most elegant "swifty" solution would be to allow enum extensions to add to existing case options.&nbsp; For example lets say I'm using a library that has the following enum defined:<br class="">&gt;<br class="">&gt; enum MyDirection {<br class="">&gt;&nbsp; &nbsp;case east, west<br class="">&gt; }<br class="">&gt;<br class="">&gt; My app for example also makes use of north and south, so I would love to be able to write:<br class="">&gt;<br class="">&gt; extension MyDirection {<br class="">&gt;&nbsp; &nbsp;case north,south<br class="">&gt; }<br class="">&gt;<br class="">&gt; In objective c, one would probably have defined constants like MyDirectionEast etc...&nbsp; these would probably have been mapped to ints or strings so a consumer of this library could have easily extended this to add additional functionality, but using constants like that is not very "swifty"<br class="">&gt;<br class="">&gt; I'm curious what the swift community thinks.<br class="">&gt;<br class="">&gt; Thank you<br class="">&gt; _______________________________________________<br class="">&gt; swift-evolution mailing list<br class="">&gt;<span class="">&nbsp;</span><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">&gt;<span class="">&nbsp;</span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></blockquote></div><div dir="ltr" class="">--<span class="">&nbsp;</span><br class=""></div><div data-smartmail="gmail_signature" class=""><div dir="ltr" class=""><div class=""><div class="">Dan Appel<br class=""></div></div></div></div></div></blockquote></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></blockquote></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></blockquote></div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">--<span class="">&nbsp;</span><br class=""></div><div data-smartmail="gmail_signature" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div dir="ltr" class=""><div class=""><div class="">Dan Appel<br class=""></div></div></div></div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></blockquote></div><div dir="ltr" class="">-- <br class=""></div><div data-smartmail="gmail_signature" class=""><div dir="ltr" class=""><div class=""><div class="">Dan Appel<br class=""></div></div></div></div></blockquote></div></div><div dir="ltr" class="">-- <br class=""></div><div data-smartmail="gmail_signature" class=""><div dir="ltr" class=""><div class=""><div class="">Dan Appel<br class=""></div></div></div></div>
</div></blockquote></div></div></blockquote></div><div dir="ltr" class="">-- <br class=""></div><div data-smartmail="gmail_signature" class=""><div dir="ltr" class=""><div class=""><div class="">Dan Appel<br class=""></div></div></div></div>
</div></blockquote></div><br class=""></body></html>