# Weird type instability

**URL:** <https://discourse.julialang.org/t/weird-type-instability/4120>\
**Category:** General Usage\
**Tags:** question, performance\
**Created:** [June 6, 2017, 11:00pm UTC](https://discourse.julialang.org/t/weird-type-instability/4120 "2017-06-06T23:00:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [June 6, 2017, 11:00pm UTC](https://discourse.julialang.org/t/weird-type-instability/4120/1 "2017-06-06T23:00:00Z")

</div>

I am having trouble understanding why `fun1` has a type instability, and not `fun2`, is this a bug?

```julia
function fun1(N::Integer, a::Number, test::Bool=false)
    if test
        b = exp(-abs2(a)/2)
        x = [(3b^n+2)/(n+1) for n = 0:N-1]
        return x
    else
        return rand(N)
    end
end

function fun2(N::Integer, a::Number, test::Bool=false)
    b = exp(-abs2(a)/2)
    x = [(3b^n+2)/(n+1) for n = 0:N-1]
    return x
end

```

```julia
julia> @code_warntype fun1(6,2,true)
Variables:
  #self#::#fun1
  N::Int64
  a::Int64
  test::Bool
  b::Core.Box
  x::Any
  #13::##13#14
...

```

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [June 6, 2017, 11:38pm UTC](https://discourse.julialang.org/t/weird-type-instability/4120/2 "2017-06-06T23:38:28Z")

</div>

I don’t have a great answer, but if you move `b` before the `if` statement, the code is type-stable.

This is the `@code_warntype` output for `fun1(6,2,true)` in 0.6:

```julia
Variables:
  #self#::#fun1
  N::Int64
  a::Int64
  test::Bool
  b::Core.Box
  x::Array{_,1} where _
  #3::##3#4

Body:
  begin
      b::Core.Box = $(Expr(:new, :(Core.Box)))
      NewvarNode(:(x::Array{_,1} where _))
...

```

The `Core.Box` is highlighted red.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [June 6, 2017, 11:42pm UTC](https://discourse.julialang.org/t/weird-type-instability/4120/3 "2017-06-06T23:42:48Z")

</div>

This is [performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276) See various workarounds there…

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [June 6, 2017, 11:51pm UTC](https://discourse.julialang.org/t/weird-type-instability/4120/4 "2017-06-06T23:51:40Z")

</div>

A type assertion did not help, but moving `b` did, thanks @anon94023334.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [June 7, 2017, 8:30am UTC](https://discourse.julialang.org/t/weird-type-instability/4120/5 "2017-06-07T08:30:31Z")

</div>

Moving the type assertion over to `b` helps (using the example in the issue ([performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276)), if we do:

```julia
function fun(N,a,t)
           if t
               b::Float64 = (a/2)
               x = [b for n = 1:N]
               return x
           else
               return Vector{Float64}(N)
           end
end

```

The type-instability goes away. But `b` is still boxed.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [June 7, 2017, 9:19am UTC](https://discourse.julialang.org/t/weird-type-instability/4120/6 "2017-06-07T09:19:03Z")

</div>

Helping Julia think about `b` looks to me like the best option. Consider,

```julia
function fun1(N::Integer, a::Number, test::Bool=false)
           if test let b = exp(-abs2(a)/2)
               x = [(3b^n+2)/(n+1) for n = 0:N-1]
               return x
           end else
               return rand(N)
           end
end

```

This way, not only is `fun1` type-stable, but `b` is not boxed and not allocated when `test==false`. Also, having the `let` on the same line as the `if` and the `end` with the `else` makes the code almost un-ugly.

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [June 7, 2017, 2:24pm UTC](https://discourse.julialang.org/t/weird-type-instability/4120/7 "2017-06-07T14:24:20Z")

</div>

That’s a nice syntax. Would be cool if the let block did not need an `end` here, but I guess if there wasn’t a bug it wouldn’t be needed anyway…

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [January 5, 2018, 1:41am UTC](https://discourse.julialang.org/t/weird-type-instability/4120/8 "2018-01-05T01:41:40Z")

</div>

Forgive me if I am asking a silly question. How is this problem related to 15276? I don’t see an inner function here.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 5, 2018, 1:43am UTC](https://discourse.julialang.org/t/weird-type-instability/4120/9 "2018-01-05T01:43:41Z")

</div>

List comprehension has similar issues.
