I'm learning Elixir now and I'm really confused with quote
and unquote
.
Here is how we create a function with a dynamic name using a macro
:
defmacro create_fun(n) do
quote do: def unquote(:"times_#{n}")(a), do: a * 4
end
It creates function times_6
, for example, if I pass 6
as a macro parameter.
Now what I don't understand: Here we unquote the atom :"times_#{n}"
. Elixir docs say that when you quote an atom it returns an atom. So when I unquote an atom, I should get this atom back too. And this is true:
iex(15)> Macro.to_string quote do: unquote(:"times_6")
":times_6"
But using ()
right after the quote gives this:
iex(14)> Macro.to_string quote do: unquote(:"times_6")()
"times_6()"
An atom with parentheses suddenly becomes not an atom. And if I substitute unquote(:"times_6")
with :"times_6"
it doesn't work:
iex(4)> Macro.to_string quote do: :"times_6"()
** (SyntaxError) iex:4: syntax error before: '('
Please, what is going on, I don't get it
do: a * unquote(n)
instead ofa * 4
? – Sheharyar:"times_6"()
. That itself is an invalid statement – Sheharyarunquote(:"times_6")()
correct?unquote(:"times_6")
should return you:"times_6"
– airled