They are not exactly the same, even if they evaluate the same values ββin REPL. Consider these examples in which cons cells are destructively modified:
TEST> (defun literal-cons () (let ((cons '(1 . 2))) (incf (cdr cons)) cons)) LITERAL-CONS TEST> (literal-cons) (1 . 3) TEST> (literal-cons) (1 . 4) TEST> (literal-cons) (1 . 5)
Compared to this:
TEST> (defun non-literal-cons () (let ((cons (cons 1 2))) (incf (cdr cons)) cons)) NON-LITERAL-CONS TEST> (non-literal-cons) (1 . 3) TEST> (non-literal-cons) (1 . 3)
In the first version, you change literal cons in the code itself (thus, this is self-modifying code). In the second version, the cons cell is not literal. It is created every time the code is called, and only this new cons cell will be changed.
TEST> (function-lambda-expression #'literal-cons) (LAMBDA NIL (DECLARE (CCL::GLOBAL-FUNCTION-NAME LITERAL-CONS)) (BLOCK LITERAL-CONS (LET ((CONS '(1 . 5))) (INCF (CDR CONS)) CONS))) ;; notice the '(1 . 5) NIL LITERAL-CONS
Since this can lead to subtle errors when using destructive operations, one must be careful with such literal objects in the code. It also affects list literals ( '(1 2 3) vs. (list 1 2 3) ), which are built from cons cells.
From HyperSpec :
literal adj. (of an object) directly referenced in the program than calculated by the program; that is, as data in the form of a quote or, if the object is a self-evaluating object, appears as unquoted data. `` In the form of (cons "one" '("two")), the expressions "one", ("two") and "two" are literal objects. ''
danlei
source share