Stack Overflow问题“Lisp/Scheme中的符号到底是什么?”的被接受答案定义了Scheme中的“符号”数据对象:
在Scheme和Racket中,符号类似于不可变的字符串,恰好被内部化。
被接受的答案写道,在Scheme中,标识符和符号之间存在内置的对应关系:
要调用一个方法,您需要查找与该方法名称对应的符号。Lisp/Scheme/Racket使这变得非常容易,因为语言已经在标识符(语言语法的一部分)和符号(语言中的值)之间建立了内置的对应关系。
为了理解这种对应关系,我阅读了《Scheme及其实现简介》中的{{link2:“关于标识符的说明”}}页面。
Scheme标识符(变量名、特殊形式名和关键字)几乎具有与Scheme符号对象字符序列相同的限制,这不是巧合。大多数Scheme实现恰好是用Scheme编写的,并且符号对象在解释器或编译器中用于表示变量名。
基于上述内容,我想知道我对以下会话中发生的事情的理解是否正确:
user@host:/home/user $ scheme
MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Copyright (C) 2011 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Image saved on Sunday February 7, 2016 at 10:35:34 AM
Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118 || Edwin 3.116
1 ]=> (define a (lambda (i) (+ i 1)))
;Value: a
1 ]=> a
;Value 13: #[compound-procedure 13 a]
1 ]=> (quote a)
;Value: a
1 ]=> (eval a (the-environment))
;Value 13: #[compound-procedure 13 a]
1 ]=> (eval (quote a) (the-environment))
;Value 13: #[compound-procedure 13 a]
1 ]=>
第一个
define
语句是由求值器捕获的特殊形式,它在全局环境中创建了一个将符号a
绑定到复合过程对象的绑定。在顶层写下
a
会使求值器收到符号对象'a
,这将计算为在全局环境中指向'a
的复合过程对象。在顶层写下
(quote a)
会使求值器收到符号列表('quote 'a))
;这个表达式是求值器捕获的特殊形式,它将计算为引用的表达式,即符号对象'a
。写下
(eval a (the-environment))
会使求值器收到符号列表('eval 'a ...)
(忽略环境)。求值器执行查找'eval
,得到eval编译过程对象,查找'a
,得到复合过程。最后,顶层求值器将eval过程应用于其参数,由于复合过程是自求值的(在Scheme48中不是),因此表达式的最终值是复合过程本身。写下
(eval (quote a) (the-environment))
会使求值器收到符号列表('eval ('quote 'a) ...)
。求值器执行查找'eval
,得到eval编译过程对象。它计算表达式('quote 'a)
,这将产生符号对象'a
。最后,顶层求值器将eval过程应用于'a
,它是一个符号对象,因此调用环境查找,得到复合过程。
read
函数来扫描文本并生成数据结构,然后纯粹地解释该数据结构。 只有在从头开始编写Scheme实现时才需要自己处理这些问题;但即使那样,你也要以同样的方式将读取与解释分开处理。 - Kaz