【问题标题】:How does Common Lisp's "loop for" macro work with multiple "and"ed counters?Common Lisp“循环for”宏如何与多个“and”计数器一起工作?
【发布时间】:2010-11-20 02:52:17
【问题描述】:

以下 Common Lisp 代码不会产生我期望的输出:

(loop for a from 5 to 10
      and b = a do
      (format t "~d ~d~%" a b))

使用 SCBL,它会产生以下输出:

5 5
6 5
7 6
8 7
9 8
10 9

我期望 a 和 b 的值在每一行都相同。

我已经在网上搜索了有关此实例中循环宏的良好文档,但找不到太多。如有任何见解,我将不胜感激!

【问题讨论】:

    标签: common-lisp


    【解决方案1】:
    (loop for a from 5 to 10
          and b = a
          do (format t "~d ~d~%" a b))
    

    上面的代码在概念上与 PSETF 很接近。这些值以“并行”方式更新。原因是 AND。

    让我们用 FOR 代替 AND:

    (loop for a from 5 to 10
          for b = a
          do (format t "~d ~d~%" a b))
    

    上面将在概念上更新变量,接近于通常的 SETF,“顺序”。

    CL-USER 20 > (loop for a from 5 to 10
                       for b = a
                       do (format t "~d ~d~%" a b))
    5 5
    6 6
    7 7
    8 8
    9 9
    10 10
    

    解释见Common Lisp HyperSpec 6.1.2.1 Iteration Control:

    如果使用多个迭代子句 控制迭代,变量 初始化和步进发生 默认顺序。 构造可用于连接两个 或多个迭代子句何时 顺序绑定和步进是 没有必要。迭代行为 and 连接的子句是类似的 到宏 do 的行为 尊重do*

    【讨论】:

      【解决方案2】:

      AND 子句的步骤形式在任何变量被赋予新值之前进行评估。请改用for b = a then a 强制按顺序评估。

      参考。 http://www.gigamonkeys.com/book/loop-for-black-belts.html#equals-then-iteration

      【讨论】:

      • 感谢您的回复!我尝试了“for b = a then a”,不幸的是,它产生了相同的输出。
      • 有趣。我在 SBCL 和 LispWorks 上尝试了“a then a”,结果相同。哦,好吧,还是谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-12
      • 2013-02-17
      相关资源
      最近更新 更多