[swift-evolution] Proposal: Universal dynamic dispatch for method calls

Paul Cantrell cantrell at pobox.com
Mon Dec 7 21:45:54 CST 2015


>> Can you think of a situation where [static dispatch] is the desired semantics, as
>> opposed to either a desirable optimization or a confusing workaround for
>> the “monkey collision” problem? (I can’t see the use case, but I’m open
>> to hearing it!)
> 
> Yes. Any time you're replacing a global function with a protocol
> extension, to preserve the semantics [etc].


Indeed, I (mistakenly?) took this to be the original rationale. It seems to me that, this case would be better served by some mechanism that makes the non-override intent explicit at the point of declaration.

> I also disagree with the claim that the current rules are confusing.

In college, my brilliant mathematician friend Fazil divided all problems into two categories: “impossible” and “trivial.” The difference was whether Fazil knew the answer. Several times, I saw him tied in knots at the whiteboard, and then a problem’s status would suddenly flip in a single aha moment: “This is impossible. Impossib– Wait, no this is trivial!” [starts erasing everything]

Point is, everything seems obvious when it’s no longer confusing. I stand firm on my assertion that these rules are not obvious to those who haven’t already studied them carefully, and that a reshuffling that makes intent more explicit (and possibly allows dynamic dispatch in more circumstances) would prevent a lot of bugs out there in the wild.

If we must mix static and dynamic dispatch, I’d like to make sure every Swift programmer _chooses_ one instead of accidentally using it. I’m sure the language could do better on that front, given Joe’s comment about module-based scoping of names. I need to give this some more thought.

Cheers,

Paul

> On Dec 7, 2015, at 5:52 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
> 
> On Mon, Dec 7, 2015, at 02:51 PM, Paul Cantrell wrote:
>>> The ability to use static dispatch in most cases is one of the great features of Swift, and it's something that needs to be preserved, not relegated to being an optimization that can be done occasionally.
>> 
>> Can you think of a situation where that’s the desired semantics, as
>> opposed to either a desirable optimization or a confusing workaround for
>> the “monkey collision” problem? (I can’t see the use case, but I’m open
>> to hearing it!)
> 
> Yes. Any time you're replacing a global function with a protocol
> extension, to preserve the semantics the protocol extension's method
> implementation must be called every time the call is resolved via the
> protocol (e.g. with generics or protocol objects, as opposed to calling
> it on a concrete type that just happens to implement the protocol). If
> you want the method implementation to be overridden by the concrete
> implementing type, then the method should be declared in the protocol
> instead of just in a protocol extension. Whether or not you want these
> semantics is entirely up to you and your particular use-case.
> 
> I also disagree with the claim that the current rules are confusing. I
> think they're very straightforward. Whenever you call a method on a
> protocol value (either a generic type that's bound by the protocol, or a
> protocol object), the only question that matters for method resolution
> is "was this method declared in the protocol?". If it was declared in
> the protocol, then concrete implementations can override it. If it was
> not declared in the protocol, then concrete implementations cannot
> override it. And this is a good thing. If concrete implementations could
> override methods that were only provided through protocol extensions,
> then that's a great way to accidentally override methods without
> realizing it. Or more generally, if I declare an extension on some
> protocol with some method, subjecting that method to overriding would be
> a serious hazard, because there's no real way for me to know whether any
> implementing type ends up accidentally overriding the method (and if
> they did, they may not match the behavior expected from my method). The
> only sane behavior here is to not subject it to overriding by default.
> 
> Incidentally, I rather like ilya's suggestion of declaring another
> protocol with conditional conformance as the solution for declaring an
> overridable method in a protocol extension. That provides a good way of
> having this behavior without changing the semantics of protocols, and
> all it requires is to be able to combine `where` clauses with protocol
> conformance (which is something that's already known to be desired on
> types, e.g. so Optional can conform to Equatable when Wrapped:
> Equatable, so the only change here is extending that to protocols).
> 
> -Kevin Ballard
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list