Why is there no primitive `unquote` Lisp?

I have been thinking a lot about the Lisp database lately; I read several guides and / or other materials on the Internet, including P. Graham's The Roots of Lisp :

In the roots of Lisp, quote described as a primitive that changes code to data, thereby quoting it, but there seems to be no equivalent inverse primitive, i.e. the unquote primitive. I thought this might be the business of eval , but eval often runs data in a zero lexical environment, which is not equivalent to changing the data back to code.

Ergo, why is there no primitive unquote Lisp?

+7
eval lisp quote
source share
2 answers

unquote is only useful in the context of quasiquote , and quasiquote can be implemented as a macro (which uses quote behind the scenes). Therefore, there is no need to have a unquote primitive; the quasiquote macro simply deals with unquote characters as they are found.

( quasiquote is the schema name for the backtick quote. Thus:

 `(foo bar ,baz) 

read like

 (quasiquote (foo bar (unquote baz))) 

in the diagram.)


Here is a very simple Scheme quasiquote macro (it processes lists, unlike the standard quasiquote , which also processes vectors and other data types):

 (define-syntax quasiquote (syntax-rules (unquote unquote-splicing) ((quasiquote (unquote datum)) datum) ((quasiquote ((unquote-splicing datum) . next)) (append datum (quasiquote next))) ((quasiquote (datum . next)) (cons (quasiquote datum) (quasiquote next))) ((quasiquote datum) (quote datum)))) 

Equivalent version using all standard reading abbreviations:

 (define-syntax quasiquote (syntax-rules (unquote unquote-splicing) (`,datum datum) (`(,@datum . next) (append datum `next)) (`(datum . next) (cons `datum `next)) (`datum 'datum))) 
+8
source share

I am also relatively new to Lisp, but I think you are thinking of eval . eval is a way to change data back into code.

Namely, consider a simple function.

 (defun foo (abc) (list abc)) 

Then, if you do something like this, you will get a list of characters:

 CL-USER> (foo 'a 'b 'c) (ABC) 

If you add a quote at the beginning, the function call itself is considered as part of the data (list):

 CL-USER> '(foo 'a 'b 'c) (FOO 'A 'B 'C) 

Adding another quote has the expected effect:

 CL-USER> ''(foo 'a 'b 'c) '(FOO 'A 'B 'C) 

Let's expand it with eval , which essentially can be seen as the inverse of quote . This is the opposite. The x axis is a data form. The Y axis is a code form. I hope this (somewhat stretched) analogy makes sense.

 CL-USER> (eval ''(foo 'a 'b 'c)) (FOO 'A 'B 'C) 

Can you guess what happens if I kiss two lines of eval in a row? Here he is:

 CL-USER> (eval (eval ''(foo 'a 'b 'c))) (ABC) 
0
source share

All Articles