How can I create a function type with custom Input and Output type

– advanced question –

Let’s say, I have a Vector{Int} and would like to transform it into a Vector{Float64}.

One super generic way to do it is to use the hidden return_type function Core.Compiler.return_type. Namely with the following

Core.Compiler.return_type(map, Tuple{typeof(x -> 0.3*x), Vector{Int}})  # Array{Float64,1}

The pitfall is that I have to give a concrete function… Hence the question:
Can I construct a FunctionType with a given Input and a given Output Type without actually providing an implementation?
It should make the following work

Core.Compiler.return_type(map, Tuple{FunctionType(Int, Float64), Vector{Int}})  # Array{Float64,1}

I suspect I am not understanding what you want. If you make a vector of ints, you can transform to a vector of floats quite easily.

julia> vi = [3;4;5]
3-element Array{Int64,1}:
 3
 4
 5

julia> vf = Float64.(vi)
3-element Array{Float64,1}:
 3.0
 4.0
 5.0
1 Like
2 Likes

that sounds really good! using the type itself as a caster actually works!

Core.Compiler.return_type(map, Tuple{Type{Float64}, Vector{Int}})  # Array{Float64,1}

that is the perfect solution :slight_smile:

however requires an extra dependency, which is why using Type{Float64} instead of FunctionWrapper{<:Any, Float64} is an actual alternative

Relying on return_type is not advised. It might very well change behavior or disappear in the future. FunctionWrappers is a very lightweight dependency. I bet there are people much better then I that can tell you the pitfalls of using return_type.

1 Like

thank you very much for the warning

I actually kind of fall in love with this programmatic type inference. I know it sometimes does not work, but I am fine with that.

The idea it should be gone in the future (without proper replacement) sounds actually quite frightening. Wouldn’t this mean that also @code_warning macro couldn’t work?

Do you know a link to a discussion where I can read more about return_type and its future?

I was searching for it on slack, but it seems it has disappeared du to the 10k message limit :frowning: I think the conclusions were that code relying on return_type would potentially break in the future due to compiler latency optimizations

1 Like

I asked for some help on slack#internals and pointed to this thread

1 Like

return_type is used internally by the compiler to infer types with the intent to generate good machine code within a “reasonable” compilation time budget. Pasting some stuff I said over on slack:

return_type approximates the return type of a function. The amount of approximation is tuneable and it can be helpful to return a more approximate (“wider”) type to reduce the amount of unproductive work type inference does. So this may be changed in the future.

If you use return_type in a way which can affect the meaning of your program, the program may break when the compiler team adjusts the inference heuristics.

Basically, the compiler team reserves the right to adjust return_type to balance the precision of type inference against the compilation cost. Less compilation cost means faster “time to first plot”, etc, which is great for the interactive user experience.

By the way, I can’t imagine @code_warntype going away, but if it did I’m sure the compiler team would be replacing it with some other mechanism to give you insight into compilation.

1 Like