我遇到过一个Scheme 过程,它使用所谓的do
过程来工作,但我不知道它是如何工作的,或者它是如何实现的。如果有人可以提供帮助,我将不胜感激。
代码如下:
(define (storage-move-right vector i j)
(do ((idx j (- idx 1)))
O(n)
((< idx i))
(vector-set! vector (+ idx 1) (vector-ref vector idx))))
最佳答案
“缺失”的循环构造 while、repeat-until 和 for
问题
控件构造while
, repeat-until
和for
存在于大多数主流编程语言中,但在Scheme 标准中却没有找到。方案中使用什么?
解决方案
这些构造都可以通过使用正常(尾递归)函数调用来“模拟”。然而,由于这些结构被如此频繁地使用,因此有一些更方便的语法糖可用。最常用的两个构造是使用 named let
和 do
构造。
最好想到 do
构造为一个美化的“do-until”循环。最简单的形式 do
是:
(do ()
[test return-exp]
exp
...)
如果return-exp
省略则返回值为 void
,“不可见的值”(如此命名是因为它不会打印在交互窗口中)。
在每个循环开始时,都会评估测试表达式。如果它不为假,则 return-exp
被求值,其返回值是整个 do
的值-环形。如果测试为假,则按顺序计算主体表达式。在计算完最后一个主体表达式后,将开始一个新的循环。
; Example 1
; WARNING: This is not good style.
; A better solution is found below.
; Pseudo Code
(define i 0) ; i := 0
(do () ; do
[(= i 5)] ; until i=5
(display i) ; display i
(set! i (+ i 1))) ; i := i +1
; displays: 01234
do
的替代方案即“named let”是 let
语法的变体。它提供了比 do 更通用的循环结构,也可以用来表达递归。它的语法与普通 let
几乎相同。 ,但变量名可以在主体中使用,以使用 var1
的新值重复执行主体。 ...通过使用新值调用名称。
(let name ([var1 exp1]
...)
body
...)
变量列表可以为空。 重写普通的 while 循环现在很容易:
while test (do () (let while ()
begin [(not test)] (when test
exp1 exp1 exp1
exp2 exp2 exp2
... ...) ...
end (while)))
(void)
表达式的计算结果为“不可见”值,表示不打算使用返回值。它不是由交互窗口(REPL)打印的。
写一个for
-循环 do
要求我们看看 do 的下一个最简单的形式:
(do ([var start-exp next-exp])
[test return-exp]
exp
...)
对do
的评价-表达式以 start-exp
的计算开始。结果绑定(bind)到变量 i
这在 next-exp
中都可见以及 test
, return-exp
和 body
表达式。当循环重新启动时next-exp
被求值并且变量var
就是反弹到结果,之前test
表达和(可能) body 被重新评估。
; Example 2
(do ([i 0 (+ i 1)]) (let loop ([i 0])
[(= i 5)] (unless (= i 5)
(display i)) (display i)
(loop (+ i 1))))
; displays: 01234
现在很清楚如何使用 do 编写普通的 for 循环:
for i=a to b step d (do ([i a (+ i d)]) (let for ([i a])
begin [(> i b)] (unless (> i b)
exp1 exp1 exp1
exp2 exp2 exp2
... ...) ...
end (for (+ i d))))
repeat-until
使用 do
编写循环很尴尬,但是使用命名的let我们可以执行如下操作:
repeat
begin (let loop () (let loop ()
exp1 exp1 exp1
exp2 exp2 exp2
... ... ...
end (if (not test) (unless test (loop)))
until test (loop)))
这个答案基于SchemeCookbook 中的一个条目。查看文件:https://web.archive.org/web/20131004034526/http://schemecookbook.org/Cookbook/IdiomLoopingConstructs
关于algorithm - "do"控制结构在Scheme 中起什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41086158/