Dispatch.jl - A Julia package that makes function dispatching across modules simple, flexible, and efficient

I am bit confused by your package: Can’t you do the exact same thing without macros and just a slight adjustment of the project’s structure?

Usually how packages are structured is like this:
api.jl (basically identical to yours)

module Api
export Interface, foo

abstract type Interface end

# slightly more idiomatic: just declare the function and 
# let Julia raise a MethodError if an implementation is missing
# Sidenote: Good style is to put your docstring here
"""
   foo(interface, s, n)

Foo your interface given a String s and an Int n.
"""
function foo end 
end

moduleA.jl

module ModuleA

using ..Api # note the additional .

export A # don't reexport foo or Interface

struct A <: Interface end

# attach method to Api's foo function
# note we have to qualify the function's name with the module
# because we used `using .Api`
function Api.foo(i::A, s::String, n::Int)
    println("A::echo(s=$s, n=$n)")
end

end

moduleB.jl (uses import and thus can leave names unqualified)

module ModuleB

import ..Api: Interface, foo

export B # don't reexport foo or Interface

struct B <: Interface end

# attach method to Api's foo function
function foo(i::B, s::String, n::Int)
    println("B::echo(s=$s, n=$n)")
end

end

new main file of the package MyPackage.jl

module MyPackage

export foo, A, B

include("api.jl")
include("moduleA.jl")
include("moduleB.jl")

using .Api
using .moduleA
using .moduleB

end

Then we can do:

julia> include("MyPackage.jl")
Main.MyPackage

julia> b = MyPackage.B()
Main.MyPackage.moduleB.B()

julia> MyPackage.foo(b, "asdf", 3)
B::echo(s=asdf, n=3)

julia> a = MyPackage.A()
Main.MyPackage.moduleA.A()

julia> MyPackage.foo(a, "asdf", 3)
A::echo(s=asdf, n=3)

Maybe I missed your point though. Can you elaborate?

1 Like