<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><blockquote type="cite" class=""><div class="">On Jul 21, 2016, at 3:05 PM, Nevin Brackett-Rozinsky <<a href="mailto:nevin.brackettrozinsky@gmail.com" class="">nevin.brackettrozinsky@gmail.com</a>> wrote:</div><div class=""><div dir="ltr" class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">I agree that it would make sense to be able to say "I allow subclasses, but they<br class="">don't get to override any of my methods unless I say so, even things I inherit".<br class="">But that feels like a refinement.</blockquote><div class=""><br class=""></div><div class="">Well, we can already achieve that by writing,</div><div class=""><br class=""></div><div class=""> public final func f() -> Int { return _f() }</div><div class=""> internal func _f() -> Int { return 42 }</div><div class=""><br class=""></div><div class="">That way subclasses in the module can override _f to change the behavior of f, while outside they cannot. So we can already accomplish “an open member of a base class is sealed by a subclass”.</div></div></div></blockquote><div><br class=""></div>Well. While that is, yes, technically possible to do to the entire open API of the superclass, it's so much boilerplate for most situations that it might as well not exist. And that's ignoring the fact that the superclass can always add more open API. I wouldn't want to dismiss the feature request this way, because it's clearly not an acceptable solution.</div><div><br class=""></div><div>John.</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">What we *can’t* do, either now or with the proposal, is have a sub-subclass *re-open* that member:</div><div class=""><br class=""></div><div class="">open class A { open var x: Int //... }</div><div class="">open class B: A { override final var x: Int { return _x } }<br class=""></div><div class="">open class C: B { override open var x: Int { return 16 } } // error: cannot override `final` member</div><div class=""><br class=""></div><div class="">For that we would need either an explicit `sealed` keyword, or the ability to override an `open` member as `public` (non-open), which class B could use here.</div><div class=""><br class=""></div><div class="">Nevin</div><div class=""><br class=""></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, Jul 21, 2016 at 4:22 PM, John McCall via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class="gmail-h5"><blockquote type="cite" class=""><div class="">On Jul 21, 2016, at 1:04 PM, Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><div 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" class="">on Thu Jul 21 2016, John McCall <</span><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><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" class="">> wrote:</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=""><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=""><blockquote type="cite" 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=""><blockquote type="cite" class="">On Jul 21, 2016, at 10:47 AM, Dave Abrahams via swift-evolution<br class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:<br class="">on Thu Jul 21 2016, Matthew Johnson<br class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">mailto:swift-evolution@swift.org</a>>><br class=""></blockquote><br class=""><blockquote type="cite" class="">wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><span style="white-space:pre-wrap" class="">        </span>* What is your evaluation of the proposal?<br class=""></blockquote><br class="">+1 to the first design. I think this is a great solution that<br class="">balances the many considerations that have been raised on all sides of<br class="">this issue. `open` is 2 characters shorter than `public` so<br class="">complaints about boilerplate are no longer valid. `internal` is the<br class="">“default” - neither `public` nor `open` are privileged as a “default”<br class="">for publishing API outside of a module.<br class=""><br class="">I am interested in language enhancements such as exhaustive pattern<br class="">matching on classes and protocols which rely on knowledge of the full<br class="">class hierarchy. Such enhancements will be far more useful if the<br class="">language supports non-open, non-final classes.<br class=""><br class="">There are design techniques that would require additional boilerplate<br class="">if we cannot have non-open, non-final classes.<br class=""><br class="">Most importantly, requiring library authors to choose `public` or<br class="">`open` provides important documentation value. Users of the library<br class="">will know whether the author intends to support subclasses or not.<br class=""></blockquote><br class="">I think this reasoning is flawed.<br class=""><br class="">If you make any methods overridable outside your module (“open”),<br class="">obviously you mean to allow subclassing outside the module. If you have<br class="">no open methods, there's absolutely nothing you need to do to “support<br class="">subclasses,” and from a design point-of-view, there's no reason to<br class="">restrict people from subclassing.<br class=""></blockquote><br class="">Superclasses can have superclasses, which can themselves have open methods.<br class="">This is, in fact, quite common for Cocoa programmers.<br class=""></blockquote><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" class="">Okay, good point.</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=""><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" class="">Making a class non-subclassable seems like a pretty indirect way to say</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" class="">“not even inherited methods should be overridden outside the defining</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" class="">module,” though.</span></div></blockquote><blockquote type="cite" class=""><div class=""><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" class="">Wouldn't we prefer to have a way to hide the inheritance relationship</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" class="">(and thus prevent overriding of inherited methods) outside the module?</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" class="">Or are these independently useful axes?</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=""></div></blockquote><div class=""><br class=""></div></div></div>I agree that it would make sense to be able to say "I allow subclasses, but they</div><div class="">don't get to override any of my methods unless I say so, even things I inherit".</div><div class="">But that feels like a refinement.</div><div class=""><br class=""></div><div class="">John.</div><div class=""><div class="gmail-h5"><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class=""><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=""><blockquote type="cite" 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=""><br class=""><br class="">John.<br class=""><br class=""><blockquote type="cite" class=""><br class="">The only reasons I can see for allowing people to prevent non-final<br class="">classes from being subclassed outside the module in which they are<br class="">defined are:<br class=""><br class="">1. It feels like a nice point of control to have.<br class=""><br class="">2. Marginal performance gains as noted in the proposal<br class=""><br class="">I personally don't find these to be convincing. #1 in particular seems<br class="">like a poor way to make language design decisions. If we decide to add<br class="">this point of control, I'll justify it to myself in terms of #2.<br class=""><br class="">P.S., I can live with either alternative; it's just important to me that<br class="">we understand the situation clearly when evaluating them.<br class=""><br class="">HTH,<br class=""><br class="">--<span class=""> </span><br class="">Dave<br class=""><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="mailto:swift-evolution@swift.org" target="_blank" class="">mailto: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=""><<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a>><br class=""></blockquote>_______________________________________________<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=""><br class=""></blockquote><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" class="">--<span class=""> </span></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" class="">Dave</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=""><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" 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" 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><br class=""></div></div></div><br class="">_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" 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="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>