为什么长生不老药指南说要在宏定义中使用引号和取消引号

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

我刚刚开始学习 elixir 中的宏。我目前正在阅读 metaprogramming-elixir 一书。

本书的开头有一个示例,说明如何创建名为 say 的宏。该宏将采用 5 + 5 和 return 之类的表达式 "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

我想知道为什么我们在定义自己的宏时需要使用 quoteunquote 宏?

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

宏的第二个版本 return 不是完全相同的答案吗?

我对宏的工作方式有什么误解吗?

宏应该 return AST。 AST 将被直接注入到调用宏的地方。这将发生在编译阶段

也就是说,后者会计算乘法的结果,在编译阶段将消息传递给stdout并注入一个常量,代表结果,在宏调用的地方。这个宏只接受编译时常量,它不会接受例如变量:

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

前者将为求值生成实际的AST。