dynamic classes and duck typing

Bill Baxter wbaxter at gmail.com
Tue Dec 1 14:24:30 PST 2009


On Tue, Dec 1, 2009 at 1:10 PM, Steven Schveighoffer
<schveiguy at yahoo.com> wrote:
> On Tue, 01 Dec 2009 16:01:41 -0500, Bill Baxter <wbaxter at gmail.com> wrote:
>
>> On Tue, Dec 1, 2009 at 12:38 PM, Steven Schveighoffer
>> <schveiguy at yahoo.com> wrote:
>>>
>>> On Tue, 01 Dec 2009 15:06:27 -0500, Pelle Månsson
>>> <pelle.mansson at gmail.com>
>>> wrote:
>>>
>>>> Steven Schveighoffer wrote:
>>>
>>>>>  Isn't opBinary almost identical to opDispatch?  The only difference I
>>>>> see is that opBinary works with operators as the 'symbol' and dispatch
>>>>> works
>>>>> with valid symbols.  Is it important to distinguish between operators
>>>>> and
>>>>> custom dispatch?
>>>>>  -Steve
>>>>
>>>> opBinary is a binary operator, opDispatch can be anything. I think they
>>>> should be kept separate.
>>>
>>> You could say the same thing about dynamic properties.  How come we don't
>>> split those out as opProperty?
>>
>> That's because of what Andrei pointed out:  &a.b .
>> The compiler can't tell if you want a delegate to the method b, or the
>> address of a property b.
>
> Huh?

If you have this:

struct S {
int opProperty(string s)() if(s=="b") { ... }
int opDispatch(string s)() if(s=="b") { ... }
}

S a;
auto x = &a.b;

which one are you talking about?  The property a.b or the method
a.b()?  That's why you can't split out properties as opProperty.

But actually maybe this is no longer true?  I'm not sure what the
@property is going to do to how we refer to a function as a piece of
data.  Maybe D won't require the & any more.  Then &a.b could only
refer to the property.

So anyway, I think your argument is bad as things currently stand.
You asked if opBinary and opDispatch are separate, then why not
opProperty.  Well, there's an ambiguity if you split off opProperty,
that's why not.  There isn't any ambiguity in splitting off opBinary.

>>> opDispatch can do opBinary, it's a subset.  It makes no sense to define
>>> opDispatch(string s)() if(s == "+") I agree, but I don't see any reason
>>> why
>>> opBinary(string s)() would fail to compile...
>>
>> I don't get your point.  It's the compiler that decides to call
>> opBinary and it's only gonna decide to do so for binary operators.
>> Even if you pretend opBinary can accept any string.
>
> My point is, the set of strings passed by the compiler to opBinary is
> completely disjoint from the set of strings passed by the compiler to
> opDispatch.  So the only reason to keep them separate is because you want to
> force people to split their code between operators and methods/properties.
>
> There is no technical reason we need to keep them separate or to combine
> them that I can see.

How about this: given only a catch-all opDispatch which implements
dynamic dispatch, the compiler cannot statically determine if
operators are really implemented or not.  Since the list of operators
is always finite, it makes sense to have them in a separate
"namespace" of sorts.   That way if you implement a catch-all
opBinary, you're only saying that you implement all /operators/ not
all possible methods.  And vice versa, you can specify that you only
implement some operators, but still have dynamic dispatch that
forwards all named methods.

Perhaps, though, there should be a rule where opBinary("+") is tried
first, and if not defined then opDispatch("+") could be tried.  Not
sure if it's worth the mental burden of another rule, though.

--bb



More information about the Digitalmars-d mailing list