Racket是多次运行的程序中的定义形式?

时间:2017-02-11 13:22:23

标签: recursion optimization racket

在Racket中,可以在另一个过程中定义过程和常量,例如:

(define (a a-list)
  (define something 10)
  (display a-list)
  (cond
    [(empty? a-list) (display "done")]
    [else
      (display a-list) (newline)
      (a (rest a-list))]))

打印列表然后取走第一个元素,然后再次打印列表,依此类推,直到列表为空。

在示例过程中,无论出于何种原因,值something都被定义为10。当程序递归时,Racket是否再次定义该值,或者它是否足够智能注意到该定义不会改变?

它也可能在先前调用的过程的堆栈空间上,如果这没有被优化,并且每个递归步骤会消耗更多的内存,具体取决于something定义的内容。例如,让我们在列表中说出一百万个数字,但从不改变数字。显然,如果该定义中的内容依赖于作为参数给出的列表,则不能简单地进行优化。

如果没有优化,最好不要在递归函数中包含太多define个形式,或者只消耗少量空间的形式?将它们放在程序之外会使它们可以从其他程序访问,即使只有一个程序使用它们。

1 个答案:

答案 0 :(得分:1)

每次调用过程时,define表达式都会被评估。考虑这个例子:

(define (test1)
  (define x (begin (display "Hello from test1 ") 10))
  x)

(test1)
=> Hello from test1 10
(test1)
=> Hello from test1 10
(test1)
=> Hello from test1 10

如果您希望过程中的值只被评估一次(当创建过程本身时),您可以将它放在过程之外的范围内,它仍然可以访问,因为{{1}在其词法环境中定义closure

lambda