Multiple-dispatch depending on output type?


#1

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.


#2

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


#3

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


#4

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!


#5

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.


#6

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


#7

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.


#8

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


#9

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)


#10

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


#11

https://github.com/JuliaLang/julia/issues/19206