Disclaimer: The following questions are not relevant for any code I'm working on, but I'm curious about any answers, since I'm still wondering about these questions despite telling me repeatedly they're not important.
I can use quote or ' to "nest" quoting as often as I want to, as in
> 'a
'a
> ''a
''a
> '''a
'''a
and so on.
I wonder if there's also a way to "unquote" a quoted expression like this:
> (my-unquote ''a)
'a
I haven't found anything on this. There isunquote, but it gives an error message when used outside a quasiquote form.
The closest approach I can think of is using eval, but that seems kind of "heavy." I guess it should be possible to turn ''a into 'a at compile time. Then again, I don't see where such unquoting would be needed, so maybe there's no way to do it because nobody needed it.
I occasionally read the statement that quoting a literal gives the literal itself. Looking at
> '1
1
> (eq? '1 1)
#t
this statement looks reasonable, but if I apply quoting more than once, I don't get the literal:
I guess this is something to do with the application of macros from outside in, i.e. since ''1 is equivalent to (quote (quote 1)) the outer quote "sees" (quote 1), not 1. However, I'm still somewhat confused and to me that's only a part of the explanation.
I think eval is precisely the opposite of quote: quoteprevents evaluation. The natural counterpart is to force evaluation using eval (though note considerations of current-namespace/the namespace argument to eval when in a module vs a REPL).
(quote (quote 1)) evaluates to the list (quote 1):
> (equal? ''1 (list 'quote 1))
#t
Recall that quote is a special form, and as such has its own evaluation rules. Special forms are evaluated outside-in, so in (quote_a (quote_b 1)) (marked for clarity; assume both are actually quote) the quote_a controls evaluation of the expression (quote_b 1) and, by the rules of quote, does not evaluate it but returns it directly.
In fact, the latter point is what makes (eval ''a) work (assuming appropriate namespace setup): the ''a is given to eval as (quote a), and evaluating that expression is of course the result 'a.
'<whatever> is read/parsed as (quote <whatever>). For the rest of my comment, I will use (quote <whatever>) explicitly to make it less confusing.
quote is not a function. It is a form that constructs a representation of <whatever>. It canāt be a function because if it were, <whatever> would already be evaluated by the time āquoteā consumes it, so it canāt access the underlying representation. This can partially explain why (quote (quote 1)) doesn't necessarily need to be equal to (quote 1).
In Racket, some expressions have a representation that coincides with itself. Numbers, like 1, are one of these expressions. Thatās why (quote 1) evaluates to 1.
On the other hand, (quote 1) is not self-quoting. (quote (quote 1)) needs to construct a representation of (quote 1), so it constructs (list (quote quote) 1).
How do you remove the outer quote when itās nested in more than one level? (quote (quote <whatever>)) evaluates to (list (quote quote) (quote <whatever>)). As you want (quote <whatever>), you can simply access the second element.
Total agreement with @sorawee . To add to it: I think the printed representation
'''a
... is in many ways confusing and broken. It suggests that the symbol is somehow "triply quoted". That's basically not true; the outer quote is essentially "disabling" all of the internal quotes. I think it would be probably better to print this value as
'(quote (quote a))
... which is another way of writing the same value. More generally, I think the printer would be less confusing if it didn't "compress" quotes occurring inside of already-quoted expressions.
The counter-argument, I suppose, would be for values like
Thanks a lot for all your replies! It's much clearer now.
@sorawee I knew that quote was a form, not a function, but due to the printing confusion that @jbclements mentioned, I somehow thought that quote, applied to an inner quote would handle the inner quote in some special way and I couldn't understand how exactly. Now I understand that the inner quote is just treated like any other "word" and becomes a symbol (i.e. 'quote = (quote quote)).
Having both representations, 'foo and (quote foo) can make things more difficult to follow, but I do understand that 'foo is more practical in a lot of cases. (I also use things like 'foo and '(1 2 3) all the time.)
@sorawee, along these lines, I think it was a good idea to explain everything in terms of quote instead of also using '.
Indeed, I guess that was the source of my confusion.
Like anything initially imported by the #lang (whether function or syntax) quote can be redefined. Add on the ' reader shorthand, and you can get enough layers to make a fine confusion.
I seem to recall an even more mysterious situation where I redefined something that caused input to the REPL to hang? Alas I can't remember now, exactly; it's probably somewhere on the old mailing list archives.
Yeah, you're right, I got lazy, I couldn't be bothered to figure out what identifier would be left there. Should probably have realized that it's "quote", though :).
Ooh, but what if you stack your dequotes? Okay, actually I have work to do....