# Macros: Mutate input expressions or not?

**URL:** https://discourse.julialang.org/t/macros-mutate-input-expressions-or-not/112495
**Category:** General Usage
**Tags:** macros
**Created:** [April 3, 2024, 11:45pm UTC](https://discourse.julialang.org/t/macros-mutate-input-expressions-or-not/112495 "2024-04-03T23:45:42Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [April 3, 2024, 11:45pm UTC](https://discourse.julialang.org/t/macros-mutate-input-expressions-or-not/112495/1 "2024-04-03T23:45:43Z")

</div>

Is there any advice on whether it’s ok to mutate the input expressions to a macro? Is it better practice to create new `Expr` objects? What are the pros and cons of mutating or not mutating?

Below is a simple example with a macro `@declare` that takes a block of names and converts them into function stubs (e.g. `function foo end`). The `@declare1` macro mutates the input block expression, whereas the `@declare2` macro creates a new block expression. They expand to the same output (including `LineNumberNode`s). Is there a reason why I should prefer one over the other?

```julia
macro declare1(block)
    for i in [2, 4]
        block.args[i] = :(function $(esc(block.args[i])) end)
    end
    block
end

macro declare2(block)
    stubs = map(block.args[[2, 4]]) do sym
        :(function $(esc(sym)) end)
    end
    Expr(:block, block.args[1], stubs[1], block.args[3], stubs[2])
end

```

```julia-repl
julia> @macroexpand @declare1 begin
           foo
           bar
       end
quote
    #= REPL[3]:2 =#
    function foo end
    #= REPL[3]:3 =#
    function bar end
end

julia> @macroexpand @declare2 begin
           foo
           bar
       end
quote
    #= REPL[4]:2 =#
    function foo end
    #= REPL[4]:3 =#
    function bar end
end

```

(Yes, I know `block.args[[2, 4]]` allocates. That’s not the point of the question.)
