Function name conflict: ADL / function merging?

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 :slight_smile:, 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.

4 Likes