7

不使用如何letrec实现set!

在我看来,这set!是一种命令式编程结构,使用它会失去函数式编程的好处。

4

2 回答 2

10

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

于 2011-12-11T23:42:55.403 回答
10

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

这里要理解的关键是:函数式编程与接口有关,而不是与实现有关。如果该代码本身无法观察到任何副作用,则该代码是有效的——即使副作用实际上是在幕后发生的。即,如果您多次检查同一变量的同一绑定的值,您将得到相同的值——即使该值在幕后是通过使用set!.

在 的情况下letrec,这里有一个小问题:如果对 中的任何绑定的评估letrec导致另一个绑定被取消引用,则结果是未定义的。所以,这段代码的结果是未定义的:

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

fooletrec 主体中的值未定义。另一方面,以下结果被定义:

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

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

于 2011-12-12T23:02:15.207 回答