Pass interpolating string to macro

I’m trying to define basic macro but fail:

macro mydebug(s)
  :(println($s))
end

function main()
  i = 42
  @mydebug("$(i)")
end

This one yield:

UndefVarError: i not defined

Is it not possible to pass interpolating strings to macros?

You need to escape it:

macro mydebug(s)
         :(println($(esc(s))))
end 

I’m not sure why though.

1 Like

This isn’t related to string interpolation. You get the same error with

macro mydebug(s)
  :(println($s))
end
function main()
  i = 42
  @mydebug i 
end
main()

because

> @macroexpand @mydebug i
:((Main.println)(Main.i))

By default, the expression returned from a macro is modified to make sure global variables are interpreted in the macro’s scope (in the case, Main). esc overrides this to leave the expression as is. There’s more details in the docs under Hygiene.

6 Likes