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

ilya ilya.nikokoshev at gmail.com
Mon Dec 7 14:52:35 CST 2015


Could you provide an example? I tried playing with protocol extensions,
modelling this situation:

> If an extension method collision occurs when a type implements multiple
protocols,

but so far all examples I found where one would see a collision are
disallowed by compiler, e.g.


protocol P1 {
    func something() -> Int
}

protocol P2 {
    func something() -> Int
    func another() -> Int
}

extension P1 {

    func something() -> Int {
        return 1
    }

    func another() -> Int {
        return 1
    }
}

extension P2 {

    func something() -> Int {
        return 2
    }

    func another() -> Int {
        return 2
    }
}

class C1: P1 { // <- P1, P2 here doesn't compile

    func something() -> Int {
        return 0
    }

}

class C2: P2 {

}

class C3: P1, P2 {

    func something() -> Int {
        return 0
    }

    func another() -> Int {
        return 0
    }

}

On Mon, Dec 7, 2015 at 7:17 AM, Paul Cantrell via swift-evolution <
swift-evolution at swift.org> wrote:

> One of the few things in Swift 2 that feels to me like a design flaw is
> the way Swift mixes static and dynamic method dispatch.
>
> Alexandros Salazar gives an excellent explanation of this problem — and I
> agree wholeheartedly with his title for the article:
>
>     http://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future
>
> The upshot is that when we see this:
>
>     foo.bar()
>
> …it’s very hard to know how the compiler will determine which
> implementation of bar() to use. It might use static dispatch; it might use
> dynamic dispatch.
>
> The rules that govern this are arcane, and hard to remember. They have the
> feeling of being a “gotcha” question for job interviews — always a red flag
> for language features.
>
> Even if you remember the rules, the information needed to determine
> whether dispatch is static or dynamic is hard to track down. It depends on
> whether bar()’s implementation comes from an extension, whether the
> extension method appeared on the extended protocol, and whether the
> inferred type of foo is the protocol itself or an implementing type.
>
> A crucial part of the meaning of “foo.bar()” is implicit, and hard to
> determine. This runs contrary to Swift’s stated goal of prioritizing
> clarity at the point of API use, and its general pattern of making intent
> explicit. And it feels dangerous — a wellspring of insidious bugs.
>
> Thus:
>
>
> PROPOSAL
>
> Make the syntax “foo.bar()” always use dynamic dispatch, i.e. always use
> _only_ the runtime type of foo to determine which implementation of bar()
> to use. If an extension method collision occurs when a type implements
> multiple protocols, require the type to explicitly specify which one to use
> (as Swift already requires the caller to do at the point of invocation).
>
>
> I mean this proposal somewhat as a strawman. It’s such an obvious choice,
> I’m sure there were good reasons not to do it. But I’d like to propose the
> obvious solution in order to understand what’s wrong with it. I realize
> static dispatch precludes some optimizations, but I doubt that this alone
> drove the design choice. I see no safety or expressiveness upside to the
> way it works now.
>
> Cheers,
>
> Paul
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151207/c38f1b91/attachment.html>


More information about the swift-evolution mailing list