Let me preface this by saying that if all that comes out of this whole discussion is a thorough understanding of why ADL does work for C++ (for some definition of ‘work’) while it doesn’t make sense for Julia, I think this whole discussion, or at least parts of it , will have been very worthwhile. But I think there is hope for an ADL-like approach in Julia in the sense Jeff described:
I was definitely wrong in this comment, for any sensible interpretation of an Any
type analogue in C++.
First, the interpretation of f(x::Any)
as a function template. The following program compiles:
namespace XNamespace {
struct X { };
template <typename T>
auto f(T) {return 1;}
}
int main() {
XNamespace::X x;
f(x);
return 0;
}
Second, if Any
is treated as the universal base class, we get
namespace Base {
struct Any { };
}
namespace XNamespace {
struct X : public Base::Any { };
auto f(const Base::Any*) {return 1;}
}
int main()
{
Base::Any a;
f(&a); // error: 'f' was not declared in this scope (because Any is not defined in XNamespace)
XNamespace::X x;
f(&x); // fine
return 0;
}
In a way this is a good thing, since I agree that the issue Jeff raised here about a function becoming applicable as a result of signature narrowing would otherwise be a showstopper.
By the way, this account by Koenig lookup’s (ADL’s) namesake makes it sound like ADL was originally added for reasons of backwards compatibility (figures…) at the time of the introduction of namespaces in C++. Just a historical note; this is not meant as an argument against ADL.