augnustin
Hi,
I have been coding with Elixir for 9+ months and I encountered several time the concept of quotes and each time, I think “ok, today I shall be mature enough to understand quotes”, re-read the content I can find on the internet (starting with the getting started).
But until now, I still haven’t understood the blood out of it. ![]()
My main question is why do we need them?
If quoting is only about changing the representation of a piece of code, then why should it be so different quoted than unquoted. I’m comfortable with the concept of AST, but as for me it only changes the representation of something, not its content.
Eg. 1 + (2 + 3) <==> add(1, add(2, 3))
Besides, it feels illogical to me that there are two worlds: the quoted one and the unquoted. If quoting is about meta-programming, then quoting quoted expressions should make sense to program meta-meta-programming, shouldn’t it?
Someone in this forum suggested that macros (that are closely related to quotes, aren’t they?) should be seen as functions that return other functions instead of expressions. This helped me a little to read some quote-using-code, but it still doesn’t explain why we need them.
I am comfortable with currying, partial application, function as references, which are the way meta-programming goes in languages I’m more comfortable with (JS, Haskell …), so what’s different here?
Finally, are quotes so hard to understand or is it just me?
Of course, I feel like this is key concept to be comfortable with Elixir, I can be patient with that, just like I was (am?) with Haskell’s monads, but nothing out there suggests that this one has to expect something hard so it may be just me…
Thanks for the help, hope this can be useful to others!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










Showing Posts 1 to 4- Show Best Posts
- Show All Posts (oldest first)
- Show All Posts (newest first)
NobbZ
Quote and unquote are the AST equivalent of the double quote that encloses a string and
#{}which you use in a string to inject a variables value rather than just it’s name.They are essential for code generation, meta programming and macros
entone
Let’s assume we have a function that is going to generate a function for us, and we want to pass in some arguments that can get pattern matched on.
This allows us to pass in compile time arguments, that can get evaluated/pattern matched at runtime.
So
unquoteallows us to pass in compile-time args, and get the AST of the value for runtime.Not sure if that helps at all.
LostKobrakai
There are two worlds because there are two times when code is executed:
Take this example:
For the function
log_levelwhat do you expectiandlevelto represent?Basically it’s 3 times this:
def log_level(i), do: level, and it would complain about unmatchable clauses (all matchi) as well as crash at runtime for an undefined variablelevel.This is where unquoting comes in.
At compile time this will define a module A with 3 function heads looking like that:
The runtime will never know of
iandleveland therefore not fail because of undefined variables. The same thing happens in macros, where you also create AST at compile time. Macros can however also edit AST.You might be wondering why this example doesn’t use a
quotelike macros do. For a module it’s clear which code is compile time executed and which isn’t (only function bodies aren’t executed at compile time), so all the quote/unquote stuff happens as part of thedefmoduleimplementation. For macros there needs to be a distinction between code executed at compile time and the code it actually generates. To not have you manually edit AST nodes there’squote. It takes its body and converts the contents into AST. It’s basically a AST generator.quotehas the same problem as I explained above for the module body, therefore it usesunquoteas well, to put data you have at compile time “hard coded” into the generated AST.The complexity really hits if you want to create the module body from my example (those
unquotes are usually named unquote fragments) within thequoteof a macro. This is where you need to use thebind_quotedoption forquoteto remove the ambiguity.augnustin
This is amazing. 1 year later I come back here and now it feels like macros are something I could get comfortable with.
Thanks @LostKobrakai your example really helps.