scheme心得(3) 尾调用/尾递归与CPS

摘要:介绍了尾调用/尾递归调用(tail call/tail recursive call)的一般概念、形式、用法,以及CPS(continuation-passing style)的编程模式。

  函数式编程非常重要的一个概念是递归。在函数式编程里面,递归是原生的合乎情理的,是从lambda计算继承而来的;而迭代(循环)是不良的,因为它的副作用,因为迭代(循环)意味着修改变量的值,违背了函数式编程的本意。修改变量的值是某些纯粹的函数式编程语言所坚决摈弃的,比如haskell。而scheme采取了更务实的做法,支持修改变量的值,并且保留了迭代(循环)的语法。这是非常有趣和值得探讨的。

  我们知道,当一个函数的返回语句是另一个函数的直接调用,可称为尾调用tail call。尾调用的优点是节省程序运行时间和空间。因为函数每一层的嵌套调用,都意味着一个新的栈帧stack frame。栈帧保留了诸如实参值,局部变量,访问链,返回地址等信息,构造和销毁栈帧是程序运行时的开销。而尾调用,可以避免在内存中保留caller函数的栈帧,只需要直接把caller的返回地址复制到callee的返回地址。一般情况下的尾调用,优势不明显,但是如果是层次非常多的递归调用,则可以大大发挥作用。这种递归叫做尾递归。优化后的尾递归,即直接传递返回地址的尾递归,与过程式编程的迭代(循环)类同。换句话说,也可以编译为goto或者jump语句。

  以阶乘函数为例。

(define (factorial n)
  (if (=
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值