dynamic classes and duck typing

Steven Schveighoffer schveiguy at yahoo.com
Tue Dec 1 09:40:21 PST 2009


On Tue, 01 Dec 2009 11:58:43 -0500, Denis Koroskin <2korden at gmail.com>  
wrote:

> On Tue, 01 Dec 2009 19:41:46 +0300, Steven Schveighoffer  
> <schveiguy at yahoo.com> wrote:
>
>> On Tue, 01 Dec 2009 11:20:06 -0500, Denis Koroskin <2korden at gmail.com>  
>> wrote:
>>
>>> On Tue, 01 Dec 2009 19:02:27 +0300, Steven Schveighoffer  
>>> <schveiguy at yahoo.com> wrote:
>>>
>>>>
>>>> You are missing the point of opDispatch.  It is not runtime defined,  
>>>> because the compiler statically decides to call opDispatch.  The  
>>>> dynamic part of opDispatch comes if you want to do something based on  
>>>> runtime values within the opDispatch function.  e.g. the compiler  
>>>> doesn't decide at *runtime* whether to call opDispatch or some normal  
>>>> function named quack, it's decided at compile time.  opDispatch could  
>>>> be completely compile-time defined since it is a template.  But the  
>>>> 'dynamicness' of it is basically no more dynamic than a normal  
>>>> function which does something based on runtime values.
>>>>
>>>> Compare that to a dynamic language with which you can add methods to  
>>>> any object instance to make it different than another object, or make  
>>>> it conform to some interface.
>>>>
>>>
>>> Well, I believe it's possible to implement the same with opDispatch  
>>> (not just to any object, but to those that support it):
>>>
>>> void foo() {}
>>>
>>> Dynamic d = ..;
>>> if (!d.foo) {
>>>      d.foo = &foo;
>>> }
>>>
>>> d.foo();
>>
>> You could do something like this (I don't think your exact syntax would  
>> work), but you could also do something like this without opDispatch.    
>> But the name 'foo' is still statically decided.  Note that opDispatch  
>> doesn't implement this ability for you, you still have to implement the  
>> dynamic calls behind it.  The special nature of opDispatch is how you  
>> can define how to map any symbol to any implementation without having  
>> to explicitly use strings.  In fact, opDispatch is slightly less  
>> powerful than such a method if the method uses a runtime string for  
>> dispatch.
>>
>> For example, in php, I can do this:
>>
>> foo($var)
>> {
>>     $obj->$var();
>> }
>>
>> The equivalent in D would be:
>>
>> foo(string var)
>> {
>>     obj.opDispatch!(var)();
>> }
>>
>> This I would consider to be true runtime-decided dispatch.
>>
>> -Steve
>
> As pointed out, ActionScript and JavaScript use foo.bar and foo["bar"]  
> interchangeably, so I believe we could do something similar.
>
> I believe there is no real difference between d.foo and d.bar for  
> opDispatch (except that it could calculate string hash at compile time  
> for faster hast-table lookup), and it would just call a generic run-time  
> method anyway. As such, this method could be made visible to everyone:
>
> class Dynamic
> {
>      // getter
>      @property Dynamic opDispatch(string prop)
>      {
>          return this[prop];
>      }
>
>      // setter
>      @property void opDispatch(string prop)(Dynamic value)
>      {
>          this[prop] = value;
>      }
>
>      ref Dynamic opIndex(string propName)
>      {
>          // do a hash-table lookup
>      }
>
>      Dynamic opCall(Args...)(Args args)
>      {
>          // do magic
>      }
> }

This is a very nice example, I only see one minor problem with it:  the  
"do a hash table lookup" has to tentatively add an element if one doesn't  
yet exist.

However, opDispatch is even less runtime-decided in this example (it can  
always be inlined).

> So essentially, opDispatch is just a syntax sugar. But it's very  
> important one, because not only it makes writing code easier, it would  
> allow using dynamic objects with generic algorithms.

Essentially you could say opDispatch is dynamic at compile time.  Runtime,  
not so much.  But anything decided at compile time can be forwarded to a  
runtime function.

Without opDispatch, you already can get dynamic runtime function calling  
via a similar method you outline above (I didn't think of using the array  
syntax, and I've been using Javascript quite a bit lately!), but you can't  
get dynamic function calling that's drop-in replaceable with normal  
function calling at compile time without opDispatch.  I like that  
explanation.  It is probably the most compelling usage for opDispatch.

-Steve



More information about the Digitalmars-d mailing list