julia
julia copied to clipboard
Feature Request: Way to tell if a macro is in local or global scope
When writing macros, you often have to come up with very clever ways of writing code that works either in the global or local scope. It'd be nice if I could just query a variable analogous to __module__ (maybe __isglobal__?) to see if a macro is called from a local or global scope. The parser certainly know what code is in a local versus global scope so this shouldn't be too difficult.
I can understand why you'd like to do this; in specialized circumstances a macro wants to emit different code in different cases, (for example in https://github.com/JuliaLang/julia/pull/35833)
The sticking point is that analysis of variable scope hasn't yet been done by the time macros are expanded — that's done later during lowering. Furthermore, if we did some analysis before macro expansion then that analysis might need to be redone based on whatever code the macro generates. And that might need to happen multiple times for nested macros. So in short, it's not trivial to implement this and seems to violate the "pipeline-like" layering of compiler analyses.
Two very speculative alternatives to having a predicate available:
- Provide macros with an
Exprthey can emit which declaratively selects code based on some predicates which are only known later during compilation - Have a way for another kind of "macro" which plugs in slightly later during the compilation; perhaps after some syntax desugaring and variable analysis, but before linearization. Big problem: what type of AST will this macro speak? It can't be surface syntax, and supplying the internal representation will make that into a public API which I very much doubt we'd like to do at this point.
Being able to emit something like
if @toplevel
...
else
In analogy to if @generated which gets handled later on downstream would be pretty interesting, and I think would solve the problem.
That seems like a promising and minimalistic minimal way to implement this, I like it!
Also generally a duplicate feature request as https://github.com/JuliaLang/julia/issues/6733
There are local scopes which are not inside functions, like let.