# How does a nested function display its local name only when assigned to a matching global name?

**URL:** <https://discourse.julialang.org/t/how-does-a-nested-function-display-its-local-name-only-when-assigned-to-a-matching-global-name/101685>\
**Category:** Internals & Design\
**Tags:** closure\
**Created:** [July 17, 2023, 4:13am UTC](https://discourse.julialang.org/t/how-does-a-nested-function-display-its-local-name-only-when-assigned-to-a-matching-global-name/101685 "2023-07-17T04:13:26Z")\
**Posts on this page:** 2\
**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 17, 2023, 4:13am UTC](https://discourse.julialang.org/t/how-does-a-nested-function-display-its-local-name-only-when-assigned-to-a-matching-global-name/101685/1 "2023-07-17T04:13:26Z")

</div>

v1.8.3 MWE:

```julia
julia> function gh(n)
         g() = n
         h = () -> n
         g, h
       end
gh (generic function with 1 method)

julia> g2, h2 = gh(1)
(var"#g#2"{Int64}(1), var"#1#3"{Int64}(1))

julia> g, h = g2, h2 # displays g when assigned to global name g
(g, var"#1#3"{Int64}(1))

julia> g2, h2 # even affects display via other global names
(g, var"#1#3"{Int64}(1))

julia> g = 1 # reassign g to something else
1

julia> g, h, g2, h2 # display back to before
(1, var"#1#3"{Int64}(1), var"#g#2"{Int64}(1), var"#1#3"{Int64}(1))

```

---

<div class="post-metadata">

**Author:** ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)\
**Post date:** [July 17, 2023, 7:59am UTC](https://discourse.julialang.org/t/how-does-a-nested-function-display-its-local-name-only-when-assigned-to-a-matching-global-name/101685/2 "2023-07-17T07:59:14Z")

</div>

I agree that it seems weird but only at first sight.

And I think this is understandable: I wouldn’t like to be able to display names that are not part of the globals of that module. That would be confusing and would give the impression that I can do `nondefinedname(...)` - after all, this is how the globally defined functions are displayed (and used). Or even worse - there might already exist a global name that is identical to the name of the nested function. However, if the name is in the global scope (and refers to the same object), why not have the pretty display since no _confusion_ is introduced?

Because there is an identity between the objects referred to by `g` and the other global name (`g2` in the context), while `g` is also defined, it seems acceptable to have the other behavior you mention (e.g., _affecting display via other global names_).

The behavior is related to the `MethodTable` names.

Try this:

```julia
function gh(n)
    g() = n
    @info typeof(g).name.mt.name
    h = () -> n
    @info typeof(h).name.mt.name
    g, h
end

```

So, in the context of your MWE:

You’ll see that the `MethodTable` name for nested generic function `g` is set to `:g`.

Not the same for the anonymous functions (where you’ll have something like `Symbol("#...")`.

Now, the `show` method for `Function` is actually checking if that name is also defined as a global variable - which is the case in your generic function but not in the case of the anonymous function: the result is that for the generic function `show_sym` is then used to handle the display (and `g` is a valid identifier, so it is displayed as it is).

There is a little more going on - which explains why `g2` reverts to the old display when you reassign `g` (like checking the identity between the function to be displayed and the corresponding object from the module - but you can go into full details by exploring the method - see below).

Inspect [this](https://github.com/JuliaLang/julia/blob/19646218e54541e286b898beca5bc1156065f4bb/base/show.jl#L522) for more details.

P. S. The same behavior applies to Julia 1.9.2.
