I’m far from an expert on how Julia inference works, but I ran into a situation where I could more succinctly define some type-stable custom promotion/conversion rules if Base._return_type was inferable, and was curious if this was possible theoretically. Basically this:
foo(::Int) = 3
foo(::Symbol) = :a
# Julia knows here the return type is going to be Int64
foo(3)
# why can't it know here that the return type of *this* call is Type{Int64} ?
Base._return_type(foo, (Int,))
I dug into the code a bit and it seems like the key is whether what the _methods function does is inferable, although I haven’t gotten any further and was curious to hear from any experts on this.
EDIT: minor change of Int → Int64 above for clarity.
Sorry, to clarify, I mean inferred in the following sense,
julia> using Base.Test
julia> @inferred Base._return_type(foo, (Int,))
ERROR: return type Type{Int64} does not match inferred return type Any
Stacktrace:
[1] error(::String) at ./error.jl:21
So the type of what Base._return_type returns is indeed Type{Int64}, but its not inferred at all (and that’s what I’m curious if it would be possible)
Huh, that’s interesting. So its inferred inside another function but somehow not on its own? Is this something special about Base._return_type or is it some other Julia “gotcha” I’m missing?
I’m guessing the compiler sees return_type as a pure function, and replaces a pure function call with constant arguments by a constant when compiling f ?