You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
module Mod
macro set_x()
:(x = 2)
end
macro set_x_global()
:(global x = 2)
end
macro set_x_global2()
:(global x; x = 3)
end
macro x()
:(x)
end
macro x_global()
:(global x; x)
end
end
Here's the answer (assuming expansion in Main):
@set_x introduces (for every invocation of @set_x a different) gensym'd global in Main that acts as a psuedo-local (local in the sense that you don't know the name of it, so you can't name it)
@set_x_global sets the (escaped) global x in Main
@set_x_global2 declares the (escaped) global x in Main and then assigns the (non-gensymed) global x in Mod (not Main)
@x access the global x in Mod according to the ordinary hygiene rules (this is fine)
@x_global declares the (escaped) global x in Main and then does the same thing as @x.
This came up in the context of #53515. I discussed this today with @JeffBezanson and @vtjnash and our conclusions were basically as follows:
The @set_x behavior is fine with the exception of leaking a bunch of unnamed globals, which can never be deleted (and fill up the symbol table and hold on to memory). The original justification for these psuedo locals was that toplevel expressions could not be placed inside toplevel begin/end blocks, but this restriction no longer exists as far as we can tell, so these can be local now.
The behavior difference in @set_x_global and @set_x_global2 is unfortunate. In particular, having x in @set_x_global2 refer to two different globals is problematic. According to a strict interpretation of our macro hygiene rules, these should both be assigning globals in Mod (without the extra declaration of global Main.x).
@x and @x_global are basically fine, again with the possible exception of the global Main.x)
We discussed that we should see if we can remedy point 1 right now. One of the primary things that would change is the renaming across Expr(:toplevel) as currently Expr(:toplevel, :(x=1), :x) uses the same gensym'd global in both arguments. However, this is already changing in #53515, so we might as well take advantage of that and try to do this properly.
Point 2 was considered too breaking by @JeffBezanson to do before 2.0, with the provisio that we should tell people not to write it (if you want Main.x write global $(esc(:x)) = 2, if you want Mod.x write global x; x = 3 or global $(GlobalRef(Mod, :x)) = 4). There was disagreement about whether to change the implicit global Main.x in @set_x_global2 and @x_global.
The text was updated successfully, but these errors were encountered:
Here's a fun quiz: What do these macros do:
Here's the answer (assuming expansion in
Main
):@set_x
introduces (for every invocation of @set_x a different) gensym'd global inMain
that acts as a psuedo-local (local in the sense that you don't know the name of it, so you can't name it)@set_x_global
sets the (escaped) globalx
in Main@set_x_global2
declares the (escaped) globalx
in Main and then assigns the (non-gensymed) globalx
inMod
(not Main)@x
access the globalx
inMod
according to the ordinary hygiene rules (this is fine)@x_global
declares the (escaped) globalx
in Main and then does the same thing as@x
.This came up in the context of #53515. I discussed this today with @JeffBezanson and @vtjnash and our conclusions were basically as follows:
The
@set_x
behavior is fine with the exception of leaking a bunch of unnamed globals, which can never be deleted (and fill up the symbol table and hold on to memory). The original justification for these psuedo locals was that toplevel expressions could not be placed inside toplevelbegin/end
blocks, but this restriction no longer exists as far as we can tell, so these can be local now.The behavior difference in
@set_x_global
and@set_x_global2
is unfortunate. In particular, havingx
in@set_x_global2
refer to two different globals is problematic. According to a strict interpretation of our macro hygiene rules, these should both be assigning globals inMod
(without the extra declaration ofglobal Main.x
).@x
and@x_global
are basically fine, again with the possible exception of theglobal Main.x
)We discussed that we should see if we can remedy point 1 right now. One of the primary things that would change is the renaming across
Expr(:toplevel)
as currentlyExpr(:toplevel, :(x=1), :x)
uses the same gensym'd global in both arguments. However, this is already changing in #53515, so we might as well take advantage of that and try to do this properly.Point 2 was considered too breaking by @JeffBezanson to do before 2.0, with the provisio that we should tell people not to write it (if you want
Main.x
writeglobal $(esc(:x)) = 2
, if you wantMod.x
writeglobal x; x = 3
orglobal $(GlobalRef(Mod, :x)) = 4
). There was disagreement about whether to change the implicitglobal Main.x
in@set_x_global2
and@x_global
.The text was updated successfully, but these errors were encountered: