为什么Scheme没有循环?

时间:2017-11-29 20:05:19

标签: loops scheme lisp

如果Scheme来自Lisp,这是一种列表编程语言,那么他们怎么没有内置循环,或者是否存在循环并且我没有意识到?

提前致谢!

2 个答案:

答案 0 :(得分:4)

  

为什么Scheme没有循环?

因为Scheme(以及Ocaml)需要tail-calls并且R5RS规范要求Scheme实现正确地提供它们(对于Java和C来说这是错误的。在C中,只有最近的编译器是有时候能够进行尾调用优化,而且大多数都没有。)

使用尾递归,您不需要任何循环结构;通过“使用参数跳转”实现尾调用,因此不要在call stack上推送新的调用帧(但用新的调用替换当前调用帧)。 / p>

  

他们怎么没有内置列表,

Scheme有列表。

Scheme确实有循环,但是要让你正确思考它们并编写尾递归调用。一旦你掌握了它,你就会发现它比循环结构更通用,更优雅。另请阅读continuationsCPS

我很惊讶很少有人问:为什么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