Multidispatch based on value of positional argument

Hi,
Just to make sure I understand multidispatch correctly here: There is no way to multidispatch based on a value in a positional argument, correct?

For example, something like:

function multidispatch(x,y,string_argument)
    string_argument = "my_string_1"
    println(x+y)
end

function multidispatch(x,y,string_argument)
    string_argument= "my_string_2"
    println(x*y)
end

multidispatch(5,7,"my_string_1")
12

multidispatch(5,7,"my_string_2")
35

Is not possible.

The only thing I could do is have a default without a 3rd argument, and a same function with a 3rd argument, i.e.:

function multidispatch(x,y)
    println(x+y)
end

function multidispatch(x,y,string_argument)
    string_argument
    println(x*y)
end

multidispatch(7,5)
12

multidispatch(7,5,"hello")
35

But this only allows for 2 dispatches, and isn’t really what I’m after.

Thanks for your help

Well.. It sort of is, for some types. You can use Val to lift a runtime value that’s isbits or of type Symbol to the type domain and dispatch on that in the signature. Things like your String won’t work though.

Keep in mind though that this very likely will dispatch dynamically, if the value you’re dispatching on is not known statically.

10 Likes

Thanks!
With Val, created this example that works correctly:

function md2(x,y,new_string::Val{Symbol("prod1")})
    new_string
    println(x+y)
end

function md2(x,y,new_string::Val{Symbol("prod2")})
    new_string
    println(x/y)
end

md2(8,4,Val(:prod1))
12
md2(8,4,Val(:prod2))
2.0

Another common pattern is to use custom types just for dispatch:

julia> struct Prod1 end

julia> struct Prod2 end

julia> md2(x,y,p::Prod1) = x + y
md2 (generic function with 1 method)

julia> md2(x,y,p::Prod2) = x * y
md2 (generic function with 2 methods)

julia> md2(8,4,Prod1())
12

julia> md2(8,4,Prod2())
32
9 Likes

And you could even make these into callable structs to cut down notation a bit (if that is appropriate in the OP’s situation, of course)

5 posts were split to a new topic: How to divide a project into files and submodules?