duck!

kenji hara k.hara.pg at gmail.com
Sun Oct 17 03:15:05 PDT 2010


I tried to arrange Duck-typing Patterns in D .

interface Quack
{
    void quack();
}
class Duck : Quack
{
    void quack(){...}
}
class Human
{
    void quack(){...}
}

1. Static object type & static signature
    ----
    Duck d = new Duck;
    d.quack();
        // The type of object referenced by d is statically chosen.
        // --> Duck,
        // The type of variable d is statically chosen.
        // --> Duck.
        // Signature 'quack' statically chosen.
    ----
    This is built-in-supported in D.

    Using template like this is included in this pattern:
    void f(T)(T t)
    {
        T.quack();
    }
    T and quack are bound statically.

2. Static object type & structural signature
    included in 5.

3. Static object type & dynamic signature
    included in 6.

4. Dynamic object type & static signature
    ----
    Quack q = new Duck;
    q.quack();
        // The type of object referenced by q is dynamically chosen.
        // --> extends Quack, like Duck,
        // The type of variable q is statically chosen.
        // --> Quack.
        // Signature 'quack' statically chosen.
    ----
    This is built-in-supported in D.

5. Dynamic object type & static/structural signature
    ----
    Quack q = adaptTo!Quack(new Duck());
    q.quack();
    q = adaptTo!Quack(new Human());
    q.quack();
        // The type of object referenced by q is dynamically chosen.
        // --> Structural conformance with Quack, like Duck, Human.
        // The type of variable q is statically chosen.
        // --> Quack.
        // Signature 'quack' statically chosen.
    ----
    Currently, adaptTo supports this pattern.

    adaptTo realizes structural conformance through using static
conformance of interface.
    It is belong to implementation decision.

6. Dynamic object type & dynamic signature
    ----
    X x;
        // x does not assume any signatures.
    x = new Duck();
    invoke(x, "quack"); // calls Duck.quack()
    invoke(x, "undef"); // throws runtime-exception

        // x can have like following templates:
        //  void opDispatch(string s)(){
        //      invoke(this, s);
        //  }
        // By using this, X can convert static/structural signature to
dynamic one.
    x.quack();          // calls Duck.quack()
    x.udnef();          // throws runtime-exception

    x = new Human();
    x.quack();          // calls Human.quack()
    invoke(x, "quack"); // calls Human.quack()
    ----

    std.variant only supports part of this pattern, it is limited
operator overloading.
    Implementing this needs runtime-reflection, so we can't support
    this pattern perfectly in current D, since my sample code does not work.

'duck' may be funny, but not accurate.

P.S.
I researched interface in Go language.
(via http://golang.org/doc/go_for_cpp_programmers.html#Interfaces),
I think it is closest to 5 than others.
But it does not called 'Duck-Typing' or 'duck'.

http://www.google.com/search?as_q=duck+typing&hl=en&as_sitesearch=golang.org%2Fdoc%2F
Searching result in go-lang doc matches none.

Kenji Hara


More information about the Digitalmars-d mailing list