Elixir: Quote Unquote

Pankaj Baagwan
ducktyp’d
Published in
2 min readJun 1, 2020

This post was originally published here on March 01, 2014

Most functional languages are great in treating/presenting everything as data. Elixir is no less, it has the power to present anything into data using its powerful quote, unquote.

Let's look at what quote does to executables. In essence, it differs from the execution and presents that executable in data form(abstract syntax tree). Let's dive

differ = quote do
"This one is " <> "quoted!"
end

{:<>, [context: Elixir, import: Kernel], ["This one is ", "quoted!"]}

All expressions are represented as a three-element tuple. Here as we can see, the first element <> is a function or operation that is to be performed, the second one is metadata related to, in this case, it defines that <> is an Kernal function and third element contains the argument passed.

Now to execute this quoted representation, we need to eval it, here is how

Code.eval_quoted(differ)
#=> {"This one is quoted!", []}

Now we will make this example more complex

list = [1,2,3]

differ = quote do
list |> Enum.map(fn(x) -> x*x end)
end

Code.eval_quoted(differ)

#however this will complain us as below
#** (CompileError) nofile:1: undefined function list/0
# (elixir) src/elixir_translator.erl:297: :elixir_translator.translate_arg/3

Why? because quoted representation or abstract syntax tree needs hard values, not references, as it packages away all stuff for later execution. So in this case it can not evaluate the list.

To overcome this elixir provides us awesome unquote. Let’s see it in action

list = [1,2,3]

differ = quote do
unquote(list) |> Enum.map(fn(x) -> x*x end)
end

Code.eval_quoted(differ)
#will give us expected
#=> {[1, 4, 9], []}

Happy Coding :)

--

--

Pankaj Baagwan
ducktyp’d

Architect, Tech Innovator, Certified Ethical Hacker and Cyber Security Enthusiast