RobStallion
RobStallion

Reputation: 1703

Why do elixir guides say to use quote and unquote inside of a macro definition

I have just started learning about macros in elixir. I am currently reading the metaprogramming-elixir book.

Right at the start of the book there is an example of how to create a macro called say. This macro will take an expression like 5 + 5 and return a string of "5 plus 5 is 10"...

defmacro say({:+, _, [lhs, rhs]}) do
  quote do
    lhs = unquote(lhs)
    rhs = unquote(rhs)
    result = lhs + rhs
    IO.puts "#{lhs} plus #{rhs} is #{result}"
    result
  end
end

I am wondering why we need to use the quote and unquote macros when we are defining our own macro?

defmacro say({:+, _, [lhs, rhs]}) do
  result = lhs * rhs
  IO.puts "#{lhs} plus #{rhs} is #{result}"
  result
end

Wouldn't the second version of the macro return the exact same answer?

Is there something that I am misunderstanding with the way macros work?

Upvotes: 1

Views: 408

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Macros are supposed to return AST. AST will be injected directly into the place where the call to macro was made from. This will happen during compilation stage.

That said, the latter will evaluate the result of the multiplication, put the message to stdout during compilation stage and inject a constant, representing the result, in place of the macro call. This macro would accept only compile-time constants, it won’t accept e.g. variables:

say(5 + 5)                       # works
with foo <- 5, do: say(foo + 5)  # raises

The former will produce an actual AST for evaluation.

Upvotes: 1

Related Questions