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