# Unexpected closure behavior

**URL:** <https://discourse.julialang.org/t/unexpected-closure-behavior/129194>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 21, 2025, 3:23am UTC](https://discourse.julialang.org/t/unexpected-closure-behavior/129194 "2025-05-21T03:23:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)\
**Post date:** [May 21, 2025, 3:23am UTC](https://discourse.julialang.org/t/unexpected-closure-behavior/129194/1 "2025-05-21T03:23:31Z")

</div>

```julia
using Logging, Cthulhu
const glogger = Ref(ConsoleLogger())
function foo(a::Real, b::Real, c::Real, d::Real)
    x₁ = b + c + d
    e = b + c + d
    if e >= 0
        x₂ = b + c + d
        x₃ = b + c + d
        with_logger(() -> @info("x123", x₁, x₂, x₃), glogger[])
    end
    return x₁, x₂, x₃
end
@descend foo(1, 2, 3, 4)

```

When I analyze type stability, I find that the types of `x2` and `x3` cannot be correctly inferred. Does anyone know what is going on please?

```julia
 3 function foo(a::Int64::Real, b::Int64::Real, c::Int64::Real, d::Int64::Real)::Tuple{Int64, Any, Any}
 4 x₁::Int64 = (b::Int64 + c::Int64 + d::Int64)::Int64       
 5 e::Int64 = (b::Int64 + c::Int64 + d::Int64)::Int64        
 6 if (e::Int64 >= 0)::Bool
 7 x₂ = (b::Int64 + c::Int64 + d::Int64)::Int64
 8 x₃ = (b::Int64 + c::Int64 + d::Int64)::Int64
 9 with_logger(() -> @info("x123", x₁, x₂, x₃), glogger::Base.RefValue{ConsoleLogger}[]::ConsoleLogger)
10 end
11 return x₁::Int64, x₂::Core.Box, x₃::Core.Box::Any
12 end

```

---

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [May 21, 2025, 5:05am UTC](https://discourse.julialang.org/t/unexpected-closure-behavior/129194/2 "2025-05-21T05:05:33Z")

</div>

If ‘e’ is negative, x2 and x3 are not defined… isn’t that causing problems, as type inference doesn’t use the actual values but only types?

---

<div class="post-metadata">

**Author:** ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)\
**Post date:** [May 21, 2025, 5:28am UTC](https://discourse.julialang.org/t/unexpected-closure-behavior/129194/3 "2025-05-21T05:28:34Z")

</div>

That may not be the point, you can add

```julia
x₂ = b + c + d
x₃ = b + c + d

```

after `if ... end` block, but the problem remains.

---

<div class="post-metadata">

**Author:** ![tverho](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tverho](https://discourse.julialang.org/u/tverho)\
**Post date:** [May 21, 2025, 6:52am UTC](https://discourse.julialang.org/t/unexpected-closure-behavior/129194/4 "2025-05-21T06:52:22Z")

</div>

If the captured variables are mutated outside the closure, that usually causes them to be boxed. One might expect that writing

```julia
else
    x₂ = b + c + d
    x₃ = b + c + d
end

```

would avoid the boxing, but that doesn’t seem to be the case. Perhaps initialization in a branch is always effectively mutation from the point of view of the compiler. However, the usual

```julia
let x₂=x₂, x₃=x₃
    with_logger(() -> @info("x123", x₁, x₂, x₃), glogger[])
end

```

fixes it.

---

<div class="post-metadata">

**Author:** ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)\
**Post date:** [May 21, 2025, 7:18am UTC](https://discourse.julialang.org/t/unexpected-closure-behavior/129194/5 "2025-05-21T07:18:49Z")

</div>

Thank you, your solution works well.
