<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=""><br class=""></div><div class="">These arguments are definitely compelling. I would have to agree with this strongly. Very fair reasoning.</div><br class=""><div><blockquote type="cite" class=""><div class="">On 20 Dec 2015, at 2:21 PM, Jordan Rose via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="">On Dec 7, 2015, at 20:30 , John McCall via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div style="" class=""><span style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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="">Our current intent is that public subclassing and overriding will be locked down by default, but internal subclassing and overriding will not be. I believe that this strikes the right balance, and moreover that it is consistent with the general language approach to code evolution, which is to promote “consequence-free” rapid development by:</span><br style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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 style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""><span style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""> (1) avoiding artificial bookkeeping obstacles while you’re hacking up the initial implementation of a module, but</span><br style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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 style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""><span style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""> (2) not letting that initial implementation make implicit source and binary compatibility promises to code outside of the module and</span><br style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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 style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""><span style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""> (3) providing good language tools for incrementally building those initial prototype interfaces into stronger internal abstractions.</span><br style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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 style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""><span style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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="">All the hard limitations in the defaults are tied to the module boundary because we assume that it’s straightforward to fix any problems within the module if/when you decided you made a mistake earlier.</span><br style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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 style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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=""><span style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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="">So, okay, a class is subclassable by default, and it wasn’t really designed for that, and now there are subclasses in the module which are causing problems. As long as nobody's changed the default (which they could have done carelessly in either case, but are much less likely to do if it’s only necessary to make an external subclass), all of those subclasses will still be within the module, and you still have free rein to correct that initial design mistake.</span><br style="font-family: Monaco; font-size: 11px; font-style: normal; font-variant: 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></div></blockquote></div><br class=""><div class="">I think John summarized my position very well, so of course I'm going to come in here and add more stuff. :-)</div><div class=""><br class=""></div><div class="">In working on the design for library evolution support ("resilience"), we've come across a number of cases of "should a library author be able to change this when they release v2 of their library?" Many times, the answer is it's <i class="">possible</i> to do something in one direction, but not at all safe to go the other way. For example, you can always add public methods to a class, but you can't <i class="">remove</i> public methods because you don't know who's calling them. You can mark them deprecated, but that doesn't help with any client apps that have already been compiled and shipped.</div><div class=""><br class=""></div><div class="">One of the things that came up was "can you add 'final' to a class?" And of course you can't, because you don't know who may have already subclassed it. That's very unfortunate for a library author who simply forgot to add 'final' when they were first writing the class.</div><div class=""><br class=""></div><div class="">The interesting thing about this is that the "error of omission"—of failing to think about whether a class should be final—is worse than the alternative. Ignoring optimizations for a minute, a class that <i class="">starts out</i> 'final' can certainly become non-final later; it doesn't change how the class is currently used.* For a lot of library evolution questions, this is the preferred answer: <b class="">the default should be safe,</b> and the designer of the class can choose to be more aggressive later.</div><div class=""><br class=""></div><div class="">This is also the guiding principle behind the behavior of 'public'. A number of people have asked for members of a public struct to implicitly be made public. But here again the "error of omission" is problematic: a helper function you add for your own use may now be depended on by client apps far and wide, just because you forgot to customize the access control. So Swift says you should explicitly consider the public interface of every type.</div><div class=""><br class=""></div><div class="">Why 'sealed' instead of 'final' as the default? Because inheritance is useful, and within your <i class="">own</i> code having to opt into it starts to feel like unnecessary clutter. This is a trade-off, just like defaulting to 'internal' over 'private', but it's one that keeps life easy for a single developer with a single module: their app. (And the compiler can still do useful things with non-final classes if it can see the entire class hierarchy.) Additionally, limiting inheritance to the <i class="">current</i> file (a la 'private') is also potentially useful.</div><div class=""><br class=""></div><div class="">This direction separates "limiting inheritance/overrides" from "has no subclasses/overrides". The former is about defining the limits of your API; the latter is a promise that can be used for performance. I think that's a good thing.</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><div class="">* Even without optimizations a 'final' class cannot safely drop the 'final'. If a class is 'final', it may have additional 'required' initializers added in extensions.</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=a745LmqnDfg8U5xkzxO94fzXSZ0ZB2d7MXjmVBHs4IEUIpix19kXwnP1IsPkPEIoFdsvfKAa5Gs3slAmm5ca6-2BhJULaxhbW0eXwncPFoH7QLKN-2FUMXTRNWOlOCb7DF7yQ5xy5NZFXsZuBfO-2BnbOQkbPiOR8kC1cZ4OGFcTS3OmwBEzfYWQU0ToOqkE2C9DtcCYyOXHTb5Gn9N7fHy3blQwXcrkS-2FOt0ueLNYrt1B2X0-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>