即使未设置,SBCL也会更改本地绑定函数对象的EQness?
鉴于此示例代码(来自Reddit / r / lisp问题):
(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*)))
以上建立一个函数NEXT
。 在LET
内部,我们将旧功能保留在OLD-NEXT
。 然后我们重新定义LET
内的全局函数NEXT
。
CCL / CMUCL / GCL / ECL / CLISP / LispWorks / ABCL:
? (load "test.lisp")
1 EQ? T
2 EQ? T
只有SBCL(SBCL 1.3.11)有不同的结果:
* (load "test.lisp")
1 EQ? T
2 EQ? NIL
局部变量old-next
的值不再eq
全局变量*next*
。
为什么???
看起来SBCL试图变得聪明并且优化变量。
(defun foobar ()
(print :foo))
(let ((old #'foobar))
(funcall old)
(defun foobar ()
(print :bar))
(funcall old))
打印
:FOO
:BAR
但是如果你在变量上使用SETF
,
(defun foobar ()
(print :foo))
(let ((old #'foobar))
(funcall old)
(setf old #'foobar)
(defun foobar ()
(print :bar))
(funcall old))
它打印
:FOO
:FOO
行为会改变变量是否特殊:
(inspect
(progn
(defun next ())
(let ((old #'next)
(foo #'next))
(declare (special foo))
(defun next () :different)
(list old foo))))
The object is a proper list of length 2.
0. 0: #<FUNCTION NEXT>
1. 1: #<FUNCTION NEXT {10037694EB}>
第一个元素是指最近的定义,而第二个元素是从特殊变量中获得的旧定义,如预期的那样。 当您删除特殊声明时,两个参考都是EQ(并指向新定义)。
链接地址: http://www.djcxy.com/p/94475.html上一篇: SBCL changes EQness of a local bound function object, even though it is not set?
下一篇: Lifetime error using associated type of trait with lifetime parameter