Typespecs on defmacro defintions?

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 :slight_smile: ?

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…

1 Like

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?

1 Like

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
2 Likes

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
1 Like

Two years later, it all ‘just works’ currently. :slight_smile: