【发布时间】:2019-07-07 19:35:14
【问题描述】:
我看不懂下面的代码:
(defun my-test ()
(let ((temp '(())))
(format t "temp: ~a~%" temp)
((lambda ()
(push 5 (first temp))))))
;; Execute this call twice in a row.
(my-test)
输出:
temp: (NIL)
temp: ((5))
temp如何保存值?我知道有以下警告,但我不明白这种行为背后的逻辑。
; in: DEFUN MY-TEST
; (PUSH 5 (FIRST TEMP))
; --> LET*
; ==>
; (SB-KERNEL:%RPLACA #:TEMP0 (CONS 5 (FIRST #:TEMP0)))
;
; caught WARNING:
; Destructive function SB-KERNEL:%RPLACA called on constant data: (NIL)
; See also:
; The ANSI Standard, Special Operator QUOTE
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition
以下代码输出相同的结果:
(flet ((my-fct ()
(let ((temp '(())))
(format t "temp: ~a~%" temp)
((lambda ()
(push 5 (first temp)))))))
(my-fct)
(my-fct))
(let ((fct (lambda ()
(let ((temp '(())))
(format t "temp: ~a~%" temp)
((lambda ()
(push 5 (first temp))))))))
(funcall fct)
(funcall fct))
但这一个有效:
;; Execute this call twice in a row.
((lambda ()
(let ((temp '(())))
(format t "temp: ~a~%" temp)
((lambda ()
(push 5 (first temp)))))))
这个也可以:
(defun my-test ()
(let ((temp (list ())))
(format t "temp: ~a~%" temp)
((lambda ()
(push 5 (first temp))))))
(my-test)
还有这个:
(defun my-test ()
(let ((temp (list (list))))
(format t "temp: ~a~%" temp)
((lambda ()
(push 5 (first temp))))))
(my-test)
但不是这个:
(defun my-test ()
(let ((temp `(,(list))))
(format t "temp: ~a~%" temp)
((lambda ()
(push 5 (first temp))))))
(my-test)
- 为什么它对某些代码有效,而对另一些代码无效?
- 如何在多次调用中保留词法值?
【问题讨论】:
-
该死的。我做了一个回答,寻找像
`(,(list))这样的特殊情况,我觉得这很有趣。我认为他正在使用 SBCL,它实际上不断地将(list)折叠到(),这使得整个事情'(())。此外,第一个 OP 说,如果您将其保存为文件并加载已编译的版本,则 SBCL 中不起作用。然后文件中所有位置的'(())被一个实例替换,并改变第一个实例。 -
@Sylwester :我确实使用了 SBCL,但没有编译文件。 Common Lisp 太酷了。 :D
标签: common-lisp