# Performant Recursive Anonymous Functions

**URL:** https://discourse.julialang.org/t/performant-recursive-anonymous-functions/90984
**Category:** General Usage
**Tags:** performance, recursion, lambda, anonymous-function
**Created:** [November 29, 2022, 10:38am UTC](https://discourse.julialang.org/t/performant-recursive-anonymous-functions/90984 "2022-11-29T10:38:10Z")
**Posts on this page:** 4
**Page:** 2

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [November 29, 2022, 11:34pm UTC](https://discourse.julialang.org/t/performant-recursive-anonymous-functions/90984/21 "2022-11-29T23:34:37Z")

</div>

> [@Sukera](#):
>
> If I understand what you want correctly, this is not a thing - all function definitions happen at the containing global scope. There are no “local only” functions. They ALWAYS get a name at the global level, because that’s relevant for world age.

I don’t really care what name it receives at the global scope; within a local scope, though, I’d rather have a name better than `var"#self#"` to call it by. Unless it becomes officially ordained.

This is a nuisance though (trying to nest local function definitions):

```julia
julia> foo = let
           function f end
           (f::typeof(f))() = begin
               let
                   function g end
         # (g::typeof(g))() = begin
         # 1
         # end
               end
           end
           f
       end
(::var"#f#41") (generic function with 1 method)

julia> foo()
(::var"#g#42") (generic function with 0 methods)

```

uncommenting the nested method definition:

```julia
julia> foo = let
           function f end
           (f::typeof(f))() = begin
               let
                   function g end
                   (g::typeof(g))() = begin
                       1
                   end
               end
           end
           f
       end
ERROR: syntax: Global method definition around REPL[58]:6 needs to be placed at the top level, or use "eval".

```

This language _really_ doesn’t want me to get my type stability 😅

It’s looking like @aplavin and @Mason may have the correct approach yet

---

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [November 29, 2022, 11:52pm UTC](https://discourse.julialang.org/t/performant-recursive-anonymous-functions/90984/22 "2022-11-29T23:52:50Z")

</div>

~~I guess the question I should be asking though is:~~

~~If I define a function locally using _named function syntax_, why isn’t there a syntax transform imposed such that any instances of it calling its own name are replaced with `var"#self#"`, and any attempts within that scope to re-define its name will throw an error?~~

This is a lot of hoop-jumping just so that we can maintain the ability to reassign the locally-defined name of locally-defined named functions, which is an ability we’re happy to live without at the global scope.

---

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [November 30, 2022, 6:02pm UTC](https://discourse.julialang.org/t/performant-recursive-anonymous-functions/90984/23 "2022-11-30T18:02:39Z")

</div>

So for now, I’m using @sgaure’s idea to use `var"#self#"`. It’s straightforward in my macro to search and replace symbols of the function’s name, since I know what it is, and this approach maximizes performance. However, this is very much a temporary fix; to me it feels like this is a bug in the language.

> [@Mason](#):
>
> The idea here is to basically just play some sleight of hand to avoid julia thinking we’re doing recursion, and to stop it from doing something dumb.

The funny thing is, Julia’s “normal” behavior toward recursion is exactly what we want here. What we _don’t_ want is for the function’s reference to itself to be boxed. And the only reason to box it is because the language is insisting that its identifier could be reassigned during the function’s life, despite using _named function syntax._

We have four different syntaxes to declare functions: two _named function syntaxes_ and two _anonymous function syntaxes_. The point of the named function syntaxes is function identifier type declaration to stabilize the type. This is convenient (don’t need to type `const`), great for performance, and quite useful for declaring recursive functions.

For whatever reason though, in local scopes the named function syntax seems to behave for all intents and purposes like anonymous function syntax in allowing its identifier to be reassigned. That means that within a local scope, we have loss of performance and four redundant syntaxes for doing basically the same thing. It’s also a break from the behavior that you come to expect from interacting with these syntaxes at global scope. And because recursive functions require their identifier to be declared simultaneous to their function body, we can’t use the `let` block trick that works for other captured variables, and we can’t use type-annotation. And because `const` is disallowed in local scopes, it’s inescapable.

This does not seem like the correct behavior. It seems like the right thing to do is to disallow locally declared named functions from having their identifier reassigned, so that references to them don’t have to be boxed. Someone should open an issue for this, no?

---

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [November 30, 2022, 11:01pm UTC](https://discourse.julialang.org/t/performant-recursive-anonymous-functions/90984/24 "2022-11-30T23:01:28Z")

</div>

[Issue submitted.](https://github.com/JuliaLang/julia/issues/47760)

[Previous page](https://discourse.julialang.org/t/performant-recursive-anonymous-functions/90984.md?page=1)
