# How to "broadcast" macro interpolation

**URL:** <https://discourse.julialang.org/t/how-to-broadcast-macro-interpolation/61641>\
**Category:** New to Julia\
**Tags:** macros, metaprogramming\
**Created:** [May 22, 2021, 3:06pm UTC](https://discourse.julialang.org/t/how-to-broadcast-macro-interpolation/61641 "2021-05-22T15:06:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![melonedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/melonedo/32/15503_2.png) [@melonedo](https://discourse.julialang.org/u/melonedo)\
**Post date:** [May 22, 2021, 3:06pm UTC](https://discourse.julialang.org/t/how-to-broadcast-macro-interpolation/61641/1 "2021-05-22T15:06:33Z")

</div>

In Julia, building a simple expression is as easy as inserting a few `$`s. For example if I write a macro that zeros a variable by setting it to literal 0:

```julia
macro zeroit(x::Symbol)
    :($(esc(x)) = 0)
end

```

But if I want a `zerothem` macro that zeros multiple variables, I have to build an `Expr` manually:

```julia
macro zerothem(xs...)
    e = Expr(:block)
    e.args = map(collect(xs)) do x
        :($(esc(x)) = 0)
    end
    e
end

```

Is there a better way to do this?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [May 22, 2021, 4:54pm UTC](https://discourse.julialang.org/t/how-to-broadcast-macro-interpolation/61641/2 "2021-05-22T16:54:00Z")

</div>

This is good. It’s basically what `@unpack` does, see [here](https://github.com/mauro3/UnPack.jl/blob/master/src/UnPack.jl).

Although my advice for writing macros is to always do it in a helper function. i.e.

```julia
macro mymacro(args...)
    esc(mymacro_helper(args...))
end

function mymacro_helper(args...)
    ...
end

```

Here’s how I would do it

```julia
julia> macro makezero(args...)
           esc(makezero_helper(args...))
       end;

julia> function makezero_helper(args...)
           assignments = map(args) do arg
               :($arg = 0)
           end
           Expr(:block, assignments...)
       end;

```

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [May 22, 2021, 5:02pm UTC](https://discourse.julialang.org/t/how-to-broadcast-macro-interpolation/61641/3 "2021-05-22T17:02:37Z")

</div>

With just interpolations (although perhaps too many parentheses):

```julia
macro zerothem(xs...)
    quote
        $((:($(esc(x)) = 0;) for x in xs)...)
        nothing # so that it does not print zero
    end
end

```

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [May 22, 2021, 5:22pm UTC](https://discourse.julialang.org/t/how-to-broadcast-macro-interpolation/61641/4 "2021-05-22T17:22:57Z")

</div>

Here’s another option:

```julia
julia> macro zerothem(xs...)
           :(($(xs...),) = $Iterators.repeated(0); ($(xs...),)) |> esc
       end

```

so that

```julia
julia> @macroexpand @zerothem x y z
quote
    (x, y, z) = (Base.Iterators).repeated(0)
    #= REPL[12]:2 =#
    (x, y, z)
end

```

and

```julia
julia> @btime @zerothem x y z
  0.019 ns (0 allocations: 0 bytes)
(0, 0, 0)

```

At this point though, one wonders if you even want a macro for this, when you could just write

```julia
julia> using Base.Iterators: repeated

julia> a, b, c = repeated(0);

julia> a, b, c
(0, 0, 0)

```

---

<div class="post-metadata">

**Author:** ![melonedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/melonedo/32/15503_2.png) [@melonedo](https://discourse.julialang.org/u/melonedo)\
**Post date:** [May 23, 2021, 2:32am UTC](https://discourse.julialang.org/t/how-to-broadcast-macro-interpolation/61641/5 "2021-05-23T02:32:04Z")

</div>

Thank you for your replies! I am starting to understand it.  
So `$(exprs...)` is a broadcasted macro interpolation, it will insert all elements from `exprs` into the parent expression. The key is that the “parent expression” needs to be made explicit (blocks, tuples, vectors, etc) so that the parser expects multiple sub-expressions:

- In case of multiple independent expressions, we need `quote $(exprs...) end` or `:($(exprs...);)`
- In case of tuples, we need `:($(exprs...),)`

Vectors could be a more interesting example:

```julia
elems = (1,2,3)
:[$(elems...);] # => :([1; 2; 3])
:[$(elems...),] # => :([1, 2, 3]), "," is optional

```

So the trailing `;` determines what kind of expressions `$(elems...)` will form.
