如果Scheme来自Lisp,这是一种列表编程语言,那么他们怎么没有内置循环,或者是否存在循环并且我没有意识到?
提前致谢!
答案 0 :(得分:4)
为什么Scheme没有循环?
因为Scheme(以及Ocaml)需要tail-calls并且R5RS规范要求Scheme实现正确地提供它们(对于Java和C来说这是错误的。在C中,只有最近的编译器是有时候能够进行尾调用优化,而且大多数都没有。)
使用尾递归,您不需要任何循环结构;通过“使用参数跳转”实现尾调用,因此不要在call stack上推送新的调用帧(但用新的调用替换当前调用帧)。 / p>
他们怎么没有内置列表,
Scheme有列表。
Scheme确实有循环,但是要让你正确思考它们并编写尾递归调用。一旦你掌握了它,你就会发现它比循环结构更通用,更优雅。另请阅读continuations和CPS。
我很惊讶很少有人问:为什么C或C ++有循环?这些语言可以声明需要进行尾调用优化。在语言中使用循环的唯一原因是缺乏尾调用优化。所以C或Java主要有历史原因。我猜Common Lisp也有循环,主要是出于历史原因。 (Common Lisp hyperspec不需要尾调用优化,但所有良好的实现(例如SBCL)都提供了它。)
答案 1 :(得分:1)
Scheme有循环(或者至少曾经有过循环,我不是最新的Scheme)。
https://en.wikibooks.org/wiki/Scheme_Programming/Looping:
'做'形式
还有一个迭代构造do,可以简化编写一些函数。例如,此过程对给定列表的所有元素进行求和:
(define (sum/display lst) (do ((remaining lst (cdr remaining)) (final-sum 0 (+ final-sum (car remaining)))) ((null? remaining) final-sum) (display (car remaining)) (newline))) (sum/display '()) > 0 (sum/display '(1 2 3 7)) >>> 1 >>> 2 >>> 3 >>> 7 > 13