内联定义函数与不内联函数定义有什么区别? [英] What is the difference between defining a function inline or not?

查看:178
本文介绍了内联定义函数与不内联函数定义有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究结构和实现计算机程序 ,在其中一章中,有一些代码用于计算数字的阶乘:

I'm working through the book Structure and implementation of computer programs and in one of the chapters there were some code used to calculate the factorial of a number:

(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)))

在本书的较早版本中,我了解到可以在这样的另一个函数中内联定义函数:

Earlier in the book I learned that I can define functions inline in another function like this:

(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-iterfactorial的范围之外是不可访问的,但是我想知道当我运行第二个版本的factorial时会发生什么吗?

I know that using the second approach fact-iter won't be accessible outside of the scope of factorial but I was wondering what happens actually when I run the second version of factorial?

是否定义了符号fact-iter的新本地绑定并创建了新函数,或者仅在程序编译时创建此绑定一次?

A new local binding for the symbol fact-iter gets defined and a new function created or this binding is created only once when the program compiles?

我来自Java背景,这对我来说还不清楚.

I'm coming from a java background and this is not yet clear for me.

推荐答案

它取决于Scheme的实现(有关策略,将在 SICP 的后续章节中进行讨论).从概念上讲,您对第二个定义的每次调用factorial都会定义/编译一个新函数.但是,一个好的编译器可以转换此代码,使其更像您的第一个定义.

It rather depends on the Scheme implementation (strategies for which are discussed in subsequent chapters of SICP). Conceptually, a new function gets defined/compiled in each call to factorial per your second definition of it. However, a good compiler can transform this code so that it's much more like your first definition.

由于此结构在Scheme中非常常见(编写循环的惯用方式是named- let结构,它也可以动态定义函数),因此Scheme编译器应该非常擅长进行此优化.实际上,您的示例对于优化程序而言很容易处理,因为内部函数的定义实际上并不依赖于外部函数所绑定的任何变量,因此可以按原样使用(只需更改名称)即可.

Since this construct is so common in Scheme (the idiomatic way of writing a loop being the named-let construct, which also defines functions on the fly), Scheme compilers should be pretty good at doing this optimization. And in fact your example is easy to handle for an optimizer since the inner function's definition does not actually depend on any variables bound by the outer function, so it can be lifted out almost as-is (only the name may have to be changed).

这篇关于内联定义函数与不内联函数定义有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆