# Can macros know if a variable is local or global?

**URL:** <https://discourse.julialang.org/t/can-macros-know-if-a-variable-is-local-or-global/66093>\
**Category:** General Usage\
**Created:** [August 9, 2021, 8:35pm UTC](https://discourse.julialang.org/t/can-macros-know-if-a-variable-is-local-or-global/66093 "2021-08-09T20:35:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [August 9, 2021, 8:35pm UTC](https://discourse.julialang.org/t/can-macros-know-if-a-variable-is-local-or-global/66093/1 "2021-08-09T20:35:42Z")

</div>

I’m writing a macro that walks the expression tree of a function definition, and would like to know if certain variables are local or global, e.g. if it saw

```julia
@mymacro function foo()
    x = 1
    return x + y
end

```

it needs to know that `x` is a local variable while `y` is a global one. The information seems like its all there in the expression, so this should be fair game for a macro. However, I’m not sure if scoping happens further down the compile chain after macro expansion, such that there’s no easy / automatic way to do this. Any ideas?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 9, 2021, 8:54pm UTC](https://discourse.julialang.org/t/can-macros-know-if-a-variable-is-local-or-global/66093/2 "2021-08-09T20:54:00Z")

</div>

No, because you can’t judge purely from the expression the macro captures whether a corresponding binding in the outer expression (where the macro is contained) exists. At best you can say if a global lookup may be necessary (the variable is read from before written to), but you can’t tell whether that will succeed or throw an UndefVarError.

Scoping happens after AST transforms like macros, which is why you have to apply macro hygiene with `esc` in the first place.

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [August 9, 2021, 8:56pm UTC](https://discourse.julialang.org/t/can-macros-know-if-a-variable-is-local-or-global/66093/3 "2021-08-09T20:56:11Z")

</div>

> [@Sukera](#):
>
> At best you can say if a global lookup may be necessary

Indeed, that’s all I need, I don’t need to know if it exists (which can only be known at runtime). I think its the exact thing that `@code_lowered` is doing:

```julia
julia> @code_lowered foo()
CodeInfo(
1 ─ x = 1
│ %2 = x + Main.y
└── return %2
)

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 9, 2021, 8:58pm UTC](https://discourse.julialang.org/t/can-macros-know-if-a-variable-is-local-or-global/66093/4 "2021-08-09T20:58:12Z")

</div>

I think `@code_lowered` is a little smarter here than that, might want to check `@macroexpand` and subsequent calls.
