Why specify argument types and return types

That’s not multiple dispatch, that’s compile-time specialization.

Multiple dispatch means having different versions of the functions (different methods) for different argument types.

Three reasons to declare argument types:

  • Clarity: if you want to give more information to the user about what type your function is expecting.
  • Correctness: if your function may give wrong results or unexpected errors unless the arguments have certain types.
  • Dispatch: If you want to implement different versions (methods) of your function for different types.

Not on this list is performance: as you say, the Julia compiler always specializes a function at compile-time for the concrete argument types, so there is no performance benefit to an argument-type declaration.

  • Caveat: there are exceptions where Julia’s compiler will not type-specialize unless you explicitly add a declaration, e.g. for higher-order functions, but this is a relatively rare concern.

On the other hand, if you over-specify the argument types (e.g. using Float64 instead of just Real or Vector{Float64} instead of AbstractVector{<:Real}), then you may be unnecessarily restricting the generality and composability of your function (with no performance benefit).

Declaring return types is generally unnecessary also, but occasionally may be a convenience if you have several points in the function where you may return a value and you don’t want to individually make sure they each return the same value. i.e. if you want to enforce type-stability in a bit of a lazy way, or in rare cases if you want to correct for some failure of type inference. Again you have to be careful that in doing so you don’t overly restrict your function’s generality.

32 Likes