# Comprehension type inference

**URL:** <https://discourse.julialang.org/t/comprehension-type-inference/4324>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 17, 2017, 10:05am UTC](https://discourse.julialang.org/t/comprehension-type-inference/4324 "2017-06-17T10:05:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [June 17, 2017, 10:05am UTC](https://discourse.julialang.org/t/comprehension-type-inference/4324/1 "2017-06-17T10:05:48Z")

</div>

Could someone explain me why Julia has problem with type inference in the following function (the comprehension example is taken from Julia Documentation):

```julia
julia> f() = [(i,j) for i=1:3 for j=1:i]                                     
f (generic function with 1 method)                                           
                                                                             
julia> @code_warntype f()
Variables:
  #self#::#f
  #61::##61#63

Body:
  begin
      SSAValue(1) = $(Expr(:new, UnitRange{Int64}, 1, :((Base.select_value)((Base.sle_int)(1, 3)::Bool, 3, (Base.sub_int)(1, 1)::Int64)::Int64)))
      SSAValue(2) = $(Expr(:new, Base.Generator{UnitRange{Int64},##61#63}, :($(QuoteNode(#61))), SSAValue(1)))
      SSAValue(3) = $(Expr(:new, Base.Iterators.Flatten{Base.Generator{UnitRange{Int64},##61#63}}, SSAValue(2)))
      return $(Expr(:invoke, MethodInstance for grow_to!(::Array{Tuple{Int64,Int64},1}, ::Base.Iterators.Flatten{Base.Generator{UnitRange{Int64},##61#63}}), :(Base.grow_to!), :($(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Tuple{Int64,Int64},1}, svec(Any, Int64), Array{Tuple{Int64,Int64},1}, 0, 0, 0))), SSAValue(3)))
  end::Union{Array{Tuple{Int64,Int64},1}, Array{Union{},1}}

```

In what cases can I expect such problems with type inference?  
For example the return type of function `g() = [(i,j) for i=1:3, j=1:3]` is inferred properly.

---

<div class="post-metadata">

**Author:** ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)\
**Post date:** [June 17, 2017, 3:24pm UTC](https://discourse.julialang.org/t/comprehension-type-inference/4324/2 "2017-06-17T15:24:00Z")

</div>

I think it’s a known bug, see [performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276)

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [June 17, 2017, 3:36pm UTC](https://discourse.julialang.org/t/comprehension-type-inference/4324/3 "2017-06-17T15:36:25Z")

</div>

I thought it was rather related with safeguarding against an empty collection. The problem is there even if the value in the comprehension is a literal:

```julia
julia> f() = [1 for i in 1:2 for j in 1:2]
f (generic function with 1 method)

julia> @code_warntype f()
Variables:
  #self#::#f
  #1::##1#3

Body:
  begin
      SSAValue(1) = $(Expr(:new, UnitRange{Int64}, 1, :((Base.select_value)((Base.sle_int)(1, 2)::Bool, 2, (Base.sub_int)(1, 1)::Int64)::Int64)))
      SSAValue(2) = $(Expr(:new, Base.Generator{UnitRange{Int64},##1#3}, :($(QuoteNode(#1))), SSAValue(1)))
      SSAValue(3) = $(Expr(:new, Base.Iterators.Flatten{Base.Generator{UnitRange{Int64},##1#3}}, SSAValue(2)))
      return $(Expr(:invoke, MethodInstance for grow_to!(::Array{Int64,1}, ::Base.Iterators.Flatten{Base.Generator{UnitRange{Int64},##1#3}}), :(Base.grow_to!), :($(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Int64,1}, svec(Any, Int64), Array{Int64,1}, 0, 0, 0))), SSAValue(3)))
  end::Union{Array{Int64,1}, Array{Union{},1}}

```
