在DrRacket中,当我将语言设置为R5RS并运行以下代码时:
(lambda (x) z)它在没有错误的情况下运行并返回#<procedure>。这对我来说很有意义;lambda表单定义了一个尚未评估身体的过程,因此返回该过程。
或者,当我使用球拍语言方言时,我会得到以下错误:
z: unbound identifier in module in: z我不明白为什么球拍会产生这个错误。我的意思是,当然,我看到z是没有定义的,但是我对评估模型的理解是,函数的主体在函数定义时没有被求值。这与R5RS的结果是一致的,但与球拍的结果不一致。确切地说,球拍在这里做什么?是否在代码正文中以某种方式“窥视”以查看是否定义了变量?评估模型与导致这种不同行为的R5RS有什么不同?
发布于 2015-04-08 18:40:58
#lang文件是模块。在文档中详细描述了如何扩展和评估模块的规范。经过一番挖掘,我发现了这张纸条:
任何标识符都不能在单个模块中的任何阶段级别上多次导入或定义。必须导入或定义每个导出标识符。任何表达式都不能引用顶级变量。
最后一句“没有表达式可以引用顶级变量”。意味着所有变量都必须绑定。
相反,在repl中输入的表达式不是模块,而是“外部”任何模块的表达式。对未绑定变量的引用变为对顶级变量的引用。计算表达式时,顶级变量的值将在当前命名空间中查找。如果在查找时,变量没有关联的值,则会发出错误信号。
repl使用这个复杂的规则来允许相互递归函数的定义,一次定义一个。
有关REPL的更多信息,请参见:https://gist.github.com/samth/3083053
发布于 2015-04-08 18:25:28
源文件在球拍中
#lang racket
(define f (lambda (x) z))结果:
z: unbound identifier in module in: zREPL互动:
Welcome to DrRacket, version 6.1.1 [3m].
Language: racket; memory limit: 128 MB.
> (define f (lambda (x) z))
> 没有错误。
定义了z的源文件:
#lang racket
(define f (lambda (x) z))
(define z 5)没有错误。
因此,Racket确保定义源文件中的所有变量,而不对REPL代码做出相同的保证。我只能认为这是一件好事,因为它可以防止源文件中的错误。
https://stackoverflow.com/questions/29520771
复制相似问题