Function name conflict: ADL / function merging?

I think we can again learn from C++'s ADL approach here. The following is valid in C++:

namespace A {
    struct MyType{ };
    
    template <typename T>
    auto f(MyType, T) {return 1;};
}

// note: no using namespace A!
int main() {
    A::MyType m;
    f(m, 2);
}

That is, you can have generic (templated) functions that are still found correctly using argument-dependent lookup, by virtue of the fact that at least one of the arguments is specifically of a type defined in the same namespace (module in Julia) in which the function is defined.

If two user modules A and B define a function foo(::Number), then of course there is ambiguity when foo is used in a third package that uses both A and B, but argument-dependent lookup would not apply because Number is not defined in A or B.

A sketch of what this could like in Julia:

module A
struct AA end
foo(::AA) = :A
bar(::Number, ::AA) = :A
baz(::Number) = :A
end

module B
struct BB end
foo(::BB) = :B
bar(::Number, ::BB) = :B
baz(::Number) = :B
end

module C
import A, B # import, not using!
foo(A.AA()) # fine, calls foo in A
foo(B.BB()) # fine, calls foo in B
bar(A.AA()) # fine, calls bar in A
bar(B.BB()) # fine, calls bar in B
baz(1.0) # bad: ADL not triggered, so baz not defined.
end
1 Like