# Type instability in closure after reassigning a variable

**URL:** https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656
**Category:** General Usage
**Tags:** type, type-stability, closure
**Created:** [January 22, 2020, 10:57am UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656 "2020-01-22T10:57:34Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [January 22, 2020, 10:57am UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/1 "2020-01-22T10:57:34Z")

</div>

I’ve stumbled recently on this behavior (julia 1.3.1):

```julia
function test()
    s = "hello"
    s = lowercase(s)
    x() = s
    x()
end

```

and `@code_warntype test()` yields

```julia
Variables
  #self#::Core.Compiler.Const(test, false)
  s@_2::Core.Box
  x::var"#x#65"
  s@_4::Union{}

Body::Any
1 ─ (s@_2 = Core.Box())
│ Core.NewvarNode(:(x))
│ Core.setfield!(s@_2, :contents, "hello")
│ %4 = Core.isdefined(s@_2, :contents)::Bool
└── goto #3 if not %4
2 ─ goto #4
3 ─ Core.NewvarNode(:(s@_4))
└── s@_4
4 ┄ %9 = Core.getfield(s@_2, :contents)::Any
│ %10 = Main.lowercase(%9)::Union{AbstractChar, String}
│ Core.setfield!(s@_2, :contents, %10)
│ (x = %new(Main.:(var"#x#65"), s@_2))
│ %13 = (x)()::Any
└── return %13

```

It seems that offending line is `s = lowercase(s)`, because this versions are type stable

```julia
function test2()
    s = "hello"
    s2 = lowercase(s)
    x() = s2
    x()
end

function test3()
    s = "hello"
    s = lowercase(s)
    x(z) = z
    x(s)
end

function test4()
    s = "hello"
    x() = s
    x()
end

```

Can anyone explain why is it happening? And is there any rule of thumb how to proceed in situations like this? May be something like “do not reassign variables”, “if variable is reassigned, specify it as an argument to closure”.

It’s not a problem to patch my real world function with anything like `test2`, `test3` approach, but it’s more interesting to understand what is going on.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [January 22, 2020, 11:05am UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/2 "2020-01-22T11:05:40Z")

</div>

Sounds like you’re hitting [performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276).

---

<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 22, 2020, 2:15pm UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/3 "2020-01-22T14:15:24Z")

</div>

The manual has a discussion about this: [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured-1).

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [January 23, 2020, 7:03am UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/4 "2020-01-23T07:03:11Z")

</div>

Thank you, definitely I should have studied manual better. Somehow I didn’t connect this problem with the one described in manual, but now it is obvious.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [January 23, 2020, 8:26am UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/5 "2020-01-23T08:26:39Z")

</div>

> [@Skoffer](#):
>
> Somehow I didn’t connect this problem with the one described in manual,

Maybe you can improve the manual?

---

<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 23, 2020, 8:40am UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/6 "2020-01-23T08:40:14Z")

</div>

Maybe changing “Performance of captured variable” to something like “Performance of captured variables in closures” makes sense (to get the closure keyword in there)?

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [January 23, 2020, 7:25pm UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/7 "2020-01-23T19:25:38Z")

</div>

To be honest I am kind of scared to change anything in the manual 🙂 It was written by smart people who know what they are doing. I guess it was my fault, should have paid more attention.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [January 23, 2020, 8:35pm UTC](https://discourse.julialang.org/t/type-instability-in-closure-after-reassigning-a-variable/33656/8 "2020-01-23T20:35:09Z")

</div>

Well, you’re possibly the smartest right now about how this section could be improved. The PR will be reviewed, so what could possibly go wrong…
