# Macros not evaluating as per expectation

**URL:** https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252
**Category:** New to Julia
**Tags:** macros
**Created:** [March 28, 2024, 8:36pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252 "2024-03-28T20:36:39Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![kishaloy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishaloy/32/30127_2.png) [@kishaloy](https://discourse.julialang.org/u/kishaloy)
#### Post date: [March 28, 2024, 8:36pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/1 "2024-03-28T20:36:39Z")

</div>

I am facing a problem in understanding why my macro works the way it does.

I have the following macro

```julia
macro create_m(m)
    y = :(a + b * c + 1)
    y.args[3].args[2] = :(2 * $m)
    dxr = m
    global dxy = 2 * m
    println("m, 2*m, dxy in macro ", dxr, " ", 2 * m, " ", dxy)
    push!(y.args, dxy + 25)
    y
end

```

The idea is to evaluate `dxy = 2 * m` and try to incorporate it into the AST and also see if it can be escaped by declaring global.

When I print the result with the following:

```julia
@macroexpand @create_m(5)
# Meta.dump(@create_m(12))
zz = @create_m(8)
println("zz = ", zz)

# println(dxr)
println("dxy = ", dxy)

```

I get

```julia
m, 2*m, dxy in macro 5 7 7
m, 2*m, dxy in macro 8 10 10
zz = 59
dxy = 10

```

Which means `2 * m` is evaluated as `2 + m`

Even `@macroexpand @create_m(5)` evaluates to `:(Main.Heller.a + (2 * 5) * Main.Heller.c + 1 + 32)` so `25 + dxy` is evaluated as `25 + (2+5)` rather than `25 + (2*5)`

Though rest of the allocations are fine.

Any reason why this is so? Any help in understanding would be appreciated

---

<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: [March 28, 2024, 10:36pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/2 "2024-03-28T22:36:24Z")

</div>

Hey @kishaloy,

I tried to reproduce the behavior you reported but to no avail.

 ![Screenshot 2024-03-29 at 00.32.32](https://global.discourse-cdn.com/julialang/original/3X/a/b/abba49b1eac2022c71c37c7bae8d1aba682bce93.png)

Can you retry using a clean environment?

---

<div class="post-metadata">

### Author: ![kishaloy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishaloy/32/30127_2.png) [@kishaloy](https://discourse.julialang.org/u/kishaloy)
#### Post date: [March 28, 2024, 10:45pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/3 "2024-03-28T22:45:45Z")

</div>

Now it is even more weird.

Basically the macro is a part of a file with other functions, but there is no dxy anywhere.

When I run the whole file Ctrl+Shift+Enter in vscode, the error comes as shown.

But when I run only the macros + the relevant lines only (Ctrl + Enter), with a clean state, it all comes good like yours. But if I have run once with all, then the state is spoiled for good.

I am using Version 1.9.3, if that helps.

Pretty strange…

---

<div class="post-metadata">

### Author: ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)
#### Post date: [March 28, 2024, 11:07pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/4 "2024-03-28T23:07:38Z")

</div>

I haven’t understood the issue you’re hitting, but what is your higher level goal?

If I understand your code, you implicitly assume that `m` is always an integer literal. If so, why not use a function?

Secondly, what is the goal of the `global` usage? To inject a named variable into the macro caller’s scope, getting around hygiene?

---

<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: [March 28, 2024, 11:09pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/5 "2024-03-28T23:09:02Z")

</div>

There are lots of pitfalls that you can explore - and I am pretty confident that once we get to the end of it, this will look pretty much expected (as opposed to weird).

The rest of the file can be pretty relevant - especially if you alter the global state from inside functions/macros (which is not necessarily a recommended thing to do).

The macro itself works pretty much as expected - so the issue might be related to when/where you are calling it (REPL vs. script will work differently in certain scenarios).

So, at this point helping us to understand what you actually try to achieve will help solve _this_ faster.

---

<div class="post-metadata">

### Author: ![kishaloy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishaloy/32/30127_2.png) [@kishaloy](https://discourse.julialang.org/u/kishaloy)
#### Post date: [March 28, 2024, 11:23pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/6 "2024-03-28T23:23:18Z")

</div>

The idea was to get the hang of macros and figuring out how to generate AST in compile time, how it works etc. using a mix of Expr and regular evals. So the example is fictitious.

---

<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: [March 28, 2024, 11:33pm UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/7 "2024-03-28T23:33:26Z")

</div>

> [@kishaloy](#):
>
> The idea was to get the hang of macros and figuring out how to generate AST in compile time, how it works etc. using a mix of Expr and regular evals. So the example is fictitious.

If this is the case, then a good approach would be to perform this exploration without dropping the macro hygiene (you can do that in justified scenarios once you are proficient enough with _clean_ macros).

[https://docs.julialang.org/en/v1/manual/metaprogramming/#Hygiene](https://docs.julialang.org/en/v1/manual/metaprogramming/#Hygiene)

---

<div class="post-metadata">

### Author: ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)
#### Post date: [March 29, 2024, 12:11am UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/8 "2024-03-29T00:11:04Z")

</div>

So my personal recommendation for learning how to write macros is one that will actually make your example go away entirely:

1. Don’t start with a macro. Start with a function that takes in expressions and produces expressions back. Convince yourself you’re doing this correctly.
2. Make the macro just a call to the expression-to-expression function.

So, for example, you’d do something like this simplification with your example:

```julia
function create_m_func(m)
    y = :(a + b * c + 1)
    y.args[3].args[2] = :(2 * $m)
    dxr = m
    global dxy = 2 * m
    println("m, 2*m, dxy in function ", dxr, " ", 2 * m, " ", dxy)
    push!(y.args, dxy + 25)
    y
end

macro create_m(m)
    create_m_func(m)
end

a, b, c = 1, 1, 1
zz = @create_m(8)

println("zz = ", zz)

println("dxy = ", dxy)

```

---

<div class="post-metadata">

### Author: ![kishaloy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishaloy/32/30127_2.png) [@kishaloy](https://discourse.julialang.org/u/kishaloy)
#### Post date: [March 29, 2024, 8:48am UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/9 "2024-03-29T08:48:27Z")

</div>

Didn’t really help. Also I simplified the macro substantially.

```julia
function create_m_fn(m)
    println("1st => m, 2*m ", m, " ", 2 * m) # 1st => m, 2*m 5 7
    2 * m
end

macro create_m(m)
    zz = create_m_fn(m)
    :(1 + $zz)
end

@macroexpand @create_m 5 # :(1 + 7)

zz = @create_m 8
println("zz = ", zz) # zz = 11

```

Somewhere my understanding in what and how variables are evaluated during macro expansion is off. `2*m` is evaluated as `2+m`. The textual substitution works as expected.

---

<div class="post-metadata">

### Author: ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)
#### Post date: [March 29, 2024, 9:16am UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/10 "2024-03-29T09:16:03Z")

</div>

Works for me as expected. The only reason I could think of is that you somehow run it in an environment where `*` is bound to `+`?

---

<div class="post-metadata">

### Author: ![kishaloy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishaloy/32/30127_2.png) [@kishaloy](https://discourse.julialang.org/u/kishaloy)
#### Post date: [March 29, 2024, 9:20am UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/11 "2024-03-29T09:20:12Z")

</div>

The packages that I am using are:

```julia
  [6e4b80f9] BenchmarkTools v1.3.2
  [336ed68f] CSV v0.10.11
  [8be319e6] Chain v0.5.0
  [a93c6f00] DataFrames v1.6.1
  [1313f7d8] DataFramesMeta v0.14.1
  [d8e11817] MLStyle v0.4.17
  [91a5bcdd] Plots v1.39.0
  [c3e4b0f8] Pluto v0.19.32
  [7f904dfe] PlutoUI v0.7.53
  [8e1ec7a9] SumTypes v0.5.0
  [ade2ca70] Dates
  [37e2e46d] LinearAlgebra
  [8dfed614] Test

```

Rest is all vanilla Julia that I have written.

---

<div class="post-metadata">

### Author: ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)
#### Post date: [March 29, 2024, 9:40am UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/12 "2024-03-29T09:40:17Z")

</div>

Ok, have installed exactly these packages into a fresh environment (on Julia 1.10.0). Still everything works as expected for me. Maybe you could try the following:

1. Start a new Julia REPL and run

```julia-repl
julia> 2 * 5

```

2. Change your code to explicitly use `*` from Base, i.e.,

```julia
function create_m_fn(m)
    println("1st => m, 2*m ", m, " ", Base.:*(2, m)) # 1st => m, 2*m 5 7
    Base.:*(2, m)
end
# Everything else as before ...

```

and then try again.

---

<div class="post-metadata">

### Author: ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)
#### Post date: [March 29, 2024, 11:21am UTC](https://discourse.julialang.org/t/macros-not-evaluating-as-per-expectation/112252/13 "2024-03-29T11:21:01Z")

</div>

Just to be clear – if you copy and paste that code into a fresh REPL session, this code works as expected or does not?

If yes, but the code does not work in the broader context you’re not fully sharing, I suspect we are not going to make progress resolving it since the core issues are in the code we’re not discussing.
