I’m playing around with type inference in Julia.
I have the following simple function:
f(x,y) = x+y
function q2()
x = Number[1.0,3]
a = 4
b = 2
c = f(x[1],a)
d = f(b,c)
f(d,x[2])
end
@code_warntype q2()
Here’s the output:
MethodInstance for q2()
from q2() in Main at In[114]:2
Arguments
#self#::Core.Const(q2)
Locals
d::Any
c::Any
b::Int64
a::Int64
x::Vector{Number}
Body::Any
1 ─ (x = Base.getindex(Main.Number, 1.0, 3))
│ (a = 4)
│ (b = 2)
│ %4 = Base.getindex(x, 1)::Number
│ (c = Main.f(%4, a::Core.Const(4)))
│ (d = Main.f(b::Core.Const(2), c))
│ %7 = d::Any
│ %8 = Base.getindex(x, 2)::Number
│ %9 = Main.f(%7, %8)::Any
└── return %9
I’m surprised that the type of c
is Any
. Given that f
is adding a Float64
and a Int64
, I would expect c
to be inferred as a Float64
.
I can use c::Float64 = f(x[1],a)
to get type inference for c
and d
, which is also surprising b/c if Julia can determine that d
is a Float64
by knowing that c
is a Float64
, then it can track the types that flow through f
, but that would imply it could predict the types for c
w/o ever having an explicit type annotation.
Even after doing c::Float64
, the final line (f(d,x[2])
) seems to return Any
:
%11 = Main.f(%9, %10)::Any
return %11
This is surprising, b/c Julia knows the type of %9
is Float64
and Julia knows the type of %10
is Number
. And presumably Float64
+ Number
is at the very least Number
instead of Any
.
Any reason why Julia’s type inference is having a hard time here?
Furthermore, code_warntype
displays Number
in red. Is it bad if your code has types like Number
(instead of more concrete types like Float64
)?