Common Lisp dotimes结果很神秘

147*_*7pm 3 loops common-lisp

我懂了

(dotimes (temp-one 10 temp-one))
Run Code Online (Sandbox Code Playgroud)

来自Hyperspec的例子dotimes.运行它会产生答案10.因此,temp-one在第三个参数位置作为返回的"结果",但是当它dotimes从0开始时它是如何变为10 并且只变为9?

>(dotimes (temp-one 10 temp-one) (format t "~3d " temp-one))
  0   1   2   3   4   5   6   7   8   9 
10
Run Code Online (Sandbox Code Playgroud)

关于第三个参数,我在这里缺少什么?

zut*_*zut 5

如果你看一下dotimes的 Hyperspec条目,它会说它是一个意味着你可以通过调用macroexpand来看到"引擎盖下" :

(macroexpand '(dotimes (i 10 i)))
Run Code Online (Sandbox Code Playgroud)

SBCL:

(BLOCK NIL
  (LET ((I 0))
    (DECLARE (TYPE UNSIGNED-BYTE I))
    (TAGBODY
      (GO #:G386)
     #:G385
      (TAGBODY)
      (PSETQ I (1+ I))
     #:G386
      (UNLESS (>= I 10) (GO #:G385))
      (RETURN-FROM NIL (PROGN I)))))
Run Code Online (Sandbox Code Playgroud)

Allegro CL:

(do ((i 0 (1+ i)))
    ((>= i 10) i))
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,迭代变量i增加1,然后结束测试(>= i 10)完成.正如jkiiski写道:

"在处理结果形式时,var与执行主体的次数绑定在一起."

并且在变量增加和测试之后评估(return-from ..)形式(SBCL)和i形式(Allegro CL).