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

Reply via email to