Elixir macros#
Macros allow us to extend the functionality of the Elixir programming language by injecting code into the application. They are special functions that return a quoted expression, which we can insert into our application code. When the compiler finds a macro, it recursively expands the macro until no macro calls remain in the code.
We’ll discuss two macros as an introduction to metaprogramming in Elixir.
quote#
quote
is instrumental to code generation in Elixir. We can use the quote
macro in the iex shell to output the quoted expression for any Elixir expression.
For instance, when applied to the code example from the previous section:
quote do: sum(2, 4, 6)
⇒ {:sum, [], [2, 4, 6]}
unquote#
While the quote
macro allows us to access the AST, the unquote
macro allows us to modify the AST by injecting new code or values into it. unquote
evaluates the expression it’s given and injects the resulting AST into a quoted expression.
For instance, in this code example, we unquote num
and inject it into the quoted expression (or AST) of the function call sum(10, num)
.
num = 20
quote do: sum(10, num)
quote do: sum(10, unquote(num))
⇒ {:sum, [], [10, {:num, [], Elixir}]}
⇒ {:sum, [], [10, 20]}
A note on using macros#
Macros are considered the building blocks of Elixir. We can use macros to write effective and readable code. They’re great for domain-specific languages (DSLs) like Phoenix and Ecto. They help us carry out complex tasks and build custom language features.
You’ll often hear that one of the first things you should know about metaprogramming is: Don’t use macros. As with most advanced programming techniques, the power that Elixir macros give us can lead to errors if handled incorrectly. Metaprogramming mistakes can result in program errors that are difficult to debug. While the disclaimers are not unfounded, they shouldn’t deter you from learning the powerful technique of metaprogramming. With the right dose of caution, you can leverage Elixir’s macro system to write less code and develop highly performant applications.