Should we add `a * b` for vectors?

Walter Bright newshound2 at digitalmars.com
Tue Oct 3 19:25:32 UTC 2017


On 10/2/2017 4:15 AM, Timon Gehr wrote:
> On 30.09.2017 23:45, Walter Bright wrote:
>> ...
>> D has other ways of doing what ADL does,
> 
> What are those ways? I'm aware of two basic strategies, both suboptimal:
> 
> - Every module imports all other modules.
> - Proliferation of wrapper types.

https://dlang.org/spec/operatoroverloading.html#binary

C++ does not have this notion.


> It's not per se related to operator overloading:

ADL was specifically intended to address operator overloading.


> ---
> module a;
> import std.range: isInputRange;
> auto sum(R)(R r)if(isInputRange!R){
>      typeof(r.front) result;
>      for(auto t=r.save;!t.empty;t.popFront())
>          result+=t.front;
>      return result;
> }
> ---
> 
> ---
> module b;
> import a;
> import std.range;
> 
> void main(){
>      int[] a = [1,2,3,4];
>      import std.stdio: writeln;
>      writeln(a.front); // ok
>      writeln(sum(a)); // error, the type is an input range, yet has no front
> }
> ---
> 
> I.e., the operations that are supported on the type differ depending on the 
> module that it is accessed from. If there are multiple definitions of the same 
> name, different modules might not agree which one is being referred to. (This is 
> particularly likely for overloaded operators, as the set of names is finite and 
> small. This is what Manu means when he says it can lead to nasty surprises. This 
> is very plausible, but I don't have a good example.)

This gets into the anti-hijacking support D has (and C++ does not). If multiple 
modules with declarations of `writeln` are in scope, the compiler attempts a 
match with `writeln` in each module. If there is a match with more than one 
module, an error is issued. The user will then have to specify which one he wants.

This is specifically designed to prevent nasty surprises. C++ has a big problem 
with ADL in that overloading is not encapsulated and any #included header can 
inadvertently add more overloads that may be entirely unrelated. Any .h can 
crack open any namespace and insert more overloads into it. It's completely 
unhygienic and uncontrollable.

As for the specific example you gave, I get:

a.d(3): Error: no property 'front' for type 'int[]'
a.d(4): Error: no property 'save' for type 'int[]'
b.d(8): Error: template instance a.sum!(int[]) error instantiating


More information about the Digitalmars-d mailing list