Scheme 为什么在编译器看到所有过程之前都必须定义它们?

Scheme 为什么在编译器看到所有过程之前都必须定义它们?,scheme,racket,r6rs,Scheme,Racket,R6rs,例如,查看以下代码(来自tspl4): 如果我在scheme中运行此程序 #!r6rs (import (rnrs)) (define proc1 (lambda (x y) (proc2 y x))) 我得到这个错误: expand: unbound identifier in module in: proc2 …此代码运行良好,但: #!r6rs (import (rnrs)) (define proc2 +) (define proc1 (lambda (x

例如,查看以下代码(来自tspl4):

如果我在scheme中运行此程序

#!r6rs
(import (rnrs))

(define proc1
  (lambda (x y)
    (proc2 y x)))
我得到这个错误:

expand: unbound identifier in module in: proc2
…此代码运行良好,但:

#!r6rs
(import (rnrs))

(define proc2
  +)

(define proc1
  (lambda (x y)
    (proc2 y x)))

(display (proc1 2 3)) ;output: 5

它们都必须在同一模块中定义(=r6rs行话中的“库”)。但是你可以按照你想要的任何顺序来定义它们——例如,在你的最后一次剪贴中,你可以交换这两个定义,它会很好地工作。但是请注意,您不能将定义放在
显示
行之后——这是一个使用其值的表达式,因此如果您将函数定义移到它之后,您将得到一个运行时错误。(请注意,这是一个运行时错误,而不是编译时错误。)

如果是运行时错误,那么为什么我的第一个程序会崩溃?它甚至不运行proc1,那么为什么它需要proc2呢?tspl4说它不应该崩溃。把它看作是一个链接问题:PLT实际上编译了你的代码,而你有一个编译器不知道的引用。
#!r6rs
(import (rnrs))

(define proc2
  +)

(define proc1
  (lambda (x y)
    (proc2 y x)))

(display (proc1 2 3)) ;output: 5