dynamic classes and duck typing

Ary Borenszweig ary at esperanto.org.ar
Tue Dec 1 04:47:43 PST 2009


Denis Koroskin wrote:
> On Tue, 01 Dec 2009 15:05:16 +0300, Ary Borenszweig 
> <ary at esperanto.org.ar> wrote:
> 
>> Ary Borenszweig wrote:
>>> retard wrote:
>>>> Tue, 01 Dec 2009 03:16:47 -0800, Walter Bright wrote:
>>>>
>>>>> Ary Borenszweig wrote:
>>>>>> Can you show examples of points 2, 3 and 4?
>>>>> Have opDispatch look up the string in an associative array that 
>>>>> returns
>>>>> an associated delegate, then call the delegate.
>>>>>
>>>>> The dynamic part will be loading up the associative array at run time.
>>>>
>>>> This is not exactly what everyone of us expected. I'd like to have 
>>>> something like
>>>>
>>>> void foo(Object o) {
>>>>   o.duckMethod();
>>>> }
>>>>
>>>> foo(new Object() { void duckMethod() {} });
>>>>
>>>> The feature isn't very dynamic since the dispatch rules are defined 
>>>> statically. The only thing you can do is rewire the associative 
>>>> array when forwarding statically precalculated dispatching.
>>>  Exactly! That's the kind of example I was looking for, thanks.
>>
>> Actuall, just the first part of the example:
>>
>> void foo(Object o) {
>>     o.duckMethod();
>> }
>>
>> Can't do that because even if the real instance of Object has an 
>> opDispatch method, it'll give a compile-time error because Object does 
>> not defines duckMethod.
>>
>> That's why this is something useful in scripting languages (or ruby, 
>> python, etc.): if the method is not defined at runtime it's an error 
>> unless you define the magic function that catches all. Can't do that 
>> in D because the lookup is done at runtime.
>>
>> Basically:
>>
>> Dynanic d = ...;
>> d.something(1, 2, 3);
>>
>> is just a shortcut for doing
>>
>> d.opDispatch!("something")(1, 2, 3);
>>
>> (and it's actually what the compiler does) but it's a standarized way 
>> of doing that. What's the fun in that?
> 
> The fun is that you can call d.foo and d.bar() even though there is no 
> such method/property.
> 
> In ActionScript (and JavaScript, too, I assume), foo.bar is 
> auto-magically rewritten as foo["bar"]. What's fun in that?

The fun is that in Javascript I can do:

---
function yourMagicFunction(d) {
   d.foo();
}

var something = fromSomewhere();
yourMagicFunction(something);
---

and it'll work in Javascript because there's no type-checking at 
compile-time (well, because there's no compile-time :P)

Let's translate this to D:

---
void yourMagicFunction(WhatTypeToPutHere d) {
   d.foo();
}

auto something = fromSomewhere();
yourMagicFunction(something);
---

What type to put in "WhatTypeToPutHere"? If it's Object then it won't 
compile. If it's something that defines foo, ok. If it's something that 
defines opDispatch, then it's:

   d.opDispatch("foo")();

but you could have written it like that from the beginning.

So for now I see two uses for opDispatch:

1. To create a bunch of similar functions, like the swizzle one.
2. To be able to refactor a class by moving a method to opDispatch or 
viceversa:

class Something {
   void foo() { }
}

can be refactored to:

class Something {
   void opDispatch(string name) if (name == "foo") {}
}

without problems on the client side either way.

In brief, when you see:

var x = ...;
x.foo();

in Javascript, you have no idea where foo could be defined.

If you see the same code in D you know where to look for: the class 
itself, it's hierarchy, alias this, opDispatch. That's a *huge* difference.



More information about the Digitalmars-d mailing list