# Anonymous function's type and methods last forever?

**URL:** <https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676>\
**Category:** Internals & Design\
**Created:** [July 5, 2024, 6:19pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676 "2024-07-05T18:19:56Z")\
**Posts on this page:** 9\
**Page:** 1

<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:** [July 5, 2024, 6:19pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/1 "2024-07-05T18:19:56Z")

</div>

My understanding is that an anonymous function is implemented as an instance of a type assigned to a generated name in the global scope, and the type and its methods should thus persist for the rest of the process. However I read in several places that anonymous functions were garbage collected and wasn’t sure of the implications, so I wanted to check. The general concern here would be `eval`ing an arbitrary number of anonymous functions would result in an unavoidable memory leak.

Example of a generated name:

```julia
julia> names(Main;all=true) # fresh session
5-element Vector{Symbol}:
 Symbol("##meta#58")
 :Base
 :Core
 :InteractiveUtils
 :Main

julia> (x->x) |> typeof # type's generated name
var"#1#2"

julia> names(Main;all=true) # generated name is here
6-element Vector{Symbol}:
 Symbol("##meta#58")
 Symbol("#1#2")
 :Base
 :Core
 :InteractiveUtils
 :Main

julia> isconst(Main, Symbol("#1#2")) # seems persistent
true

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 5, 2024, 6:49pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/2 "2024-07-05T18:49:05Z")

</div>

> [@Benny](#):
>
> However I read in several places that anonymous functions were garbage collected and wasn’t sure of the implications, so I wanted to check.

The particular instantiation is garbage collected, but the type & associated constructor sticks around. I don’t think there’s any source claiming that the type itself would be collected too?

---

<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:** [July 5, 2024, 6:52pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/3 "2024-07-05T18:52:07Z")

</div>

Right, there’s no even semi-official source about collecting anonymous functions, these were errant vaguely worded comments. I did think at first they were wholly referring to instances, but half the examples had instances that didn’t need to be garbage collected so there was an implication that something else was. It contradicted everything I could observe, but worth verifying.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 5, 2024, 7:00pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/4 "2024-07-05T19:00:09Z")

</div>

Do you have an example of such an anonymous function that doesn’t need to be garbage collected?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 5, 2024, 7:22pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/5 "2024-07-05T19:22:03Z")

</div>

> [@Benny](#):
>
> The general concern here would be `eval`ing an arbitrary number of anonymous functions would result in an unavoidable memory leak.

If you are doing code generation of lots of anonymous functions symbolically, then compiling them via `eval`, you might be better of with something like DynamicExpressions.jl.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 5, 2024, 7:35pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/6 "2024-07-05T19:35:58Z")

</div>

Discussed recently:

> [@How's the progress in garbage-collecting unused functions?](https://discourse.julialang.org/t/hows-the-progress-in-garbage-collecting-unused-functions/116300):
>
> When a function compilation in Julia no longer gets used, it doesn’t go away. Instead, it stays in memory. Normally, this is not a problem because you don’t generate so many functions in the first place, and each function doesn’t take much memory. However, in my (private) symbolic regression use case, I generated a lot of functions and learned the painful way that unused generated functions stay in memory. This poses a serious issue in semi-dynamic programs where codes are generated and compiled…

---

<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:** [July 5, 2024, 7:48pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/7 "2024-07-05T19:48:05Z")

</div>

Sanity considered checked, thanks everyone!

> [@Sukera](#):
>
> Do you have an example of such an anonymous function that doesn’t need to be garbage collected?

Ones isolated to a local scope would just live on the stack.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 5, 2024, 8:01pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/8 "2024-07-05T20:01:16Z")

</div>

> [@Benny](#):
>
> Ones isolated to a local scope would just live on the stack.

Pretty sure a local function is actually implemented as a global function, with an automatically generated name. As long as it’s not a closure.

---

<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:** [July 5, 2024, 8:24pm UTC](https://discourse.julialang.org/t/anonymous-functions-type-and-methods-last-forever/116676/9 "2024-07-05T20:24:58Z")

</div>

> [@stevengj](#):
>
> [DynamicExpressions.jl](https://juliahub.com/ui/Packages/General/DynamicExpressions)

Reading the README, how on earth is it only a bit slower than a compiled method? Or does the discrepancy widen when things get more complicated and there’s more to optimize?

> [@nsajko](#):
>
> Pretty sure a local function is actually implemented as a global function, with an automatically generated name.

The type gets the name:

```julia-auto
julia> (x->x) isa getproperty(Main, Symbol("#1#2")) # fresh session
true

```
