A co-worker made a comment on a PR that I need to typespec defmacro definition. The first thing I did is to look through all the open source libs and see how it is done. None I found have typespecs on defmacro’s. It sort of make sense - quoted expressions in, quoted expressions out - but I was wondering what is the official common sense here ?
I ‘think’ the base ast type is fullfilled by Macro.t
, so maybe something like this (remembering that a macro actually starts with MACRO-
and takes the environment first?
@spec unquote(:"MACRO-blah")(Macro.ENV.t, Macro.t, integer) :: Macro.t
defmacro blah(ast, i) do
quote do
unquote(ast)
unquote(i)
end
end
Or so?
I’m not actually sure, seems like we need a @specmacro
call to smooth that out…
Every macro takes ast and returns ast so is this really even needed? Maybe just for the args of the macro? it’s possible that OP’s comment was referring to a function defined by a macro needing a typespec?
defmacro blah(name) do
@type unquote(name)() :: :blah
def unquote(name)() do
:blah
end
end
would you use @type for a function in the macro?
Whoops. That should be spec
. I do this all the time. Updated:
defmacro blah(name) do
@spec unquote(name)() :: :blah
def unquote(name)() do
:blah
end
end
unquote is unnecessary. Elixir compiler automatically adds MACRO- prefix and env arg to spec. This will do
@spec blah(Macro.t, integer) :: Macro.t
defmacro blah(ast, i) do
quote do
unquote(ast)
unquote(i)
end
end
Two years later, it all ‘just works’ currently.