I don't know many of the details on type inference, but I do know that 
there is a bounded limit to the number of times inference is iteratively 
run. I remember seeing the number 4 in this context, too, but I don't know 
if it's the same 4.  

My naive assumption is that without this bound, Julia would effectively be 
trying to solve the halting problem… and it might never converge.

The goal is to simply get good enough without taking (literally) forever.

On Thursday, February 12, 2015 at 8:53:59 PM UTC-5, David Maxwell wrote:
>
>
>
> I ran into the following when tracking down a type instability issue. 
>  Consider the following type hierarchy:
>
> ```julia
>
> type T1{I<:Number} end
>
> type T2{T<:T1} 
> x::T
> end
>
> type T3{T<:T2} 
> x::T
> end
>
> type T4{T<:T3} 
> x::T
> end
>
> type T5{T<:T4} 
> x::T
> end
> ```
> Now, two functions, one which returns a `T4`, and one which returns a `T5`.
>
> ```julia
> function foo() 
> t2 = T2( T1{Float64}() )
> t3 = T3( t2 )
> T4( t3 )
> end
>
> function bar() 
> t2 = T2( T1{Float64}() )
> t3 = T3( t2 )
> t4 = T4( t3 )
> T5( t4 )
> end
> ```
>
> Julia is able to infer the return type of `foo`, but not of `bar`.
>
> ```
> julia> @code_warntype foo()
> Variables:
>   t2::T2{T1{Float64}}
>   t3::T3{T2{T1{Float64}}}
>
> Body:
>   begin  #
>       t2 = $(Expr(:new, T2{T1{Float64}}, :($(Expr(:new, T1{Float64}))))) # 
> line 22:
>       t3 = $(Expr(:new, T3{T2{T1{Float64}}}, :(t2::T2{T1{Float64}}))) # 
> line 23:
>       return $(Expr(:new, T4{T3{T2{T1{Float64}}}}, 
> :(t3::T3{T2{T1{Float64}}})))
>   end::T4{T3{T2{T1{Float64}}}}
> Variables:
>   t2::T2{T1{Float64}}
>   t3::T3{T2{T1{Float64}}}
>   t4::T4{T3{T2{T1{Float64}}}}
>
> julia> @code_warntype bar()
> Body:
>   begin  #
>       t2 = $(Expr(:new, T2{T1{Float64}}, :($(Expr(:new, T1{Float64}))))) # 
> line 28:
>       t3 = $(Expr(:new, T3{T2{T1{Float64}}}, :(t2::T2{T1{Float64}}))) # 
> line 29:
>       t4 = $(Expr(:new, T4{T3{T2{T1{Float64}}}}, 
> :(t3::T3{T2{T1{Float64}}}))) # line 30:
>       GenSym(0) = t4::T4{T3{T2{T1{Float64}}}}
>       return 
> ((top(apply_type))(T5,T4{T3{T2{T1{Float64}}}})::TYPE{_<:T5{T<:T4{T<:T3{T<:T2{T<:T1{I<:NUMBER}}}}}})(GenSym(0))::T5{T<:T4{T<:T3{T<:T2{T<:T1{I<:NUMBER}}}}}
>   end::T5{T<:T4{T<:T3{T<:T2{T<:T1{I<:NUMBER}}}}}
> ```
> Am I running up against a genuine limit in Julia's type inference?
>

Reply via email to