Before something can be evaluated by a Lisp, it must be read in first. Read
operation takes a textual representation of some datum and turns it into a Lisp datum.
[6]> (read)
'a ; I typed this
'A ; CLISP responded
[7]> (type-of *) ; * is previous-value
CONS
[8]> (mapcar #'print **) ; ** is value before previous value
QUOTE ; first element of the list (code form), (QUOTE A)
A ; second element of the list
'A ; CLISP translates (QUOTE A) back into 'A, for show
So ' ...
is turned into (quote ...)
, on read. How does this work?
[4]> (get-macro-character #\')
#<SYSTEM-FUNCTION SYSTEM::QUOTE-READER> ;
NIL
So there is something there behind the quote. A quote-reader
system function. Lists are also something special:
[5]> (get-macro-character #\()
#<SYSTEM-FUNCTION SYSTEM::LPAR-READER> ;
NIL
When all is read, the result is then evaluated. That's the "read-eval" part of the "read-eval-print loop", the REPL. The result of evaluating a quote form, (quote ...)
, is whatever is inside it. IOW the top quote
disappears, but all the inner quote
s remain.
Without the quote, everything is evaluated. So to evaluate (cdr (FEE FI))
, the form (FEE FI)
must be evaluated, and if it results in a list, that list's cdr
will be returned.
You could try to define another way of representing literal data, say with [ ... ]
brackets standing for (quote ( ... ))
. The conversion could treat the inner brackets as simple parentheses. Then both
> (cdar [(fee fi) (fo fum)])
> (cdar [[fee fi] [fo fum]])
would behave the same, as you expected.
PS. CLHS is your friend.
edit: here's where you've erred. In your last example,
[77]> (car '('(fee fi) '(fo fum)))
'(FEE FI)
[78]> (cdr '(FEE FI))
(FI)
the last call should have been
[1]> (cdr (quote '(FEE FI)))
((FEE FI))
Putting '(FEE FI)
inside the quote
form prevents its evaluation, so it is passed as is to cdr
. Here's how we can be sure about this:
[2]> (car '('(fee fi) '(fo fum)))
'(FEE FI)
[3]> (cdr *) ; * is the last returned value
((FEE FI))
(cdr (car ...))
really is cdar
, no question about it.