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.
so I am curious for an example from Manu about why it doesn't work.
It's not per se related to 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.)