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:
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 for more details.
P. S. The same behavior applies to Julia 1.9.2.