I ganna write about behavior of quote and unquote from viewpoint of context.
I thought quote and unquote both have to be used toghether when I started to learn metaprogramming. But chapter of code generation in Metaprogramming Elixir book showed me some weird examples.
One of them is like this.
mimes.exs defines several functions based on type and extension in mimes.txt.
this code works like this. When we set a type, a function returns extensions. On the other hand a function returns type when we set a extension.
Here this unquote is called “unquote fragments”.
This made me curious to search role of exceptional macro more. So I understood why this code works well without quote after I run a little test codes.
Thinking relation between unquote and context reveals what unquote does precisely and then it leads to think relation between quote and context.
I believe once we got these relationship, it helps we use macro more.
As you know the role of quote normally translates expression to AST tuple except 5 literals.
Thanks to quote, we can manipulate AST freely. And unquote is needed when we inject variables to AST.
Yes. The variable: second is evaluated within AST. Role of unquote is resolving whether a name of variable binds a value or not.
But from where…?
Here I wanna bring up context which is called scope in different languages.
Before we consider unquote, let’s just check variables context with
First I set the value at the outside of
c1 takes an augment named
a then check what’s bound, c2 try to check
b, and c3 bind an augment to
b then check it.
*c2 fails because of compile error.
Now we can see context is marked off by a
defmacro you know.
variables never refer to outside variables in the body of these macros.
Let’s check other example.
unquote(a) in c1 and change c2 function.
This example leads to what unquote does right?
Unquote obviously refer to a high context
Both function show a outside value even if function has same name of variable.
And one more thing I gave a function a variable which binds atom by using unquote.
This example show us where area belong to function context.
Think about def NAME, do: BODY. NAME and BODY both are in a function context.
Now we can explain why first mimes.exs works well.
type and extensions currently bind a value at the outside of
That’s why unquote is used in order to define function like following
Unquote fragments and unquote both just acts upon context and resolving
This code is likely to work well, isn’t it? This is because mimes.exs generates new codes without defmacro and quote.
Oh you are right. It can’t work because defmacro is designed to take AST as arguments and return new AST.
But… This code fails because of some reasons
Type is not defined at line 8.
defmacro a key word def is not evaluated so if we use unquote here, unquote refer to the outside of
OK. Let’s try remove unquote. And compile result is… Another error. We can’t invoke it inside function/macro.
Hmmmmmm, how do we do that? Is there any marker except
Yes. Just remember such examples.
unquote refer to second over
quote and as you know quote can be put in anywhere!
quote on and get back
Good! really good. Quote actually mark off context as well
How was that? Considering context of unquote and quote together, it can be easy to read what is going on metaprogramming code I guess
Actually quote have some extra informations about context, but I recommend that you read Metaprogramming Elixir book for it.
Thank you for reading That’s all :)
Let’s enjoy Elixir!!