如何在不使用“set!”的情况下实现“letrec”?

时间:2011-12-11 23:35:51

标签: variables scheme language-implementation letrec

如何在不使用letrec的情况下实施set!

在我看来,set!是一种命令式编程结构,通过使用它,人们就失去了函数式编程的好处。

2 个答案:

答案 0 :(得分:9)

我知道我们通常会要求复制内容,但对您的问题没有简短的答案。 http://www.cs.indiana.edu/~dyb/pubs/fixing-letrec.pdf

答案 1 :(得分:9)

没有。仅仅因为功能特性是在幕后使用命令式代码实现的,这并不能使该功能成为必需。我们的计算机器势在必行;所以在某些时候,所有功能代码都必须通过翻译成命令式代码来实现!

这里要理解的关键是:函数式编程属于接口,而不属于实现。如果代码本身无法观察任何副作用,即使副作用实际上发生在幕后,一段代码也是有用的。也就是说,如果你多次检查同一个变量的相同绑定的值,你将得到相同的值 - 即使幕后的那个值是通过set!使用的。

letrec的情况下,这里有一点点:如果对letrec中的任何绑定的评估导致另一个绑定被解除,则结果是未定义的。所以,这段代码的结果是未定义的:

(letrec ((foo bar)
         (bar 7))
  (cons foo bar))

letrec主体中foo的值未定义。另一方面,定义了以下结果:

(letrec ((foo (lambda () bar))
         (bar 7))
  (cons (foo) bar))

这是因为评估lambda会捕获对bar的引用,但是直到在正文中执行闭包时才会查找实际值。