在Scheme中使用“do”

时间:2010-07-07 21:57:26

标签: scheme do-loops

CODE SNIPPET 1和CODE SNIPPET 2有什么区别?

;CODE SNIPPET 1
(define i 0)                      
(do ()                             
  ((= i 5))                       ; Two sets of parentheses
  (display i)                     
  (set! i (+ i 1))) 


;CODE SNIPPET 2
(define i 0)                      
(do ()                             
  (= i 5)                         ; One set of parentheses
  (display i)                     
  (set! i (+ i 1))) 

第一个代码片段产生01234,第二个代码片段产生5.发生了什么?额外的一组括号有什么作用?另外,我看到使用了[(= i 50)]而不是((= i 5))。有区别吗?谢谢!

2 个答案:

答案 0 :(得分:11)

do表单的一般结构如下:

(do ((<variable1> <init1> <step1>)
     ...)
    (<test> <expression> ...)
  <command> ...)

释义http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-6.html#node_chap_5,每次迭代从评估<test>开始,如果评估为真值,则从左到右评估<expression>,如果结果是do,则评估最后一个值。 =表格。在你的第二个例子中,(= i 5)将被评估为布尔值为true,然后我将被评估,最后5是表单的返回值。在第一种情况下,do是测试,(do ((i 0 (+ i 1))) ((= i 5) i) ; maybe return the last value of the iteration (display i)) 形式返回未定义的值。编写循环的通常方法更像是:

<step>

您不需要显式变量循环变量,因为它由{{1}}表达式处理。

答案 1 :(得分:6)

在第一种情况下,((= i 5))用作终止测试。所以重复do循环直到i = 5.

在第二种情况下,(= i 5)不是测试。 do循环只执行第一个表单,返回 5

-

(根据所附评论)括号在某些方案中可以互换。对参数使用[]有时被认为是惯用的(即对父)。