我正在读这本书计算机程序的结构和实现 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html在其中一章中,有一些代码用于计算数字的阶乘:
(define (factorial n)
(fact-iter 1 1 n))
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product)
(+ counter 1)
max-count)))
在本书的前面,我了解到我可以在另一个函数中内联定义函数,如下所示:
(define (factorial n)
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product)
(+ counter 1)
max-count)))
(fact-iter 1 1 n))
我知道使用第二种方法fact-iter
在范围之外将无法访问factorial
但我想知道当我运行第二个版本时实际发生了什么factorial
?
符号的新本地绑定fact-iter
被定义并创建一个新函数,还是在程序编译时仅创建一次此绑定?
我来自java背景,这对我来说还不清楚。
它更取决于计划的实施(其策略将在后续章节中讨论)SICP)。从概念上讲,每次调用都会定义/编译一个新函数factorial
根据你对它的第二个定义。但是,一个好的编译器可以转换此代码,使其更像您的第一个定义。
由于这种构造在Scheme中非常常见(编写循环的惯用方式是命名的-let
构造,它还动态定义函数),Scheme 编译器应该非常擅长进行这种优化。事实上,您的示例对于优化器来说很容易处理,因为内部函数的定义实际上并不依赖于外部函数绑定的任何变量,因此它几乎可以按原样取出(只有名称可能需要更改) 。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)