...

/

Using the Representation as Code

Using the Representation as Code

Understand how to inject our code into a program's internal representation.

Introduction

When we extract the internal representation of some code (either via a macro parameter or using quote), we stop Elixir from adding it automatically to the tuples of code it’s building during compilation. We’ve effectively created a free-standing island of code. How do we inject that code back into our program’s internal representation?

There are two ways.

The first is the macro. Just like with a function, the value a macro returns is the last expression evaluated in that macro. That expression is expected to be a fragment of code in Elixir’s internal representation. But Elixir doesn’t return this representation to the code that invoked the macro. Instead, it injects the code back into the internal representation of our program and returns the result of executing that code to the caller. But that execution takes place only if needed.

We can demonstrate this in two steps.

  1. First, here’s a macro that simply returns its parameter (after printing it out).
  2. When we invoke the macro, the code is passed as an internal representation. The macro returns that code and that representation is injected back into the compile tree.
defmodule My do
  defmacro macro(code) do
    IO.inspect code
    code
  end
end
defmodule Test do
  require My
  My.macro(IO.puts("hello"))
end
...