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
下面的所有整数之和,该值在循环结束时返回。