方案中标识符和符号之间的区别?

Difference between an identifier and symbol in scheme?

我试图了解 Scheme 元循环求值器如何以不同于符号数据的方式处理引用表达式。

已接受的答案 Stack Overflow 问题 What exactly is a symbol in lisp/scheme? 定义了 Scheme 中的 "symbol" 数据对象:

In Scheme and Racket, a symbol is like an immutable string that happens to be interned

接受的答案是这样写的,在Scheme中,标识符和符号之间有一个内置的对应关系:

To call a method, you look up the symbol that corresponds to the method name. Lisp/Scheme/Racket makes that really easy, because the language already has a built-in correspondence between identifiers (part of the language's syntax) and symbols (values in the language).

为了理解对应关系,我阅读了 Scheme 及其实现简介 中的 "A Note on Identifiers" 页,其中说

Scheme identifiers (variable names and special form names and keywords) have almost the same restrictions as Scheme symbol object character sequences, and it's no coincidence. Most implementations of Scheme happen to be written in Scheme, and symbol objects are used in the interpreter or compiler to represent variable names.

基于以上,我想知道我对以下会话中发生的事情的理解是否正确:

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 ]=>
  1. 第一个 define 语句是求值器捕获的特殊形式,它为符号 a 创建了一个绑定到全局环境中的复合过程对象。

  2. 在顶层写a会导致求值器接收符号对象 'a,它求值为复合- 'a 指向全局环境中的过程对象。

  3. 在顶层写(quote a)会导致求值器收到一个符号列表 ('quote 'a));此表达式是计算器捕获的特殊形式,计算结果为引用的表达式,即符号对象 'a.

  4. 写入 (eval a (the-environment)) 会导致计算器收到一个符号列表 ('eval 'a ...)(忽略环境)。求值器查找 'eval,生成 eval 编译过程对象,查找 'a,生成复合过程。最后,顶层求值器将 eval 过程应用于它的参数,因为复合过程是自求值的(在 Scheme48 中不是真的),表达式的最终值是复合过程本身。

  5. 写入 (eval (quote a) (the-environment)) 会导致计算器收到一个符号列表 ('eval ('quote 'a) ...)。求值器对 'eval 执行查找,这会产生 eval 编译过程对象。它计算表达式 ('quote 'a) 产生符号对象 'a。最后,顶级评估器将评估过程应用于 'a,这是一个符号对象,因此调用产生复合过程的环境查找。

这个解释是否正确地(在高层次上)描述了 Scheme 解释器如何区分语言中的符号对象和标识符?这些描述是否存在根本性的误解?

R6RS Scheme 报告,在 4.2 Lexical Syntax 中,使用术语 identifer 来指代字符级语法。也就是说,粗略地说,identifier 的意思类似于当表达式成为对象时从中构造符号的词法标记。然而,在文本的其他地方,identifier 似乎被随意用作 symbol 的同义词。例如。 "Scheme allows identifiers to stand for locations containing values. These identifiers are called variables."(1.3 变量和绑定)。基本上,关于这个术语的规范似乎是松散的。根据上下文,标识符要么与符号(对象)相同,要么 <identifier>:来自词法句法的语法类别。

在这样的句子中,某个字符可能会或可能不会出现在标识符中,上下文显然是词法语法,因为符号对象是原子而不是字符串;它不包含任何东西。但是,当我们谈论表示内存位置(作为变量)的标识符时,这就是符号;我们已经解决了什么样的标记可以在文本源代码中生成符号的问题。

问题中链接的 Scheme 及其实现简介 教程使用了它自己的 identifier 的特殊定义,它位于与 Scheme 语言不一致。这意味着标识符是"variable names, and special form names and keywords"(因此不是变量名的符号不是标识符,规范不支持)。

ObPreface: 提前向您道歉,告诉您您已经知道的事情!

你的第一句话就给我提出了很大的 XY 问题。你写"I am trying to understand how the Scheme meta-circular evaluator handles quoted expressions differently than symbolic data."你写的"the Scheme meta-circular evaluator"是什么意思?另外,"symbolic data" 是什么意思?这两个术语都让我觉得您想问更多 high-level 个问题。

无论如何,您的标题暗示了一个关于标识符和符号之间区别的问题。区别是这样的:

"Identifiers"是句法范畴。也就是说,假设我们获取一个文本文件并将其分解为标记。其中一些标记将是 left-parens。有些会是 right-parens。有些将是数字。有些将是标识符。每种语言都有自己的一组句法类别,但其中许多使用名称 "identifier" 表示 "word-like thing that can usually be a function name or a variable name or whatever."

另一方面,

"Symbols" 是 Scheme 和 Lisp 系统中的一种特殊值。 Scheme 有很多不同类型的值:数字、布尔值、字符串、对、符号等等。

在Scheme中,开发parser/interpreter/compiler/whatever时,用符号(值)来表示标识符(句法实体)非常方便。具体来说,"quote" 具有将某些宿主语言标记序列转换为符号、数字、字符串和布尔值列表的特殊能力。你不需要利用这一点,但它消除了很多代码。