Vul*_*tan 4 lambda scheme racket r5rs
在DrRacket中,当我将语言设置为R5RS并运行以下代码时:
(lambda (x) z)
Run Code Online (Sandbox Code Playgroud)
它运行没有错误并返回#<procedure>
.这对我来说很有意义; lambda表单定义了一个尚未对其主体进行求值的过程,以便返回该过程.
或者,当我使用Racket语言方言时,我收到以下错误:
z: unbound identifier in module in: z
Run Code Online (Sandbox Code Playgroud)
我不明白为什么Racket会产生这个错误.我的意思是,当然我看到这z
是未定义的,但我对评估模型的理解是在函数定义时不评估函数体.这与R5RS结果一致,但与Racket结果无关.什么是球拍在这里做的,确切地说?是否在代码正文中以某种方式"窥视"以查看变量是否已定义?R5RS的评估模型有什么不同导致这种不同的行为?
Racket 中的源文件
#lang racket
(define f (lambda (x) z))
Run Code Online (Sandbox Code Playgroud)
结果:
z: unbound identifier in module in: z
Run Code Online (Sandbox Code Playgroud)
REPL 交互:
Welcome to DrRacket, version 6.1.1 [3m].
Language: racket; memory limit: 128 MB.
> (define f (lambda (x) z))
>
Run Code Online (Sandbox Code Playgroud)
没有错误。
定义了 z 的源文件:
#lang racket
(define f (lambda (x) z))
(define z 5)
Run Code Online (Sandbox Code Playgroud)
没有错误。
因此,Racket 确保源文件中的所有变量都已定义,而不对 REPL 代码做出相同的保证。我只能认为这是一件好事,因为它可以防止源文件中的错误。
一个#lang
文件是模块.有关如何扩展和评估模块的规范在文档中有详细描述.经过一番挖掘,我发现了这个说明:
在单个模块中的任何阶段级别都不能导入或定义多个标识符.必须导入或定义每个导出的标识符.没有表达式可以引用顶级变量.
最后一句"没有表达式可以引用顶级变量".意味着必须绑定所有变量.
相比之下,在repl中输入的表达式不是模块,而是在任何模块"外部"的表达式.对未绑定变量的引用将成为对顶级变量的引用.在计算表达式时,将在当前名称空间中查找顶级变量的值.如果在查找时,变量没有关联值,则会发出错误信号.
repl使用这个复杂的规则,以允许定义相互递归函数,一次定义一个.
有关REPL的更多信息,请参阅:https: //gist.github.com/samth/3083053
归档时间: |
|
查看次数: |
1623 次 |
最近记录: |