无间地狱:递归和应用序的宿世恩仇

本文通过两个函数示例探讨了Scheme解释器的工作方式——应用序与正则序的区别,并介绍了一个尝试改进条件判断函数if的例子,揭示了其背后的原理及潜在问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

示例

> (define (p)(p))

 

注解这是一个无聊的函数,该函数永远调用自己,却永远什么事都不做。

 

说明从前有一个叫Ben Bitdiddle为了检测解释器采用的是应用序(先求值后展开表达式)还是正则序(先展开表达式再对所有表达式求值),便写了这么两个函数:

> (define (p)(p))

> (define (test?x y)

    (if (= x 0)

        0

        y))

然后调用:

> (test? 0 (p))

很明显,如果是应用序,即会陷入无限死循环;如果是正则序,则立即返回0

 

《计算机程序的构造和解释中文版2》练习1.6中讲了一个小美女故事,说聪明的小美女准备使用Cond符录为自己修练出威力更强大的if法杖,过程如下:

(define (new-if predicatethen-clause else-clause)

  (cond(predicate then-clause)

        (elseelse-clause)))

看上去似乎很美好,但其实却是错的。魔法失败了,小美女被炸成了乌鸡白凤丸。当用户调用这个new-if函数时,如果then-clauseelse-clause只要是表达式,不论predicate是否为真,马上便被调用,因为我们的scheme解释器是应用序解释。在递归中如果用这个new-if来做递归结束判断并调用自身,那么将永远没有结果,直至内存爆炸。

 

备注:示例来自《计算机程序的构造和解释中文版2》习题1.51.6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值