Common lisp &引用;“做”;未绑定宏变量定义
我已经使用DO宏(使用Peter Seibel的书作为参考)编写了一个函数,但出于某种原因,当我编译我的函数时:Common lisp &引用;“做”;未绑定宏变量定义,common-lisp,Common Lisp,我已经使用DO宏(使用Peter Seibel的书作为参考)编写了一个函数,但出于某种原因,当我编译我的函数时: (defun test () (do ((n 2 (1+ n)) (m 1 (1+ m)) (a (1+ n)) (b (1+ m)) (c (+ n m))) ((= n 10) (* a b c)) (print (* a b c)))) 我收到以下警告消息: WARNING: in TEST
(defun test ()
(do ((n 2 (1+ n))
(m 1 (1+ m))
(a (1+ n))
(b (1+ m))
(c (+ n m)))
((= n 10) (* a b c))
(print (* a b c))))
我收到以下警告消息:
WARNING: in TEST in lines 1..10 : N is neither declared nor bound,
it will be treated as if it were declared SPECIAL.
WARNING: in TEST in lines 1..10 : M is neither declared nor bound,
it will be treated as if it were declared SPECIAL.
WARNING: in TEST in lines 1..10 : N is neither declared nor bound,
it will be treated as if it were declared SPECIAL.
WARNING: in TEST in lines 1..10 : M is neither declared nor bound,
it will be treated as if it were declared SPECIAL.
当我尝试执行test
时,它说n
没有值
我的印象是,装订的顺序并不重要,但我还是尝试重新排列,结果还是一样的
我错过了什么?
在创建任何变量绑定之前,我正在使用CLISP 2.49对变量的所有初始化表单进行求值。这意味着绑定对同一
DO
中的init表单不可见
代码应该改为使用DO*
,尽管输出不是很有趣,因为A
、B
和C
从未更改
(defun test ()
(do* ((n 2 (1+ n))
(m 1 (1+ m))
(a (1+ n))
(b (1+ m))
(c (+ n m)))
((= n 10) (* a b c))
(print (* a b c))))
(test)
; 18
; 18
; 18
; 18
; 18
; 18
; 18
;=> 18
DO*
在其他方面与DO
相同,但它逐个计算并建立绑定,因此您可以在init表单中引用前面的变量。使用step表单更新变量时也会执行相同操作。DO
在创建任何变量绑定之前,对变量的所有初始表单进行求值。这意味着绑定对同一DO
中的init表单不可见
代码应该改为使用DO*
,尽管输出不是很有趣,因为A
、B
和C
从未更改
(defun test ()
(do* ((n 2 (1+ n))
(m 1 (1+ m))
(a (1+ n))
(b (1+ m))
(c (+ n m)))
((= n 10) (* a b c))
(print (* a b c))))
(test)
; 18
; 18
; 18
; 18
; 18
; 18
; 18
;=> 18
DO*
在其他方面与DO
相同,但它逐个计算并建立绑定,因此您可以在init表单中引用前面的变量。使用step表单更新变量时也会执行相同操作。由DO
创建的绑定对于DO
中的init表单不可见。您可能希望DO*
,但我不确定循环应该做什么。变量A
、B
和C
没有阶跃形式,因此它们的值永远不会改变。也许你丢失了这些的init表单?@jkiiski谢谢你的评论。我不知道它们在init表单中不可用。我想,既然我可以在步骤表单中使用它们,那么它在任何地方都可以使用:/As为了循环的目的,为了这个问题,我删除了主体和返回值。这在上下文中是有意义的!您建议我如何绕过init表单限制?使用do*
而不是do
应该可以,除非您需要在任何赋值之前对步骤表单进行求值(情况似乎并非如此,除非代码中没有显示更多变量)。@jkiiski非常感谢您的回答。你应该写一个评论摘要作为答案,这样我可以给你一些信任。由DO
创建的绑定对于DO
中的init表单是不可见的。您可能希望DO*
,但我不确定循环应该做什么。变量A
、B
和C
没有阶跃形式,因此它们的值永远不会改变。也许你丢失了这些的init表单?@jkiiski谢谢你的评论。我不知道它们在init表单中不可用。我想,既然我可以在步骤表单中使用它们,那么它在任何地方都可以使用:/As为了循环的目的,为了这个问题,我删除了主体和返回值。这在上下文中是有意义的!您建议我如何绕过init表单限制?使用do*
而不是do
应该可以,除非您需要在任何赋值之前对步骤表单进行求值(情况似乎并非如此,除非代码中没有显示更多变量)。@jkiiski非常感谢您的回答。你应该写一个评论摘要作为回答,这样我可以给你一些信用。