Multiple-dispatch depending on output type?


I was just thinking about multiple-dispatch and something just occurred to me. Currently, there is multiple-dispatch based on input types but what if it can dispatch on output type as well?

For example sqrt(-1) will fail currently but sqrt(-1)::Complex should succeed because sqrt is dispatching on output type. One way around this currently is to have the output type as a parameter e.g. sqrt(-1, outType = Complex) then it will dispatch based on Type{Complex}. For example

import Base.sqrt
sqrt(x, ::Type{Complex}) = sqrt(Complex(x))
sqrt(-1, Complex) # works fine

Of course this a very weird idea as most of the time we write

x = sqrt(-1)

and at this point, x isn’t defined, so it will fail; but

x::Complex = sqrt(-1)

should work if multiple-dispatch is on output type.

I can see how implementing this sort of things will rely on more magic, so may not be a good idea but I think this may be something not many people have talked about. So worth mentioning.


We already do this for some functions, but in the first argument, notably trunc, round, floor, ceil.


Ok. Is it available as a language feature or is it defined function by function in the core implementation?


No, it’s defined function by function. But the nice thing about Julia is that it is easy to add new methods to existing functions!


Are you talking about trunc(T, x) methods? I am not sure this is what @xiaodai was asking about, my understanding is that he would like

x::Complex = sqrt(-1)

to be lowered into a form where Complex becomes an argument to sqrt.


If, then it should probably be: x = sqrt(-1)::Complex.


But this is already taken for type assertion syntax.

Also, I am not saying that the original idea is a good one, just trying to interpret what was suggested.

I actually think that making caller context available to functions in this subtle, optional way is not a good design choice. If the function needs that information, it should be explicit in the argument list.


Haskell dispatches on output type (but I’m not saying Julia should).


One thing: typically in Julia, when making a method of a function where you want to dispatch on a type, in particular to indicate the return type, it is the first argument, for example, convert, rand, zero, etc., so if you did this, it probably should be something like: sqrt(Complex, -1)


What if your function accepta a function as argument. It that case do we put the type second to allow for the do notation?