Lately, I've been thinking a lot about the basis of Lisp; I've read several manuals and/or other materials on the Internet, including The Roots of Lisp by P. Graham:
In The Roots of Lisp, quote
is described as a primitive that changes code into data, thereby quoting it, but there doesn't seem to be an equivalent inverse primitive, that is an unquote
primitive. I thought it might have been eval
's business, but eval
often runs the data in a null lexical environment, which is not equivalent to changing data back into code.
Ergo, why isn't there an unquote
Lisp primitive?
I am also relatively new to Lisp, but I think that what you were thinking about is
eval
.eval
is the way to change data back to code.Namely, consider a simple function.
Then, if you do something like this, you get a list of symbols:
If you add a quote in the front, the function call itself is treated as a piece of data (list):
Adding one more quote has an expected effect:
Let us now unwind it with
eval
, which in essence may be thought of as the inverse operation for thequote
. It is the inverse. The x-axis is the data form. The y-axis is the code form. Hopefully this (somewhat stretched) analogy makes sense.Can you guess what will happen if I chain two
eval
s in a row? Here it is:unquote
is only useful in the context ofquasiquote
, andquasiquote
can be implemented as a macro (that usesquote
behind the scenes). So there's no need to have anunquote
primitive; thequasiquote
macro simply deals withunquote
symbols as they are found.(
quasiquote
is the Scheme name for the backtick quote. Thus:is read in as
in Scheme.)
Here's a very simple Scheme
quasiquote
macro (it only handles lists, unlike standardquasiquote
which also handles vectors and other data types):Equivalent version using all the standard reader abbreviations: