Macrofunology 1: module structure
This series of posts is about macros that expand into Elixir def
expressions. That is, they expand into definitions of functions that get "attached" to a containing module. Such macros are not wildly more complicated than normal Elixir macros, but there are some subtleties and some gotchas. This series of posts aims to explain them to you.
The series: this post, bodies and arglists, guard expressions, atoms and function names
The first gotcha is that you can't use defmacrop
to make a module-specific macro.
Here's the type of private macro you might be used to:
plus
is a macro that expands into an expression used within the body of a function definition (def
). As such, it can be both defined and used within the same module, Works
.
But I can't use the same pattern if the macro is one that creates a def
:
The call to defadder
will produce this error:
== Compilation error in file lib/defmacrop.ex ==
** (CompileError) lib/defmacrop.ex:28: undefined function defadder/1
What's happening there is not specific to macros. For example, the same thing happens with ordinary functions:
The details of what's happening are complicated enough that I think they'd be a big digression from the point of this series. So, for purposes of defining functions with macros, suffice it to say that the macro definition needs to be in one module and all the uses in other modules. For example, here's a definition:
... and here's a use, which has to require
or import
the first module: