Using unquote outside of quote block

This behaviour is called “unquote fragments” and is documented here: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#quote/2-binding-and-unquote-fragments. The reason it works is because unquote/1 is stored as a function call in the AST like any other function call. Since def/2 is a macro it receives the AST within the :do block and returns a modified AST. It escapes the AST so that it can be returned in its AST form instead of being evaluated. Why it’s escaping the code is clear when you think about it, as the module is being defined the code inside def is of course not evaluated, it is only stored so that that it can be compiled after the module and all its functions are defined and then later be evaluated when the function is called.

Since we need to escape the code we can implement unquote fragments because we can simply skip escaping the code inside unquote/1 so that it will be evaluated when the function is defined instead of being escaped and evaluated at runtime. The Macro.escape/1 function can do this for us by passing it unquote: true in the options https://hexdocs.pm/elixir/Macro.html#escape/2.

8 Likes