Scheme 中的命名让
Named let in Scheme
我正在尝试使用命名 let 在 Scheme 中编写一个循环。我希望能够根据各种标准尽早结束迭代,而不是总是在最后循环。实际上,我想要 while
、break
和 continue
。出于充分的原因,我不得不使用 guile 1.8,而 guile 1.8 没有实现 R6RS while
构造。我的问题是,使用命名 let 进行递归是否必须是尾递归,为什么不能在结束之前重新启动循环? [这需要代码示例吗?]当我尝试在多个 IO 操作点使用提前退出进行递归时,我总是读取过去的 EOF 并得到不可预测的数据损坏。
(let name ((iter iter-expr) (arg1 expr1) (arg2 expr2))
(cond
(continue-predicate (name (next iter) arg1 arg2)))
(break-predicate break-expression-value)
(else (name (next iter) next-arg1-expression next-ar2-expression))))
continue 只是使用大多数相同的参数再次调用,除了迭代的部分将更改为下一个内容之外,其余参数不变。
休息是基本情况。
那么什么是while
?它是一个带有中断谓词和默认情况的命名 let
。
Scheme 并没有真正的 while
结构。如果您阅读该报告,您会发现它只是一个语法糖(宏),可以变成类似于命名 let
的东西。
如果你想在没有完成所有之前的计算的情况下退出它,你需要它是尾递归的。您还可以使用 call/cc
提供退出延续,这基本上是让 Scheme 在幕后为您完成。通常 call/cc
对初学者来说太过遥远,掌握它需要一些时间,所以让你的程序尾递归比做这样的事情更容易理解:
(define (cars lists-of-pair)
(call/cc (lambda (exit)
(fold (lambda (e a)
(if (pair? e)
(cons (car e) a)
(exit '()))) ; throw away continuations to make current result make it ()
'()
lists-of-pair)))
(cars '((1 2) (a b))) ; ==> (1 a)
(cars '((1 2) ())) ; ==> ()
我正在尝试使用命名 let 在 Scheme 中编写一个循环。我希望能够根据各种标准尽早结束迭代,而不是总是在最后循环。实际上,我想要 while
、break
和 continue
。出于充分的原因,我不得不使用 guile 1.8,而 guile 1.8 没有实现 R6RS while
构造。我的问题是,使用命名 let 进行递归是否必须是尾递归,为什么不能在结束之前重新启动循环? [这需要代码示例吗?]当我尝试在多个 IO 操作点使用提前退出进行递归时,我总是读取过去的 EOF 并得到不可预测的数据损坏。
(let name ((iter iter-expr) (arg1 expr1) (arg2 expr2))
(cond
(continue-predicate (name (next iter) arg1 arg2)))
(break-predicate break-expression-value)
(else (name (next iter) next-arg1-expression next-ar2-expression))))
continue 只是使用大多数相同的参数再次调用,除了迭代的部分将更改为下一个内容之外,其余参数不变。
休息是基本情况。
那么什么是while
?它是一个带有中断谓词和默认情况的命名 let
。
Scheme 并没有真正的 while
结构。如果您阅读该报告,您会发现它只是一个语法糖(宏),可以变成类似于命名 let
的东西。
如果你想在没有完成所有之前的计算的情况下退出它,你需要它是尾递归的。您还可以使用 call/cc
提供退出延续,这基本上是让 Scheme 在幕后为您完成。通常 call/cc
对初学者来说太过遥远,掌握它需要一些时间,所以让你的程序尾递归比做这样的事情更容易理解:
(define (cars lists-of-pair)
(call/cc (lambda (exit)
(fold (lambda (e a)
(if (pair? e)
(cons (car e) a)
(exit '()))) ; throw away continuations to make current result make it ()
'()
lists-of-pair)))
(cars '((1 2) (a b))) ; ==> (1 a)
(cars '((1 2) ())) ; ==> ()