functionjuliamultiple-dispatch

Dispatching on arguments after the slurping operator (args...) in julia


How would you implement a function like this:

function foo(a,b...,c)
    println(a,b,c)
end
foo(2,3,3,"last")

=> a = 2 , b = (3,3) , c = "last"

I cannot use something like:

function foo(a,b...) 
    c = b[end]
    println(a,b,c)
end

Because I want to dispatch on c, i.e. I want to have methods:

foo(a,b...,c::Foo)

and

foo(a,b...,c::Bar)

Also I cant have something like this:

foo_wrapper(a,b...) = foo(a,b[1:end-1],b[end])

Because I also want to dispatch on foo in general.

Is this somehow posssible?


Solution

  • you can invert the order and then dispatch on an auxiliary function:

    function foo(a,d...)
        c = last(d)
        b = d[begin:end-1]
        return _foo(a,c,b...)
    end
    
    function _foo(a,c::Int,b...)
        return c+1
    end
    
    function _foo(a,c::Float64,b...)
        return 2*c
    end
    

    in the REPL:

    julia> foo(1,2,3,4,5,6)
    7
    julia> foo(1,2,3,4,5,6.0)
    12.0
    
    julia> foo(1,2,8.0)
    16.0
    
    julia> foo(1,90) #b is of length zero in this case
    91