【发布时间】:2016-11-20 02:43:47
【问题描述】:
以下面的函数定义为例:
(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 是“保留名称”?
【问题讨论】:
-
你不能,或者至少不应该能,因为内部
defines 可能只出现在define、lambda、@987654328 正文的开头@、let*、letrec等(根据 r5rs)。 -
@manualcrank 但是为什么呢?过早的引用可以使代码更全面,我认为这是一个很大的优势。允许
define出现在包含define的正文中的任何地方有什么缺点? -
某些方案可能确实允许您的第一个定义,但在定义之前调用
bar时会引发错误。 -
例如 Racket 将允许您定义
(define (foo) (bar) (define (bar) (display "bar")) (bar))。但是请注意,在其定义之后额外的(bar); Racket 在一系列内部定义之后坚持至少一个表达式。 Chez Scheme,OTOH,在编译时拒绝这个和你原来的foo。
标签: scheme lisp language-design sicp mit-scheme