Method dispatch

Julia is a lot about multiple dispatching and I am having trouble to understand what an idiomatic way of using mulitple dispatch is.

My question is for small methods if I should define two different methods or if I should just use if else statements? (i.e. if typeof(...)...)

Example: I want to format/convert numbers or arrays of numbers into a string. Is the below approach reasonable? Or what is an idiomatic way to deal with the two cases (i) a single number and (ii) an array of things (e.g. numbers).

function _format_params(para::Number)
    string(para)
end

function _format_params(para::Array)
    join(para,", ")
end

Thanks for explaining.

I think for really small methods with only 2 or 3 different types, it can be more convenient to use an if else statement, but just remember that in that case neither you nor any user can extend your method for their own types. So the set of types your code works with is more or less “locked”. That can be more or less problematic depending on the expected use of that code.

One other thing to keep in mind, if you dispatch on Array there’s a whole lot of AbstractArrays that wouldn’t work with that code, even though all array-like things should work in principle.

1 Like

If you code is type stable, multiple methods produce compile time dispatch (fast) while the branch is decided at run time (slow).

3 Likes

If you code is type stable, multiple methods produce compile time dispatch (fast) while the branch is decided at run time (slow).

At cost of a little more effort on the first time the multiple methods are run, and sligtly more memory use (as there are many versions of the same compiled code), there is no free lunch. However, this is often the trade-off you want to do, unless low latency is crucial.

No, if the compiler can figure out the types, the unneeded branches are removed at compile time. So you will get the same performance.

Personally, though, I strongly prefer the multi-methods approach, also (or even particularly) for short methods like in the OP.

11 Likes

Using a distinct function for each type signature (with functions that take multiple arguments, “for each signature”) makes it easier to think about your program. If you need to revisit it at a much later date, perhaps to expand its coverage (as mentioned above) or to enhance its logic, this style can simplify doing so. Even where one later needs to incorporate some additional step for each method of that function, refactoring to use an outer function would be better than facing editing a internally composite source.

It is best practice to avoid if typeof(argument) == _ without some clear and strong reason to do so.

2 Likes

Thanks to all of you for your answers. I conclude that there are three things to take into consideration (i) performance, (ii) readability and (iii) extensibility.

For all three using distinct function may be helpful or even better. Thanks!