# Is this a bug? Nested Functions and NLsolve

**URL:** https://discourse.julialang.org/t/is-this-a-bug-nested-functions-and-nlsolve/86085
**Category:** General Usage
**Tags:** bug, optimization, functions
**Created:** [August 21, 2022, 12:15pm UTC](https://discourse.julialang.org/t/is-this-a-bug-nested-functions-and-nlsolve/86085 "2022-08-21T12:15:41Z")
**Posts on this page:** 1
**Showing post:** 19

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [August 22, 2022, 8:57am UTC](https://discourse.julialang.org/t/is-this-a-bug-nested-functions-and-nlsolve/86085/19 "2022-08-22T08:57:56Z")

</div>

Some more thoughts for OP because I’m taking OP’s word that they are new to Julia, though I have to say this is not a beginner’s question.

1. The scoping rules mentioned earlier reminded me to say that closures capture _by variable_ rather than by value. It’s not worded this way but the behavior is shown in the “Let Blocks” and “Loops and Comprehensions” sections of [Scope of Variables · The Julia Language](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks). Note how different closures capturing the same variable will use that variable’s most updated value, not the value at capture; to replicate the behavior of capturing values, you have to create different variables, and Julia’s `let`/`for` scoping rules makes that easy.

2. As mentioned and linked by @bkamins, a closure that captures variables is implemented as a hidden [functor](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects). The fields of the `struct` component correspond to the captured variables. Given this implementation, it actually makes a little sense that inference only happens when the captured variable is assigned just once prior to the closure. The closure is just a `struct` instance, and you can’t reassign a field there. If the captured variable is assigned after the closure or is assigned multiple times, then when the closure is instantiated, the corresponding field must be a mutable placeholder, the Core.Box. Core.Box [has been described](https://discourse.julialang.org/t/what-is-core-box/8717/3) as an internal analog of `Base.RefValue{Any}`, so hypothetically it could be redesigned to be parametric like a `RefValue`, which I expect a fix of issue 15276 to do.

3. The workaround `let r=r` in the Performance Tips section creates a new local `r` in a new local scope and assigns the outer `r`’s value to it, and boxing does not happen because that assignment occurs only once and prior to the closure instantiation. The `let` block is assigned to `f` because the block expression’s value is the last line’s value, so it somewhat acts like a function’s return. Note that not all block expressions do this; `for` and `while` do not.

4. Case 3 and case 4 in the OP are a couple known workarounds to get type inference working. Case 3: global `struct` and `function` definitions are implicitly `const` variables (local variables cannot be `const`!), and since functions only check global variables when compiled, they can compile with known constants, which are great for type inference. Case 4: functions compile with argument instances present at the function call, so passing in a function won’t be a problem for type inference. You should be careful that input variables are type stable; while the function call itself might be type-stable, you would have to dispatch to one of many functions at runtime rather than dispatching to one known function at compile-time of the surrounding method. Functions are singletons (a type with only 1 instance), so you should make sure the input variable is only ever assigned that one function, even if multiple times for no reason e.g. `ff4 = ff4`.

---

_[View the full topic](https://discourse.julialang.org/t/is-this-a-bug-nested-functions-and-nlsolve/86085)._
