Common lisp 解释Lisp';s:dotimes:结果表在做什么?

Common lisp 解释Lisp';s:dotimes:结果表在做什么?,common-lisp,Common Lisp,我正在查看dotimes上的LispWorks,但我不明白第三个变量[结果表单]在做什么。举例如下: (dotimes (temp-one 10 temp-one)) => 10 (setq temp-two 0) => 0 (dotimes (temp-one 10 t) (incf temp-two)) => T temp-two => 10 Hyperspec说 …然后对结果表进行评估。在生成结果表时 处理后,var绑定到主体的执行次数 不知道这是什么意思

我正在查看
dotimes
上的LispWorks,但我不明白第三个变量
[结果表单]
在做什么。举例如下:

(dotimes (temp-one 10 temp-one)) =>  10
(setq temp-two 0) =>  0
(dotimes (temp-one 10 t) (incf temp-two)) =>  T
temp-two =>  10
Hyperspec说

…然后对结果表进行评估。在生成结果表时 处理后,var绑定到主体的执行次数

不知道这是什么意思。为什么在这两个
dotimes
示例中需要第三个变量?在第二个例子中,我似乎可以完全忽略它,它是有效的。我的下一个例子(不确定在哪里找到的)


我也很困惑。
s
服务有什么用?

因为dotimes是一个宏,查看它的宏扩展可以让事情更清楚:


以您的第一个示例为例进行扩展:

(pprint (MACROEXPAND-1 '(dotimes (temp-one 10 temp-one))))
我得到以下输出:(根据CL实现,您的输出可能会有所不同)

有很多事情要做,但需要注意的关键是temp one绑定到值0,并作为表达式的值返回(以标准lisp求值顺序)


最后一个例子是:

(pprint (macroexpand-1 '(dotimes (i n s) (incf s i))))
产出:

(BLOCK NIL
  (LET ((#:G8253 N) (I 0))
    (DECLARE (CCL::UNSETTABLE I))
    (IF (CCL::INT>0-P #:G8253)
        (TAGBODY
         #:G8252 (INCF S I)
                 (LOCALLY (DECLARE (CCL::SETTABLE I))
                   (SETQ I (1+ I)))
                 (UNLESS (EQL I #:G8253) (GO #:G8252))))
    S))
正如您所看到的,这里的S与前面示例中的temp one的处理方式相同


在不传递最后一个变量的情况下尝试一个:

(pprint (macroexpand-1 '(dotimes (i n) (do-something i))))
你会得到:

(BLOCK NIL
  (LET ((#:G8257 N) (I 0))
    (DECLARE (CCL::UNSETTABLE I))
    (IF (CCL::INT>0-P #:G8257)
        (TAGBODY
         #:G8256 (DO-SOMETHING I)
                 (LOCALLY (DECLARE (CCL::SETTABLE I))
                   (SETQ I (1+ I)))
                 (UNLESS (EQL I #:G8257) (GO #:G8256))))
    NIL))

请注意返回值是多少。

因为dotimes是一个宏,查看它的宏扩展可以让事情更清楚:


以您的第一个示例为例进行扩展:

(pprint (MACROEXPAND-1 '(dotimes (temp-one 10 temp-one))))
我得到以下输出:(根据CL实现,您的输出可能会有所不同)

有很多事情要做,但需要注意的关键是temp one绑定到值0,并作为表达式的值返回(以标准lisp求值顺序)


最后一个例子是:

(pprint (macroexpand-1 '(dotimes (i n s) (incf s i))))
产出:

(BLOCK NIL
  (LET ((#:G8253 N) (I 0))
    (DECLARE (CCL::UNSETTABLE I))
    (IF (CCL::INT>0-P #:G8253)
        (TAGBODY
         #:G8252 (INCF S I)
                 (LOCALLY (DECLARE (CCL::SETTABLE I))
                   (SETQ I (1+ I)))
                 (UNLESS (EQL I #:G8253) (GO #:G8252))))
    S))
正如您所看到的,这里的S与前面示例中的temp one的处理方式相同


在不传递最后一个变量的情况下尝试一个:

(pprint (macroexpand-1 '(dotimes (i n) (do-something i))))
你会得到:

(BLOCK NIL
  (LET ((#:G8257 N) (I 0))
    (DECLARE (CCL::UNSETTABLE I))
    (IF (CCL::INT>0-P #:G8257)
        (TAGBODY
         #:G8256 (DO-SOMETHING I)
                 (LOCALLY (DECLARE (CCL::SETTABLE I))
                   (SETQ I (1+ I)))
                 (UNLESS (EQL I #:G8257) (GO #:G8256))))
    NIL))

请注意返回值是NIL。

结果表单只是一个表单,在循环完成后,对其求值以生成返回值(或多个)。它是可选的(如果不使用它,返回值将为
NIL
)。在上一个示例中,变量
S
用于累加
N
下的所有整数之和,该值在循环结束时返回。结果表单只是一个表单,在循环完成后对其求值以生成返回值(或倍数)。它是可选的(如果不使用它,返回值将为
NIL
)。在上一个示例中,变量
S
用于累加
N
下面的所有整数之和,该值在循环结束时返回。