【问题标题】:Using "do" in Scheme在 Scheme 中使用“do”
【发布时间】:2011-03-13 01:41:11
【问题描述】:

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))) 

第一个代码 sn -p 产生 01234,第二个产生 5。这是怎么回事?额外的一组括号有什么作用?另外,我看到使用[(= i 50)] 代替((= i 5))。有区别吗?谢谢!

【问题讨论】:

  • “生产”是什么意思?第一个 sn-p 打印 "01234" 并且 评估 为空。第二个 sn-p 不 打印 任何内容,并且 评估 为 5。

标签: scheme do-loops


【解决方案1】:

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,每次迭代都从评估&lt;test&gt;开始,如果评估为真值,则从左到右评估&lt;expression&gt;s,最后一个值作为do形式的结果返回.在您的第二个示例中,= 将被评估为布尔值,意思是 true,然后 i 将被评估,最后 5 是表单的返回值。在第一种情况下,(= i 5) 是测试,do 表单返回一个未定义的值。编写循环的通常方法是这样的:

(do ((i 0 (+ i 1)))
    ((= i 5) i)      ; maybe return the last value of the iteration
  (display i))

您不需要循环变量的显式突变,因为这是由&lt;step&gt; 表达式处理的。

【讨论】:

    【解决方案2】:

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

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

    --

    (根据附加的 cmets)括号在方案的某些方言中是可以互换的。有时将 [] 用于参数(即对父 do)被认为是惯用的。

    【讨论】:

    • Scheme 的某些方言允许 []() 表示相同的意思。区别只是为了增强组之间的视觉差异。
    • 特别是,非常流行的 Racket/mzscheme 方言允许任意一组成对的括号互换使用,例如 {= [+ 1 2] (- 7 4)} 返回 #t。不平衡肯定是一个错字。我注意到有一种趋势是使用方括号来表示特殊的“句法”列表,比如有问题的列表。
    • Harman:在我阅读之前,我看到原始问题中的不平衡已得到纠正。我认为这只是一个错字。
    • @newacct 你是对的;出于某种原因,我在心理上将 = 解析为赋值运算符,并且 do 评估所有形式而不仅仅是第一个形式。已相应地更新了我的答案。
    • 嗯,没有。 do 循环不会“简单地执行”第二种形式。这到底是什么意思??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多