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.

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.

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)