<div dir="ltr"><div class="gmail_extra">First off, I'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"><<a href="mailto:kevin@sb.org" target="_blank">kevin@sb.org</a>></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're subclassing some framework-provided class, like UIView or UIViewController. Just because I'm subclassing UIViewController doesn't mean I want my controller's API to be subject to Obj-C method dispatch unnecessarily.<br>
<br>
And even in the cases where I'm subclassing NSObject for Obj-C compatibility, that doesn'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'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's interesting, your library has very few non-final methods, because most of your classes are `final`. it'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'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>
> > Interaction with Obj-C runtime machinery stuff like KVO should be opt-in. In Obj-C it's ad-hoc, many classes support it for properties but many also don't, and very few properties have their KVO conformance documented. I don'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>
><br>
> This is an interesting point, and it would be an interesting semantic.<br>
> However in practice, the majority of NSObject code is imported from<br>
> obj-c, and it's generated interface does not follow this convention.<br>
<br>
</span>Just because framework classes don't follow this convention doesn't mean it's not a valuable convention to have in code written in Swift. There's a lot of things that Swift does better than Obj-C, and that you don't get when using an API imported from Obj-C, but that's not a reason to not do those things.<br>
<span class="gmail-"><br>
> Also, it's strange to conflate how something was dispatched and if it<br>
> supported KVO. I think property delegates will be the future here and<br>
> enable some exciting contracts if adopted.<br>
><br>
> Another approach is to just make it easier to opt into the full obj-c<br>
> machinery. The addition of a class or extension level `dynamic`<br>
> keyword would be great. If we could get buy in on this, then the<br>
> debate becomes if NSObject should default to `dynamic` or not.<br>
<br>
</span>I don'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'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>
> Brian<br>
><br>
> ><br>
> > -Kevin Ballard<br>
> ><br>
> > On Wed, Dec 14, 2016, at 03:15 PM, Brian King via swift-evolution wrote:<br>
> >> I wanted to follow up to a blog post I wrote about Message Dispatch in<br>
> >> 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>
> >> mentioned some changes to NSObject that didn’t result in any<br>
> >> objections, so I thought it was time to see what the SE mailing list<br>
> >> thought.<br>
> >><br>
> >> I’ve read a few conversations on SE mailing list that have morphed<br>
> >> into abstract conversations about dynamic vs static dispatch. I want<br>
> >> to focus specifically on how Swift NSObject subclasses behave.<br>
> >><br>
> >> I think that there are 2 changes that will result in fewer bugs and<br>
> >> will not have a substantial impact on performance:<br>
> >><br>
> >><br>
> >> ## Remove Table Dispatch from NSObject<br>
> >><br>
> >> NSObject subclasses use table dispatch for the initial class<br>
> >> declaration block. I think that using message dispatch for NSObject<br>
> >> subclasses everywhere will result in a much more consistent developer<br>
> >> experience.<br>
> >><br>
> >> ## Block NSObject Visibility Optimizations<br>
> >><br>
> >> Swift upgrades method dispatch to final when the compiler can prove<br>
> >> that the method is not subclassed. I would like to see Swift be more<br>
> >> careful about the impact of these optimizations on message dispatch,<br>
> >> and consider message dispatch non-upgradable.<br>
> >><br>
> >><br>
> >> I thought it would help to frame this choice as a trade-off between<br>
> >> Swift’s goals of safe, fast, and expressive.<br>
> >><br>
> >> ## Safe<br>
> >><br>
> >> Always using message dispatch for NSObject subclasses will fix a class<br>
> >> of runtime errors in framework features that are designed around<br>
> >> message passing (e.g. KVO). Arguments against using dynamic features<br>
> >> like this are valid, but Cocoa frameworks still use dynamic features<br>
> >> and the above behaviors result in actual bugs. As a bonus, this will<br>
> >> resolve SR-584, where a table-dispatched method that is overridden by<br>
> >> a message dispatch method doesn’t behave correctly.<br>
> >><br>
> >> ## Fast<br>
> >><br>
> >> The above changes will result in slower dispatch in NSObject<br>
> >> subclasses. However, I don't think that these dispatch changes<br>
> >> actually have a tangible impact on performance. Most NSObject<br>
> >> subclasses sit on top of a lot of `objc_msgSend`, and if there is a<br>
> >> specific hot spot, it would still be optimizable via the final<br>
> >> keyword.<br>
> >><br>
> >> ## Expressive<br>
> >><br>
> >> Using table dispatch for NSObject without any source indication or<br>
> >> library documentation is not very expressive. I think it’s important<br>
> >> to weigh table dispatch behavior against all of the framework<br>
> >> documentation and developer experience that assume message dispatch.<br>
> >> This will also eliminate the need for a lot of `@objc` and `dynamic`<br>
> >> annotations that are often inconsistently applied depending on if they<br>
> >> are needed in the scope they are defined in (e.g. class vs extension).<br>
> >><br>
> >><br>
> >> If this idea shows promise, I’d be glad to formalize a Swift Evolution<br>
> >> Proposal and explore syntactic details. I think being able to flag a<br>
> >> class with `dynamic` and applying this flag to `NSObject` may be the<br>
> >> only syntactic change needed. However, it would be good to debate the<br>
> >> merit of the behavior change before the syntax.<br>
> >><br>
> >><br>
> >> Thanks!<br>
> >><br>
> >><br>
> >> Brian King<br>
> >> ______________________________<wbr>_________________<br>
> >> swift-evolution mailing list<br>
> >> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
> >> <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>
> > ______________________________<wbr>_________________<br>
> > swift-evolution mailing list<br>
> > <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
> > <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>