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`

)?