【发布时间】:2014-11-09 15:02:15
【问题描述】:
如果我创建这样的闭包,
(let ((A (make-array '(10) :initial-element 5)))
(defun h (i)
(aref a i))
(defsetf h (i) (x) `(setf (aref ,a ,i) ,x)))
然后,正如我所料,(h i) 将返回a 的第 i 个元素:
(h 1) ;; => 5
(h 2) ;; => 5
但尽管setf 扩展可以正常工作并正确设置a 的第i 个元素,但它也会在SBCL 中产生警告:
(setf (h 1) 10)
; in: SETF (H 1)
; (SETF (AREF #(5 10 5 5 5 5 5 5 5 5) 1) #:G1124)
; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL SB-C::%FUNCALL
; ==>
; ((SETF AREF) #:NEW0 #(5 10 5 5 5 5 5 5 5 5) 1)
;
; caught WARNING:
; Destructive function (SETF AREF) called on constant data.
; See also:
; The ANSI Standard, Special Operator QUOTE
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition
在 GCL 中发出错误信号:
>(setf (h 1) 10)
Error:
Fast links are on: do (si::use-fast-links nil) for debugging
Signalled by LAMBDA-CLOSURE.
Condition in LAMBDA-CLOSURE [or a callee]: INTERNAL-SIMPLE-UNBOUND-VARIABLE: Cell error on A: Unbound variable:
Broken at LIST. Type :H for Help.
1 Return to top level.
在 CLISP 和 ECL 中,该示例运行良好。
我在写了几年 Scheme 之后又回到了 Common Lisp,所以我可能在概念上混合了这两种语言。我想我已经触发了根据规范未定义的行为,但我无法确切地看到我做错了什么。我将不胜感激!
【问题讨论】:
标签: lisp closures common-lisp