<div dir="ltr">On Mon, Jul 18, 2016 at 7:07 AM, Károly Lőrentey <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 2016-07-18 09:17:43 +0000, David Hart via swift-evolution said:<br>
<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
On 18 Jul 2016, at 11:11, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
<br>
On Mon, Jul 18, 2016 at 3:27 AM, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt; On Jul 17, 2016, at 8:57 PM, L. Mihalkovic via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; On Jul 17, 2016, at 9:14 PM, Garth Snyder via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Is there a summary somewhere of the motivation for allowing methods to be declared non-overridable within open classes?<br></span>
[...]<span class=""><br>
Garth: I think it&#39;s implicit in the reasons to prevent subclassing. The mere fact that a class allows subclassing doesn&#39;t necessarily mean that every member in it is designed to be subclassed. Consider `UIViewController`: It&#39;s obviously designed to be subclassed, and some methods in it (such as `loadView`) are intended to be overridden, but others (such as `loadViewIfNeeded`) are *not* intended to be overridden.<br>
<br>
And [if UIViewController were to be written in Swift] there&#39;d be a good reason why `loadViewIfNeeded` and others of its ilk couldn&#39;t be final? <br>
<br>
I don&#39;t know UIKit internals, but I could imagine loadViewIfNeeded be overridden internally, if one knows the precise internal workings of UIViewController. That would require open, to allow overriding internally but not externally.<br>
</span></blockquote>
<br>
<br>
I thought about this aspect a little more. I think it&#39;s fair to say that we&#39;re breaking new ground for language design here. Classes limiting inheritance to a certain set of subclasses are nothing new (I&#39;ve written &amp; used classes doing this in C++, Java and C#), but no language that I know of allows limiting overrides of a specific public member in such a way. I think we need a convincing rationale for making this esoteric middle ground between final and open members the new default.<br>
<br>
The UIKit example above isn&#39;t convincing at all. It is already quite easy to allow package-internal subclasses to configure the behavior of loadViewIfNeeded without such a novel language feature. E.g., the UIKit team can simply make loadViewIfNeeded call into a non-final but internal method:<br>
<br>
public open class UIViewController {<br>
        private var _view: UIView? = nil<br>
<br>
        public final func loadViewIfNeeded() {<br>
                internalLoadViewIfNeeded()<br>
        }<br>
<br>
        internal func internalLoadViewIfNeeded() { // overridable internally<br>
                if let view = _view { return }<br>
                loadView()<br>
        }<br>
<br>
        public open func loadView() {<br>
                // Load it from a nib or whatevs<br>
        }<br>
}<br>
<br>
I see no drawback to this pattern; it is quite clear and simple. Therefore, in the interest of keeping the language free of needless complexity, I suggest we change the proposal to remove the implicit &quot;sealed&quot; level of public member overridability, and support only &quot;open&quot; or &quot;final&quot; class members.<br></blockquote><div><br></div><div>I&#39;m impressed by this analysis. You&#39;ve convinced me that the proposed default for public members is rather esoteric; given this very clean alternative way of achieving the same result, an esoteric default (though formally consistent with Swift conventions) seems unduly burdensome.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
For members, &quot;open&quot; should mean the opposite of &quot;final&quot;, with no levels in between. Member-level openness should be entirely independent of visibility; so it should be possible to say &quot;internal open&quot; to mean an internally overridable member that&#39;s not at all visible outside the module -- the same as today&#39;s default.<br>
<br>
(Note that (on platforms with an Objective-C runtime) &quot;dynamic&quot; provides a third level of flexibility for class members; I argue that it should imply &quot;open&quot;. So in order of increasing flexibility, we&#39;d have &quot;final&quot;, &quot;open&quot; and &quot;dynamic&quot; members. This seems easy enough to describe and understand.)<br>
<br>
I also suggest that for now, we should make neither &quot;final&quot; nor &quot;open&quot; nor &quot;dynamic&quot; the default for public members of open classes: we should rather require class authors to explicity add one of these qualifiers to all public member declarations. This way, we can defer the argument for choosing a default to a later (additive) proposal, once we have some experience with this setup. Non-public members can safely keep defaulting to &quot;internal open&quot;, like they do today.<span class="HOEnZb"><font color="#888888"><br>
<br>
-- <br>
Károly<br>
@lorentey</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div><br></div></div>