Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 对lambda求值的函数不能用于定义范围内的新函数_Scheme_R5rs - Fatal编程技术网

Scheme 对lambda求值的函数不能用于定义范围内的新函数

Scheme 对lambda求值的函数不能用于定义范围内的新函数,scheme,r5rs,Scheme,R5rs,在scheme中,您可以定义返回lambda表达式的函数,并使用它们定义新函数。例如,您可以编写此代码 (define (pow-iter base exp r) (if (= exp 1) r (pow-iter base (- exp 1) (* base r)))) (define (pow exp) (lambda (base) (pow-iter base exp base))) (define cubic (pow 3)) (cubic

在scheme中,您可以定义返回lambda表达式的函数,并使用它们定义新函数。例如,您可以编写此代码

(define (pow-iter base exp r)
  (if (= exp 1)
      r
      (pow-iter base (- exp 1) (* base r))))

(define (pow exp)
  (lambda (base)
    (pow-iter base exp base)))

(define cubic (pow 3))

(cubic 2)
这里有一个函数
pow
,它以指数为参数,求值为lambda函数,求值为给定基的n次方

但是,如果我们将其放在这样的范围内:

(define (do-cubic x)
  (define (pow-iter base exp r)
    (if (= exp 1)
        r
        (pow-iter base (- exp 1) (* base r))))

  (define (pow exp)
    (lambda (base)
      (pow-iter base exp base)))

  (define cubic (pow 3))

  (cubic x))

(do-cubic 2)
我犯了一个错误

pow:未定义;在初始化之前不能使用


为什么会发生此错误?有没有办法在不更改程序逻辑的情况下修复此错误?

此程序会引发相同的错误:

#lang r5rs
(let ()
  (define (foo x) (lambda (y) (+ 42 x)))
  (define bar (foo 1))
  (bar 2))

Output:
  foo: undefined;
  cannot use before initialization
出现错误的原因是“内部定义”被重写为
letrec
表达式。在计算初始值时,所有绑定都有效,因此允许相互递归定义

(letrec ((foo (lambda (x) (lambda (y) (+ 42 x))))
         (bar (foo 1)))
 (bar 2))
在R5R中,初始化表达式按未指定的顺序求值。这意味着在上面的第一个代码片段中,可以在
(define(foo x)…)
之前对
(define bar(foo 1))
进行求值。换句话说,在初始化
foo
之前需要
foo
的值

在Racket(
#lang Racket
)中,内部定义使用
letrec*
-语义(即,初始化表达式按照它们在代码中出现的顺序进行计算。因此程序运行时不会出错

还请注意,
#lang racket
中的
letrec
对应于
letrec*
在“R5RS”实现中的作用


有关
letrec
vs
letrec*
的更多信息,请参阅Racket it works中的

。@Renzo您的意思是它在
#!Racket
中工作。在
#!r5rs
中,即使在RacketVM下,也应该失败。它们是不同的语言。