# Define another function in the definition of a function

**URL:** <https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016>\
**Category:** General Usage\
**Tags:** question, documentation, function\
**Created:** [March 23, 2024, 10:46am UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016 "2024-03-23T10:46:36Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [March 23, 2024, 10:46am UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/1 "2024-03-23T10:46:36Z")

</div>

I learned from somewhere I can’t remember that Julia allows defining a function in the definition of another function. Is there any detailed introduction for this usage?

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 23, 2024, 11:24am UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/2 "2024-03-23T11:24:13Z")

</div>

I use this feature a lot for passing parameters to callback functions:

```julia
function gamma(c_ep, e_p, gamma_est)
    function residual(Γ0)
        return c_ep([Γ0, gamma_est]) - e_p
    end
    find_zero(residual, 0.9)
end

```

In this example the inner function has access to all parameters of the outer function,  
even though it is called only with the value `Γ0` which is varied by the root finder (find\_zero) such that the returned value approaches zero.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [March 23, 2024, 12:34pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/3 "2024-03-23T12:34:27Z")

</div>

This is called a “closure” but it does not appear in many places in the basic docs. Here are pages with more details:

- [https://docs.julialang.org/en/v1/devdocs/functions/#Closures](https://docs.julialang.org/en/v1/devdocs/functions/#Closures)
- [https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured)

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [March 23, 2024, 3:49pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/4 "2024-03-23T15:49:50Z")

</div>

Functions are first-class objects in Julia and obey all of the normal scope rules. So, a function defined inside of another function can be used internally and can be returned for use externally. However, if you don’t return the function then it will cease to exist outside that local scope.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [March 24, 2024, 4:53pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/5 "2024-03-24T16:53:56Z")

</div>

Thanks to everyone for providing good resources and succinct and popular interpretation. They do make me get deeper understanding on the concept “closure”, but please forgive me that I still don’t fully understand it. 🥴

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [March 24, 2024, 5:06pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/6 "2024-03-24T17:06:08Z")

</div>

For example, the following code confused me ver much:

```julia
function f()
  i = 0
  function ()
    i += 1
  end
end
counter = f()
println(counter(), ", ", counter())

```

Can someone tell me what happened respectively when the closure function `counter()` was called twice? Why the value of `i` can be remembered?

Thanks!

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [March 24, 2024, 5:23pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/7 "2024-03-24T17:23:06Z")

</div>

This technically works but would probably be considered by many to be bad practice and likely to produce bugs. I am not a wizard in Julia’s low-level implementation, but my interpretation of this behavior is:

The function `f` returns a function that increments a global variable whose name was `i` at the moment this code was compiled. Once `f` returns, the binding of the name `i` to the variable whose data is stored at this location in memory is lost. However, the actual abandonment/recycling of that memory block is the responsibility of Julia’s garbage collector. Since a reference to that variable data continues to somewhere in the code, the memory block is not recycled automatically.

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [March 24, 2024, 5:42pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/8 "2024-03-24T17:42:11Z")

</div>

Julia is not an object-oriented language. It’s more of a functional language and makes extensive use of multiple dispatch; this is a defining feature and I found my productivity in the language increased greatly when I learned how to leverage it instead of fighting it.

In my opinion, the big mental shift between OO languages and Julia is the distinction between data and functions. You can use `struct`s to store data, and define functions that act on that data. In that way, a counter isn’t a function that carries some state inside of it, but would be better represented as a `struct` that carries that state and a function that increments or interacts with it.

```Julia
mutable struct MyCounter
    i::Int
end

function count(c::MyCounter)
    c.i += 1
    return c.i
end

myc = MyCounter(0)
count(myc)
# 1
count(myc)
# 2

```

You could also define the function to act directly on an instance of the type, like

```julia
function (c::MyCounter)()
    c.i += i
    return c.i
end

count = MyCounter(0)
count()
# 1
count()
# 2

```

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [March 24, 2024, 9:46pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/9 "2024-03-24T21:46:20Z")

</div>

> [@WuSiren](#):
>
> Can someone tell me what happened respectively when the closure function `counter()` was called twice? Why the value of `i` can be remembered?

That’s why it’s called a closure, in fact!

We say that the anonymous function “closes over” `i`. Ordinarily, the value of `i` is purely local, and would be lost when the function `f` returns. But because it returns a closure, and that closure refers to `i`, we say that `i` has “escaped”, so it continues to exist. Every time you call `counter()` that closed-over value of `i` is incremented. If you call `f` again, it creates a new value of `i`, a new function escapes, and the whole thing starts over.

One way to anchor this is to ask what would happen if the language didn’t support closures? At best, the anonymous function would throw an error because `i` doesn’t exist anymore. At worst, it would point to a stack frame which contains new data, and incrementing would corrupt it.

So when you a) allow functions to be returned from other functions and b) allow functions to refer to the outer lexical scope in which they’re defined, you’ll have closures.

Technically there can be two kinds of closures: ones passed as an argument are “downward closures”, like a do-block in Julia, and ones returned from functions, like your example, are “upward closures”. Some languages only support downward, or have efficient implementations of downward closures and inefficient implementations of upward closures. Julia supports both.

But you do have to be careful, because Julia’s escape analysis is not perfect. For instance, this example:

> [@ufechner7](#):
>
> ```julia
> function gamma(c_ep, e_p, gamma_est)
> function residual(Γ0)
> return c_ep([Γ0, gamma_est]) - e_p
> end
> find_zero(residual, 0.9)
> end
> 
> ```

Should probably be written like so:

```julia
function gamma(c_ep, e_p, gamma_est)
    residual = let c_ep = c_ep, e_p = e_p, gamma_est = gamma_est
        Γ0 -> c_ep([Γ0, gamma_est]) - e_p
    end
    find_zero(residual, 0.9)
end

```

It isn’t always clear when Julia can infer that variables won’t be shared or mutated, and that can change between releases, using this sort of defensive pattern will assure that the closed-over values are private to the closure.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [March 24, 2024, 9:52pm UTC](https://discourse.julialang.org/t/define-another-function-in-the-definition-of-a-function/112016/10 "2024-03-24T21:52:31Z")

</div>

> [@mike.ingold](#):
>
> The function `f` returns a function that increments a global variable whose name was `i` at the moment this code was compiled.

`i` isn’t a global variable, although it could be, that’s still a closure. But in this case it’s a function-local variable. From the closure’s perspective, it’s an `outer` variable, sometimes known as an upvalue.

> [@mike.ingold](#):
>
> Once `f` returns, the binding of the name `i` to the variable whose data is stored at this location in memory is lost. However, the actual abandonment/recycling of that memory block is the responsibility of Julia’s garbage collector. Since a reference to that variable data continues to somewhere in the code, the memory block is not recycled automatically.

This could be read (although I don’t believe you meant it that way) as though the continued existence of `i` depends on whether or not the garbage collector has run. So to clarify, when the closure escapes, everything it refers to escapes with it. Since `i` is a primitive/`isbits` type, it would start out allocated on a stack frame, not the heap, and escape analysis would move it to (I believe it’s) a special struct, which has a reference to the function and to its closed-over variables. As long as there’s a reference to the function, the data it can “see” will not be garbage collected.

> [@mike.ingold](#):
>
> This technically works but would probably be considered by many to be bad practice and likely to produce bugs.

There can be efficiency issues with closures in Julia, but not correctness issues. The counter example will work correctly and continue to yield a monotonically increasing value indefinitely (it’s pretty hard to reach `typemax(Int64)` starting from one).

It’s one of many techniques to have under one’s belt, closures are nothing to be afraid of. There’s nothing wrong with your callable-struct reimplementation of a counter, except for two things: it’s about twice as long, and anything can disrupt the count by setting the mutable counter to any value. With a closure, code doesn’t have access to `i`, except for the counter.

The flip side of that is that if you _want_ to be able to modify `i`, then a different approach, such as yours, is going to be a better choice.
