# Recursive macro call

**URL:** https://discourse.julialang.org/t/recursive-macro-call/46369
**Category:** New to Julia
**Tags:** macros, recursion
**Created:** [September 10, 2020, 10:36am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369 "2020-09-10T10:36:53Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)
#### Post date: [September 10, 2020, 10:36am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369/1 "2020-09-10T10:36:53Z")

</div>

As an exercise, I’m trying to make a macro that turns `@x a b c` into `a = b = c = 1234`.

I tried to write it recursively, but I don’t know how to fix my error ☹

Definition:

```julia
julia> macro x(s::Symbol, ss...)
           quote
               $(esc(s)) = @x $(esc(ss))...
           end
       end

julia> macro x()
           1234
       end

```

Call:

```julia
julia> @x a b c
ERROR: LoadError: MethodError: no method matching @x(::LineNumberNode, ::Module, ::Expr)
Closest candidates are:
  @x(::LineNumberNode, ::Module) at REPL[9]:2
  @x(::LineNumberNode, ::Module, ::Symbol, ::Any...) at REPL[21]:2
in expression starting at REPL[21]:3

```

Any tips?

(The self-assigned exercise is to write it recursively)

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [September 10, 2020, 10:44am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369/2 "2020-09-10T10:44:10Z")

</div>

Generally one doesn’t write macros as _themselves_ being recursive. Instead, you write a function that works on the input expression, and that function is recursive. The macro calls the recursive function and returns the final expression.

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [September 10, 2020, 10:45am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369/3 "2020-09-10T10:45:49Z")

</div>

This works…

```julia
julia> macro xx(s, ss...)
           quote
               $(esc(s)) = @xx $(esc.(ss)...)
           end
       end;

julia> macro xx()
           1234
       end
@xx (macro with 2 methods)

julia> (@macroexpand @xx a b c) |> Base.remove_linenums!
quote
    a = begin
            b = begin
                    c = 1234
                end
        end
end

```

although I would do:

```julia
julia> macro y(s::Symbol, ss...)
         _y(s, ss...)
       end;

julia> _y(s, ss...) = :($(esc(s)) = $(_y(ss...)));

julia> _y() = 1234
_y (generic function with 2 methods)

julia> @macroexpand @y a b c
:(a = (b = (c = 1234)))

```

---

<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: [September 10, 2020, 10:48am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369/4 "2020-09-10T10:48:13Z")

</div>

After the 5th or 6th guess at where to put the `esc` 🙂 :

```julia
macro x(s::Symbol, ss...)
    quote
        $(esc(s)) = $(esc(:(@x $(ss...))))
    end
end

macro x()
    1234
end

```

---

<div class="post-metadata">

### Author: ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)
#### Post date: [September 10, 2020, 10:58am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369/5 "2020-09-10T10:58:52Z")

</div>

Thanks everyone! And @mcabbott thank you for the tip to call out to functions 🙂

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [September 10, 2020, 11:07am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369/6 "2020-09-10T11:07:42Z")

</div>

You probably don’t want to escape `@x` as well, since that will look for the macro definition in the macro caller’s scope, so if you are defining the macro in a different module and don’t explicitly import it, this will fail. @mcabbott’s solution doesn’t have this problem, because only the arguments are escaped.

---

<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: [September 10, 2020, 11:13am UTC](https://discourse.julialang.org/t/recursive-macro-call/46369/7 "2020-09-10T11:13:29Z")

</div>

Good point. Actually I tried @mcabbott’s solution but didn’t think to remove the `::Symbol`, which I guess is crucial (it errors otherwise) for reasons that are currently mysterious to me…
