# Using splat inside macro

**URL:** <https://discourse.julialang.org/t/using-splat-inside-macro/77761>\
**Category:** General Usage\
**Tags:** macros\
**Created:** [March 11, 2022, 4:16pm UTC](https://discourse.julialang.org/t/using-splat-inside-macro/77761 "2022-03-11T16:16:56Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![pjgorski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pjgorski/32/4802_2.png) [@pjgorski](https://discourse.julialang.org/u/pjgorski)\
**Post date:** [March 11, 2022, 4:16pm UTC](https://discourse.julialang.org/t/using-splat-inside-macro/77761/1 "2022-03-11T16:16:56Z")

</div>

I wanted to create a macro to print simulation status every now and then.

```julia
function display_res(ntuple::NamedTuple)
    cur = Dates.format(now(), "HH:MM:SS dd.mm.yyyy");
    str = savename(ntuple, connector="; ", sort = false)

    println("Just finished: $str" * ". Time: $cur");
    return nothing;
end

macro display_res(vars...)
    quote 
        display_res($(:(@ntuple($(vars...)))))
    end 
end

```

`savename` and `@ntuple` are from `DrWatson` package. The former creates a string, the latter creates `NamedTuple` (e.g., `n=5;g=5;@ntuple(n, g)` would give `(n=5, g=5)`.

Above code works in Repl, but when I put it in the module, it doesn’t, resulting in: `UndefVarError: n not defined`.

Following is the output from `@macroexpand`:

```julia
quote
    #= /path_to_file/file.jl:63 =#
    MyModuleName.display_res((n = MyModuleName.n, g = MyModuleName.g))
end

```

So, of course the problem is with `MyModuleName.n` and `MyModuleName.g`. Does anybody know how to cope with that? Cheers!

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 12, 2022, 4:40am UTC](https://discourse.julialang.org/t/using-splat-inside-macro/77761/2 "2022-03-12T04:40:26Z")

</div>

This isn’t really about splatting, it’s just the usual rules about macro hygiene: [Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/#Hygiene), namely that you need to escape (with `esc()`) values that you want to interpolate like this.

Here’s a simpler example that works. I’ve removed `savename` because I don’t have `DrWatson`, and I’ve also removed `@ntuple` because you can do the same thing via `(; n, g)` as of Julia 1.7:

```julia
function display_res(ntuple)
	println("got: ", ntuple)
end

macro display_res(vars...)
	quote
		ntuple = (; $(esc.(vars)...))
		display_res(ntuple)
	end
end

```

Usage:

```julia
julia> function foo()
         n = 1
         g = 2
         @display_res(n, g)
       end
foo (generic function with 1 method)

julia> foo()
got: (n = 1, g = 2)

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [March 12, 2022, 9:55am UTC](https://discourse.julialang.org/t/using-splat-inside-macro/77761/3 "2022-03-12T09:55:23Z")

</div>

As @rdeits underlined, recent versions of Julia make it more easy to build named tuples and keyword arguments. So if you do not need to support older Julia versions, you might want to consider getting rid of macros entirely. Something like that (again removing `savename` to make the example runnable without `DrWatson`):

```julia
function display_res(; kwargs...)
    ntuple = NamedTuple(kwargs)
    cur = Dates.format(now(), "HH:MM:SS dd.mm.yyyy");
    str = string(ntuple)

    println("Just finished: $str. Time: $cur");
    return nothing;
end

```

```julia
julia> let
           a = 2
           b = 3
           display_res_new(; a, b)
       end
Just finished: (a = 2, b = 3). Time: 10:47:37 12.03.2022

```

The call syntax is perhaps a bit less user-friendly than what you wanted, but this way you don’t have to worry about topics like macro hygiene (which are arguably kind of hard to grasp).

---

<div class="post-metadata">

**Author:** ![pjgorski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pjgorski/32/4802_2.png) [@pjgorski](https://discourse.julialang.org/u/pjgorski)\
**Post date:** [March 14, 2022, 9:33am UTC](https://discourse.julialang.org/t/using-splat-inside-macro/77761/4 "2022-03-14T09:33:44Z")

</div>

Thank you @rdeits @ffevotte

I will just add that your codes work in Julia 1.6.4.
