duck!

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Oct 17 09:56:23 PDT 2010


On 10/17/2010 05:15 AM, kenji hara wrote:
> 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
[snip]

> 2. Static object type&  structural signature
>      included in 5.
>
> 3. Static object type&  dynamic signature
>      included in 6.
>
> 4. Dynamic object type&  static signature
[snip]

> 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.

Yup. Nice.

>      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.

Correct. Could you please submit the appropriate bug report(s) so this 
is looked into?

Actually Variant can be made to support calls by using compile-time 
reflection, as long as the type during assignment is known. Consider:

Variant v;
v = new Human;

At assignment time, v knows the static type of Human and can store a map 
with "quack"'s signature. Later on, if you say v.quack(), the Variant 
will access the map and find the right method.

The scenario that needs runtime reflection is this:

Variant v;
v = cast(Object) new Human;

At this point all static information is lost at assignment time.

> '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.

I wouldn't want the creator of the facility himself to be unhappy about 
the name. Here's a thought - I suggest we call your function simply 
"adapt". Later on we might add an extra parameter to it that controls 
strictness. Works?


Andrei


More information about the Digitalmars-d mailing list