在Scheme中使用"do"

Gau*_*tam 5 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))) 
Run Code Online (Sandbox Code Playgroud)

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

Jör*_*ann 11

do表单的一般结构如下:

(do ((<variable1> <init1> <step1>)
     ...)
    (<test> <expression> ...)
  <command> ...)
Run Code Online (Sandbox Code Playgroud)

复述http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-ZH-6.html#node_chap_5,每次迭代都从评估开始<test>,如果评估为真值,<expression>则从左侧开始评估s如果do表单的结果是右边和最后一个值.在你的第二个例子中,=将被评估为布尔值为true,然后我将被评估,最后5是表单的返回值.在第一种情况下(= i 5)是测试,do表单返回一个未定义的值.编写循环的通常方法更像是这样:

(do ((i 0 (+ i 1)))
    ((= i 5) i)      ; maybe return the last value of the iteration
  (display i))
Run Code Online (Sandbox Code Playgroud)

您不需要循环变量的显式变化,因为这是由<step>表达式处理的.


G__*_*G__ 6

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

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

-

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

  • Scheme的一些方言允许`[]`以及`()`表示同样的事情.区别仅在于增强组之间的视觉差异. (2认同)