dynamic classes and duck typing

Denis Koroskin 2korden at gmail.com
Tue Dec 1 05:19:58 PST 2009


On Tue, 01 Dec 2009 16:08:18 +0300, Ary Borenszweig <ary at esperanto.org.ar>  
wrote:

> Denis Koroskin wrote:
>> On Tue, 01 Dec 2009 15:47:43 +0300, Ary Borenszweig  
>> <ary at esperanto.org.ar> wrote:
>>
>>> 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);
>>> ---
>>>
>>  I believe there will soon be a library type that would allow that.
>
> It's called a template:
>
> void yourMagicFunction(T)(T d) {
>    d.foo();
> }
>
> I can write that and I can always compile my code. I can use that  
> function with any kind of symbol as long as it defines foo, whether it's  
> by definining it explicitly, in it's hierarchy, in an aliased this  
> symbol or in an opDispatch. That's the same concept as any function in  
> Javascript (except that in Javascript if the argument doesn't define foo  
> it's a runtime error and in D it'll be a compile-time error).

No, I was thinking about a Dynamic class:

class Foo {
     void foo() { ... }
}

void yourMagicFunction(Dynamic d) {
     d.foo(); // might throw if there is no such method in an underlying  
class
}

yourMagicFunction(new Dynamic(new Foo()));

There are a few open issues, though: lack or true reflection and lack of  
overload by return type.

For example, I'd like to do the following:

Dynamic d = ...;
d.foo = 42.0;
int i = d.foo; // returns 42
float f = d.foo; // return 42.f

Overload by return type would allow that:

RetType opDispatch(RetType, string method, Args...)(Args args)
{
     // ...
}

But relection is still needed to find out what methods a given object has:

class Foo { void foo(float f) { ... } }
Object o = new Foo();

Dynamic d = new Dynamic(o);
d.foo(-1); // should call o.foo(-1.0); but I see no way to implement it  
currently



More information about the Digitalmars-d mailing list