<div dir="ltr"><div class="gmail_extra">First off, I&#39;m still learning out how to debate at this speed, sorry for the slow replies!</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 14, 2016 at 9:32 PM, Kevin Ballard <span dir="ltr">&lt;<a href="mailto:kevin@sb.org" target="_blank">kevin@sb.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">On Wed, Dec 14, 2016, at 05:54 PM, Brian King wrote:<br><br>
</span>Obj-C compatibility certainly is one reason to use NSObject, but perhaps a bigger reason is because you&#39;re subclassing some framework-provided class, like UIView or UIViewController. Just because I&#39;m subclassing UIViewController doesn&#39;t mean I want my controller&#39;s API to be subject to Obj-C method dispatch unnecessarily.<br>
<br>
And even in the cases where I&#39;m subclassing NSObject for Obj-C compatibility, that doesn&#39;t mean that most of the calls to my object are coming from Obj-C. All that means is that at least one place my object is used is Obj-C, and 99% of the uses might be Swift. Or if I&#39;m writing a library, it might mean that I simply want to preserve Obj-C compatibility in case a client wants it, even though I expect my clients to be primarily Swift (For example, this is how postmates/PMHTTP is written; Obj-C–compatible, but the expectation is most clients will probably be Swift).<br></blockquote><div><br></div><div>It&#39;s interesting, your library has very few non-final methods, because most of your classes are `final`. it&#39;s great to have this option, and as a result, it is very easy to write performant code. It is very wordy to write runtime friendly code. I think I value these optimizations less than you, to me it feels like it&#39;s pre-mature optimization, especially given how easy it is to opt into Static dispatch.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class="gmail-"><br>
&gt; &gt; Interaction with Obj-C runtime machinery stuff like KVO should be opt-in. In Obj-C it&#39;s ad-hoc, many classes support it for properties but many also don&#39;t, and very few properties have their KVO conformance documented. I don&#39;t view having to mark my properties as `dynamic` to participate in KVO to be a problem with Swift but rather a feature. It tells the reader that this property supports KVO.<br>
&gt;<br>
&gt; This is an interesting point, and it would be an interesting semantic.<br>
&gt; However in practice, the majority of NSObject code is imported from<br>
&gt; obj-c, and it&#39;s generated interface does not follow this convention.<br>
<br>
</span>Just because framework classes don&#39;t follow this convention doesn&#39;t mean it&#39;s not a valuable convention to have in code written in Swift. There&#39;s a lot of things that Swift does better than Obj-C, and that you don&#39;t get when using an API imported from Obj-C, but that&#39;s not a reason to not do those things.<br>
<span class="gmail-"><br>
&gt; Also, it&#39;s strange to conflate how something was dispatched and if it<br>
&gt; supported KVO. I think property delegates will be the future here and<br>
&gt; enable some exciting contracts if adopted.<br>
&gt;<br>
&gt; Another approach is to just make it easier to opt into the full obj-c<br>
&gt; machinery. The addition of a class or extension level `dynamic`<br>
&gt; keyword would be great. If we could get buy in on this, then the<br>
&gt; debate becomes if NSObject should default to `dynamic` or not.<br>
<br>
</span>I don&#39;t think we should ever make it possible to mark an entire class as `dynamic`. This just reintroduces the Obj-C problem, where many properties support KVO, but not all, and there&#39;s no indication on the property itself as to whether it supports it.<br></blockquote><div><br></div><div>This would just be short hand for adding the `dynamic` keyword in front of every variable and method, so shy of the already existing computed property getter case, all of the properties should just work.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-HOEnZb"><font color="#888888"><br>
-Kevin Ballard<br>
</font></span><div class="gmail-HOEnZb"><div class="gmail-h5"><br>
&gt; Brian<br>
&gt;<br>
&gt; &gt;<br>
&gt; &gt; -Kevin Ballard<br>
&gt; &gt;<br>
&gt; &gt; On Wed, Dec 14, 2016, at 03:15 PM, Brian King via swift-evolution wrote:<br>
&gt; &gt;&gt; I wanted to follow up to a blog post I wrote about Message Dispatch in<br>
&gt; &gt;&gt; Swift — <a href="https://www.raizlabs.com/dev/2016/12/swift-method-dispatch" rel="noreferrer" target="_blank">https://www.raizlabs.com/dev/<wbr>2016/12/swift-method-dispatch</a>. I<br>
&gt; &gt;&gt; mentioned some changes to NSObject that didn’t result in any<br>
&gt; &gt;&gt; objections, so I thought it was time to see what the SE mailing list<br>
&gt; &gt;&gt; thought.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I’ve read a few conversations on SE mailing list that have morphed<br>
&gt; &gt;&gt; into abstract conversations about dynamic vs static dispatch. I want<br>
&gt; &gt;&gt; to focus specifically on how Swift NSObject subclasses behave.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I think that there are 2 changes that will result in fewer bugs and<br>
&gt; &gt;&gt; will not have a substantial impact on performance:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ## Remove Table Dispatch from NSObject<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; NSObject subclasses use table dispatch for the initial class<br>
&gt; &gt;&gt; declaration block. I think that using message dispatch for NSObject<br>
&gt; &gt;&gt; subclasses everywhere will result in a much more consistent developer<br>
&gt; &gt;&gt; experience.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ## Block NSObject Visibility Optimizations<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Swift upgrades method dispatch to final when the compiler can prove<br>
&gt; &gt;&gt; that the method is not subclassed. I would like to see Swift be more<br>
&gt; &gt;&gt; careful about the impact of these optimizations on message dispatch,<br>
&gt; &gt;&gt; and consider message dispatch non-upgradable.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I thought it would help to frame this choice as a trade-off between<br>
&gt; &gt;&gt; Swift’s goals of safe, fast, and expressive.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ## Safe<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Always using message dispatch for NSObject subclasses will fix a class<br>
&gt; &gt;&gt; of runtime errors in framework features that are designed around<br>
&gt; &gt;&gt; message passing (e.g. KVO). Arguments against using dynamic features<br>
&gt; &gt;&gt; like this are valid, but Cocoa frameworks still use dynamic features<br>
&gt; &gt;&gt; and the above behaviors result in actual bugs. As a bonus, this will<br>
&gt; &gt;&gt; resolve SR-584, where a table-dispatched method that is overridden by<br>
&gt; &gt;&gt; a message dispatch method doesn’t behave correctly.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ## Fast<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; The above changes will result in slower dispatch in NSObject<br>
&gt; &gt;&gt; subclasses. However, I don&#39;t think that these dispatch changes<br>
&gt; &gt;&gt; actually have a tangible impact on performance. Most NSObject<br>
&gt; &gt;&gt; subclasses sit on top of a lot of `objc_msgSend`, and if there is a<br>
&gt; &gt;&gt; specific hot spot, it would still be optimizable via the final<br>
&gt; &gt;&gt; keyword.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ## Expressive<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Using table dispatch for NSObject without any source indication or<br>
&gt; &gt;&gt; library documentation is not very expressive. I think it’s important<br>
&gt; &gt;&gt; to weigh table dispatch behavior against all of the framework<br>
&gt; &gt;&gt; documentation and developer experience that assume message dispatch.<br>
&gt; &gt;&gt; This will also eliminate the need for a lot of `@objc` and `dynamic`<br>
&gt; &gt;&gt; annotations that are often inconsistently applied depending on if they<br>
&gt; &gt;&gt; are needed in the scope they are defined in (e.g. class vs extension).<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; If this idea shows promise, I’d be glad to formalize a Swift Evolution<br>
&gt; &gt;&gt; Proposal and explore syntactic details. I think being able to flag a<br>
&gt; &gt;&gt; class with `dynamic` and applying this flag to `NSObject` may be the<br>
&gt; &gt;&gt; only syntactic change needed. However, it would be good to debate the<br>
&gt; &gt;&gt; merit of the behavior change before the syntax.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Thanks!<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Brian King<br>
&gt; &gt;&gt; ______________________________<wbr>_________________<br>
&gt; &gt;&gt; swift-evolution mailing list<br>
&gt; &gt;&gt; <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
&gt; &gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
&gt; &gt; ______________________________<wbr>_________________<br>
&gt; &gt; swift-evolution mailing list<br>
&gt; &gt; <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
&gt; &gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div></div></blockquote></div><br></div></div>