Fully dynamic d by opDotExp overloading

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Apr 17 21:02:29 PDT 2009


Steven Schveighoffer wrote:
> On Fri, 17 Apr 2009 18:01:51 -0400, Andrei Alexandrescu 
> <SeeWebsiteForEmail at erdani.org> wrote:
>> Au contraire, it's a very adequate comparison. We changed the language 
>> to support ranges/arrays uniformly. Here, I'll paste your argument 
>> with the appropriate changes:
>>
>> ====
>> But globals acting as members cannot make arrays usable in the same way
>> as user-defined types, because one of the rules of arrays is that 
>> trying to call a non-existant member function on an array results in a 
>> compile-time error. The best your rule can do it make nonmember calls 
>> *seem* the same which is deceptive.
>> ====
> 
> Calling global functions as if they were array members does not subvert 
> the type system.  It is not even close to the same level of danger that 
> this is.

It's also far away from the same level of opportunity.

> I'm all for expanding runtime introspection that remains within the type 
> system, I'm even for adding some possibility to create dynamically 
> dispatched functions, as long as those functions are called differently 
> from normal functions.
> 
> I think you would agree that one of the main roles of the compiler is to 
> prevent you from making mistakes before it even gets to runtime.  
> Without knowing which calls the compiler checked and which ones it 
> didn't, I can't know where to spend time scrutinizing.

Of course I agree. The thing is, if you decide to use a dynamic type, 
then it will become like a dynamic type.

>>> If you want static and dynamic calls to be really usable in the same 
>>> way (like iterating over a range vs array), then there's only two 
>>> possibilities:
>>>  1. Make attempts to invokation a non-existant static function a 
>>> runtime error (obviously a bad idea).
>>> or
>>> 2. Provide a *secondary* syntax to invoke a method that works for 
>>> both static and dynamic. Such as through a reflection api:
>>>  traits(new Foo()).invokeMethod("bar");
>>
>> If I want to write an algorithm that calls "bar" twice, it should be:
>>
>> void twix(T)(T value)
>> {
>>     value.bar();
>>     value.bar();
>> }
>>
>> NOT
>>
>> void twix(T)(T value)
>> {
>>      static if (isDynamicType!T)
>>      {
>>          value.invokeMethod("bar");
>>          value.invokeMethod("bar");
>>      }
>>      else
>>      {
>>          value.bar();
>>          value.bar();
>>      }
>> }
>>
>> Please at least acknowledge that you are in receipt of this argument.
> 
> I think Nick's point number 2 is that you would have to write the above as:
> 
> void twix(T)(T value)
> {
>       value.invokeMethod("bar");
>       value.invokeMethod("bar");
> }
> 
> which would work whether bar was dynamically or statically defined.

And will uglify and pessimize all code for the benefit of the few.

>> We are discussing a language extension. That language extension will 
>> allow a type to choose flexibility in defining methods dynamically, 
>> while being otherwise integrated syntactically with the current 
>> values. This has advantages, but also alters the expectations.
> 
> As long as it identifies what can be dynamic and what cannot.  I can't 
> imagine Walter will go for this with his strict view of hijacking.

You will be surprised.


Andrei



More information about the Digitalmars-d mailing list