了解MIT Scheme中的块结构

时间:2016-11-20 02:43:47

标签: scheme lisp language-design sicp mit-scheme

将以下函数定义作为我的示例:

(define (foo)
  (bar)
  (define (bar)
    (display "bar")))

这会产生错误:;Premature reference to reserved name: bar。相反,以下两个定义是合法的。请注意,我在两者中都使用了过早的引用。

(define (foo)
  (bar))
(define (bar)
  (display "bar"))

(define (foo)
  (define (bar)
    (display "bar"))
  (bar))

我的问题是:在使用块结构时,为什么我不能过早地引用当前未定义的函数?为什么bar是"保留名称"?

1 个答案:

答案 0 :(得分:1)

你可以引用它,但你不能使用仍未定义的内容。

Racket让您定义

(define (foo) 
  (bar)                    ; here the future error
  (define (bar) 
      (display "bar")) 
  (bar))

但是当您尝试使用消息

来调用(foo)时出错
    bar: undefined;
cannot use before initialization

所以, 这里涉及某个时间轴,某些排序;根据他们在定义中的文字定位,有些事情在别人面前完成。考虑这个进一步的Racket REPL互动:

> (define (foo) (baz) (define (bar) (display "bar")) (bar))
> (foo)
. . baz: undefined;
 cannot reference an identifier before its definition
> (define (baz) '())
> (foo)
bar

REPL有自己的时间表。但是,每个Scheme实现都可以用自己的方式处理REPL的这个方面。