<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="">Am 25.05.2016 um 19:38 schrieb Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt;:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><br class="">Sent from my iPad</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="">On May 25, 2016, at 12:04 PM, Leonardo Pessoa via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><div class=""><div style="font-family: Calibri, sans-serif; font-size: 11pt;" class="">I like the idea of sealed types but I think much better is Ceylon's concept of previously declaring the many subclasses that are going to exist both because I can have a bunch of public classes in a framework and restrict their subclasses and because there are threads in this group discussing the idea of a union type (perhaps both ideas could benefit from one another).<br class=""></div></div></div></blockquote><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">I forgot to mention this in my last reply. &nbsp;What I am proposing allows sealed classes to be viewed as similar to nominal sum types. &nbsp;This is like Scala's case classes. &nbsp;</span><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Ceylon's unions are structural sum types (the sum type analogue of a Tuple, which is a structural product type). &nbsp;I really want to see these as well (I recently ran into a use case where they are far superior to what we can do today). &nbsp;But they are not the same as sealed classes and protocols.</div></div></blockquote><div><br class=""></div>That’s true and readily demonstrated by Ceylon which has both :-)</div><div><br class=""></div><div>-Thorsten</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class=""><div style="font-family: Calibri, sans-serif; font-size: 11pt;" class=""><br class="">Another idea could be to add a single simple keyword to the root class (could even be sealed but I don't think it grabs this concept) to declare all its subclasses must exist within the same module. That would restrict the number of subclasses to the compiler without requiring us to revisit the root class each time we need to create a subclass and would still allow for every subclass to be public.<br class=""><br class="">Sealed wouldn't be a good idea because the root class would still enable subclassing and it would be ideal that the switch could only work with these "sealed" types.<br class=""><br class="">+1 for enabling this for protocols too.<br class=""><br class="">Just a few issues:<span class="Apple-converted-space">&nbsp;</span><br class="">- here we're considering having subclasses of subclasses, or not?<span class="Apple-converted-space">&nbsp;</span><br class="">-what about public protocols being adopted outside the module, should we just ignore them or completely forbid the adoption?<br class=""><br class=""></div></div><div dir="ltr" class=""><hr class=""><span style="font-family: Calibri, sans-serif; font-size: 11pt; font-weight: bold;" class="">From:<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: Calibri, sans-serif; font-size: 11pt;" class=""><a href="mailto:swift-evolution@swift.org" class="">Thorsten Seitz via swift-evolution</a></span><br class=""><span style="font-family: Calibri, sans-serif; font-size: 11pt; font-weight: bold;" class="">Sent:<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: Calibri, sans-serif; font-size: 11pt;" class="">‎25/‎05/‎2016 01:18 PM</span><br class=""><span style="font-family: Calibri, sans-serif; font-size: 11pt; font-weight: bold;" class="">To:<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: Calibri, sans-serif; font-size: 11pt;" class=""><a href="mailto:tseitz42@icloud.com" class="">Thorsten Seitz</a></span><br class=""><span style="font-family: Calibri, sans-serif; font-size: 11pt; font-weight: bold;" class="">Cc:<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: Calibri, sans-serif; font-size: 11pt;" class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution</a></span><br class=""><span style="font-family: Calibri, sans-serif; font-size: 11pt; font-weight: bold;" class="">Subject:<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: Calibri, sans-serif; font-size: 11pt;" class="">Re: [swift-evolution] [Pitch] Exhaustive pattern matching forprotocols and classes</span><br class=""><br class=""></div><div class=""></div><div class="">Just realized that Matthew did introduce `sealed` exactly to enable this for public types. That's fine with me!</div><div class=""><br class=""></div><div class="">-Thorsten&nbsp;</div><div class=""><br class="">Am 25.05.2016 um 18:11 schrieb Thorsten Seitz via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt;:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div class=""></div><div class="">Ceylon uses the following syntax for stating that a class has a finite set of subclasses:</div><div class=""><br class=""></div><div class="">class C of C1 | C2 {...}</div><div class=""><br class=""></div><div class="">where `|` is the type union operator. Swift could use a simple comma separated list instead after the `or`. The advantage over sealed+private/internal would be thatnthe class or protocol could be public as well.</div><div class=""><br class=""></div><div class="">-Thorsten&nbsp;</div><div class=""><br class="">Am 25.05.2016 um 04:01 schrieb David Sweeris via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt;:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div class="">Or if there was a way to declare that a class/protocol can only have a defined set of subclasses/conforming types.<br class=""><br class="">Sent from my iPhone</div><div class=""><br class="">On May 24, 2016, at 15:35, Austin Zheng via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">If you pattern match on a type that is declared internal or private, it is impossible for the compiler to not have an exhaustive list of subclasses that it can check against.<div class=""><br class=""></div><div class="">Austin</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, May 24, 2016 at 1:29 PM, Leonardo Pessoa<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:me@lmpessoa.com" target="_blank" class="">me@lmpessoa.com</a>&gt;</span><span class="Apple-converted-space">&nbsp;</span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">I like this but I think it would be a lot hard to ensure you have all<br class="">subclasses covered. Think of frameworks that could provide many<br class="">unsealed classes. You could also have an object that would have to<br class="">handle a large subtree (NSObject?) and the order in which the cases<br class="">are evaluated would matter just as in exception handling in languages<br class="">such as Java (or require some evaluation from the compiler to raise<br class="">warnings). I'm +1 for this but these should be open-ended like strings<br class="">and require the default case.<br class=""><br class="">On 24 May 2016 at 17:08, Austin Zheng via swift-evolution<br class=""><div class="HOEnZb"><div class="h5">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">&gt; I have been hoping for the exhaustive pattern matching feature for a while<br class="">&gt; now, and would love to see a proposal.<br class="">&gt;<br class="">&gt; Austin<br class="">&gt;<br class="">&gt; On Tue, May 24, 2016 at 1:01 PM, Matthew Johnson via swift-evolution<br class="">&gt; &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">&gt;&gt;<br class="">&gt;&gt; Swift currently requires a default pattern matching clause when you switch<br class="">&gt;&gt; on an existential or a non-final class even if the protocol or class is<br class="">&gt;&gt; non-public and all cases are covered.&nbsp; It would be really nice if the<br class="">&gt;&gt; default clause were not necessary in this case.&nbsp; The compiler has the<br class="">&gt;&gt; necessary information to prove exhaustiveness.<br class="">&gt;&gt;<br class="">&gt;&gt; Related to this is the idea of introducing something like a `sealed`<br class="">&gt;&gt; modifier that could be applied to public protocols and classes.&nbsp; The<br class="">&gt;&gt; protocol or class would be visible when the module is imported, but<br class="">&gt;&gt; conformances or subclasses outside the declaring module would be prohibited.<br class="">&gt;&gt; Internal and private protocols and classes would implicitly be sealed since<br class="">&gt;&gt; they are not visible outside the module.&nbsp; Any protocols that inherit from a<br class="">&gt;&gt; sealed protocol or classes that inherit from a sealed class would also be<br class="">&gt;&gt; implicitly sealed (if we didn’t do this the sealing of the superprotocol /<br class="">&gt;&gt; superclass could be violated by conforming to or inheriting from a<br class="">&gt;&gt; subprotocol / subclass).<br class="">&gt;&gt;<br class="">&gt;&gt; Here are examples that I would like to see be valid:<br class="">&gt;&gt;<br class="">&gt;&gt; protocol P {}<br class="">&gt;&gt; // alternatively public sealed protocol P {}<br class="">&gt;&gt; struct P1: P {}<br class="">&gt;&gt; struct P2: P {}<br class="">&gt;&gt;<br class="">&gt;&gt; func p(p: P) -&gt; Int {<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;switch p {<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;case is P1: return 1 // alternatively an `as` cast<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;case is P2: return 2 // alternatively an `as` cast<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;}<br class="">&gt;&gt; }<br class="">&gt;&gt;<br class="">&gt;&gt; class C {}<br class="">&gt;&gt; // alternatively public sealed class C {}<br class="">&gt;&gt; class C1: C {}<br class="">&gt;&gt; class C2: C {}<br class="">&gt;&gt;<br class="">&gt;&gt; func c(c: C) -&gt; Int {<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;switch c {<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;case is C1: return 1 // alternatively an `as` cast<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;case is C2: return 2 // alternatively an `as` cast<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;case is C: return 0&nbsp; &nbsp;// alternatively an `as` cast<br class="">&gt;&gt;&nbsp; &nbsp; &nbsp;}<br class="">&gt;&gt; }<br class="">&gt;&gt;<br class="">&gt;&gt; I am wondering if this is something the community is interested in.&nbsp; If<br class="">&gt;&gt; so, I am wondering if this is something that might be possible in the Swift<br class="">&gt;&gt; 3 timeframe (maybe just for private and internal protocols and classes) or<br class="">&gt;&gt; if it should wait for Swift 4 (this is likely the case).<br class="">&gt;&gt;<br class="">&gt;&gt; -Matthew<br class="">&gt;&gt; _______________________________________________<br class="">&gt;&gt; swift-evolution mailing list<br class="">&gt;&gt;<span class="Apple-converted-space">&nbsp;</span><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">&gt;&gt;<span class="Apple-converted-space">&nbsp;</span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" rel="noreferrer" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">&gt;<br class="">&gt;<br class="">&gt;<br class="">&gt; _______________________________________________<br class="">&gt; swift-evolution mailing list<br class="">&gt;<span class="Apple-converted-space">&nbsp;</span><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">&gt;<span class="Apple-converted-space">&nbsp;</span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" rel="noreferrer" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">&gt;<br class=""></div></div></blockquote></div><br class=""></div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span></div></blockquote></div></div></div></blockquote></div><br class=""></body></html>