dynamic classes and duck typing
Bill Baxter
wbaxter at gmail.com
Tue Dec 1 05:38:39 PST 2009
On Tue, Dec 1, 2009 at 5:18 AM, Lutger <lutger.blijdestijn at gmail.com> wrote:
> Ary Borenszweig 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);
>> ---
>>
>> 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.
>
> I don't get it, what if WhatTypeToPutHere does a dynamic lookup, then it's
> pretty much the same a Javascript isn't it? Except that everything in
> Javascript does dynamic lookup and in D you are restricted to types that
> have this dynamic lookup (which, pending a phobos solution you have to code
> yourself). Do you mean to say this 'except' is the obstacle somehow?
>
> To say it in code:
>
> void yourMagicDFunction(T)(T d)
> if ( ImplementsFooOrDispatch!T )
> {
> d.foo(); // may (or not) be rewritten as d.opDispatch!"foo"
> }
>
> In javascript I understand it is like this:
>
> void yourMagicJavascriptFunction(T d)
> {
> d.foo(); // rewritten as d["foo"]
> }
>
> But with opDisptach implemented like this it is the same in D:
>
> class DynamicThing
> {
> void opDispatch(string name)()
> {
> auto func = this.lookupTable[name]; // looks up 'foo'
> func(); //
> }
> }
>
> How is that less dynamic? You would be able to call or even redefine at
> runtime, for example, signals defined in xml files used to build gui
> components.
It is a bit less dynamic because in D it's all done with templates.
For instance in Javascript you can easily pass
yourMagicJavascriptFunction around to other functions.
And you can rebind the method by setting d.foo = &someOtherFunction.
Instead of d.lookupTable["foo"] = &someOtherFunction.
But I'm not sure such differences make a big impact on any major class
of use cases.
--bb
More information about the Digitalmars-d
mailing list