[swift-evolution] Proposal: Universal dynamic dispatch for method calls
kevin at sb.org
Mon Dec 7 22:06:09 CST 2015
On Mon, Dec 7, 2015, at 07:45 PM, Paul Cantrell wrote:
> > 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.
There is already such a mechanism. It's the fact that the declaration
happens in an extension instead of in the original protocol.
> > 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.
I'm saying it's not confusing because there is an extremely simple rule
to determine whether method call through a protocol type allows
overriding (e.g. dynamic dispatch). And the rule is: Was the method
declared in the protocol? If it was, great! You get dynamic dispatch. If
it wasn't, there's no dynamic dispatch. The reason why this is confusing
to people is because nobody's clearly stating the rule.
I also disagree with the claim that changing this would prevent a lot of
bugs. I think it would introduce plenty of other bugs, because methods
in protocol extensions would start being unexpectedly overridden.
Dynamic dispatch in Swift is something that is opt-in, and it should
stay that way. The only implicit dynamic dispatch is methods/properties
on non-final classes can be overridden in subclasses, but that's an
explicit feature of classes (and still requires the `override` keyword
on the subclass method/property). Protocols of course have dynamic
dispatch, but only when used as protocol objects; it's still static
dispatch when used as generic type constraints (nitpick: the change
being discussed here also affects static method dispatch resolution in
specialization of generic functions, and lumping this under "dynamic
dispatch" is slightly misleading).
> 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.
The language already makes you choose it today. If this is unclear to
people, then we need to perhaps work on how protocols and protocol
extensions are explained instead of further muddying the waters by
making things dynamically-dispatched that really don't need to be.
More information about the swift-evolution