Given this example code (from a Reddit /r/lisp question):
(defun next (pos)
(nth (1+ pos)
'(0 1 2 3 4 5 6 7 8 9 10)))
(defvar *next* (function next))
(let ((old-next #'next)
(previous (make-hash-table)))
(format t "~% 1 EQ? ~a" (eq old-next *next*))
(defun next (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-next pos))))
(format t "~% 2 EQ? ~a" (eq old-next *next*)))
Above establishes a function NEXT
. Inside the LET
, we keep the old function in OLD-NEXT
. Then we redefine the global function NEXT
inside the LET
.
CCL/CMUCL/GCL/ECL/CLISP/LispWorks/ABCL:
? (load "test.lisp")
1 EQ? T
2 EQ? T
Only SBCL (SBCL 1.3.11) has a different result:
* (load "test.lisp")
1 EQ? T
2 EQ? NIL
The value of the local variable old-next
is no longer eq
to the value of the global variable *next*
.
Why???
Looks like SBCL is trying to be smart and optimizes the variable away.
Prints
But if you use
SETF
on the variable,it prints