December 01, 2009
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.
December 01, 2009
On Tue, 01 Dec 2009 14:26:04 +0300, retard <re@tard.com.invalid> 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.

I believe you should distinguish duck types from other types.

You shouldn't be able to call duckMethod given a reference to Object, it's a statically-typed language, after all.
December 01, 2009
Tue, 01 Dec 2009 14:30:43 +0300, Denis Koroskin wrote:

> On Tue, 01 Dec 2009 14:26:04 +0300, retard <re@tard.com.invalid> 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.
> 
> I believe you should distinguish duck types from other types.
> 
> You shouldn't be able to call duckMethod given a reference to Object, it's a statically-typed language, after all.

Agreed. But this new feature is a bit confusing - there isn't anything dynamic in it. It's more or less a compile time rewrite rule. It becomes dynamic when all of that can be done on runtime and there are no templates involved.
December 01, 2009
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. Also:

class Foo {
  ... opDispatch ...
}

class Bar : Foo {
  // Let's make Bar understand more things...
  ... opDispatch ...
}

Foo foo = new Bar();
foo.something();

will not work as expected because something() will be bound to Foo's opDispatch and it isn't a virtual method. Of course you can make opDispatch invoke a virtual function and override that function in Bar, but since there isn't a standard name or method for doing this everyone will start doing it their way (I don't like it when there's no standarization for well-known operations) and it looks like a hack.
December 01, 2009
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?
December 01, 2009
Ary Borenszweig 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.

I mean at compile-time, grrr.

Promise, no more talking with myself. :-P
December 01, 2009
On Tue, 01 Dec 2009 15:05:16 +0300, Ary Borenszweig <ary@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?
December 01, 2009
Tue, 01 Dec 2009 14:05:16 +0200, Ary Borenszweig 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?

Yep, this would be another cool feature. There aren't that many languages that actually support both dynamic and static types. I guess you would indeed need a new type, something like your Dynamic, to define this behavior. With dynamic types, the opDispatch would be automatically rewritten by the compiler to look up the hash table. This way the types would look syntactically like built-in method calls but would act like e.g. python objects.
December 01, 2009
Denis Koroskin wrote:
> On Tue, 01 Dec 2009 15:05:16 +0300, Ary Borenszweig <ary@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.
December 01, 2009
On Tue, 01 Dec 2009 15:47:43 +0300, Ary Borenszweig <ary@esperanto.org.ar> wrote:

> Denis Koroskin wrote:
>> On Tue, 01 Dec 2009 15:05:16 +0300, Ary Borenszweig <ary@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.