【问题标题】:"DO" macro variable-definition not being bound [duplicate]“DO”宏变量定义未绑定[重复]
【发布时间】:2018-02-23 21:40:31
【问题描述】:

我使用 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 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 创建的绑定对DO 中的 init-forms 不可见。您可能想要DO*,但我不确定循环应该做什么。变量ABC 没有阶梯形式,因此它们的值永远不会改变。也许您缺少那些的初始化表单?
  • @jkiiski 感谢您的评论。我不知道它们在 init 形式中不可用。我想,因为我可以在步骤形式中使用它们,所以它可以在任何地方使用:/ 至于循环的目的,为了这个问题,我删除了主体和返回值。这在上下文中是有道理的!你会建议我做些什么来解决初始化表单的限制?
  • 使用 DO* 而不是 DO 应该可以工作,除非您需要在任何分配之前对所有步骤进行评估(似乎并非如此,除非您有更多变量代码中没有显示)。
  • @jkiiski 非常感谢您的回答。您应该写一个 cmets 的摘要作为答案,这样我就可以给您一些功劳。

标签: common-lisp


【解决方案1】:

DO 在创建任何变量绑定之前评估变量的所有初始化形式。这意味着绑定对同一 DO 中的 init-forms 不可见。

代码应该使用DO* 代替,尽管输出不是很有趣,因为ABC 永远不会改变。

(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-forms 中引用前面的变量。使用 step-form 更新变量时也是如此。

【讨论】:

    猜你喜欢
    • 2016-12-26
    • 1970-01-01
    • 2022-12-31
    • 2019-07-03
    • 2022-12-18
    • 1970-01-01
    • 2012-06-06
    • 2014-10-09
    • 1970-01-01
    相关资源
    最近更新 更多