什么是lisp / scheme中的符号?

时间:2012-01-13 06:08:02

标签: lisp scheme racket

为了全能的爱,我还没有理解符号'iamasymbol的目的。我理解数字,布尔值,字符串...变量。但是符号对于我的小思维思维来说太过分了。我究竟用它做什么用的?它们应该如何在程序中使用?我对这个概念的掌握是失败的。

5 个答案:

答案 0 :(得分:29)

符号是一个具有简单字符串表示形式的对象(默认情况下)保证实习;也就是说,任何两个写成相同的符号都是内存中的同一个对象(引用相等)。

为什么Lisps有符号?好吧,它主要是Lisps将自己的语法作为语言的数据类型嵌入的事实。编译器和解释器使用符号来表示程序中的标识符;由于Lisp允许您将程序的语法表示为数据,因此它提供符号,因为它们是表示的一部分。

除此之外它们有什么用处?嗯,有几点:

  • Lisp通常用于实现嵌入式特定于域的语言。许多用于此的技术来自编译器世界,因此符号在这里是一个有用的工具。
  • Common Lisp中的宏通常涉及比这个答案提供的更详细的符号处理。 (尽管特别是,为宏扩展生成唯一标识符要求能够生成一个保证永远不会与其他符号相等的符号。)
  • 固定枚举类型更好地实现为符号而不是字符串,因为符号可以通过引用相等来进行比较。
  • 您可以构建许多数据结构,从而可以通过使用符号和引用相等来获得性能优势。

答案 1 :(得分:28)

在Scheme和Racket中,符号就像一个不可变的字符串恰好被实现,因此符号可以与eq?进行比较(快速,基本上是指针比较)。符号和字符串是单独的数据类型。

符号的一个用途是轻量级枚举。例如,可以说方向是'north'south'east'west。你当然可以使用字符串来达到同样的目的,但效率会稍差。使用数字是个坏主意;尽可能以明显和透明的方式表示信息。

另一个例子,SXML是使用列表,符号和字符串表示XML。特别是,字符串表示字符数据,符号表示元素名称。因此,XML <em>hello world</em>将由值(list 'em "hello world")表示,可以更紧凑地编写'(em "hello world")

符号的另一个用途是作为键。例如,您可以将方法表实现为将符号映射到实现函数的字典。要调用方法,请查找与方法名称对应的符号。 Lisp / Scheme / Racket使真正变得容易,因为语言已经在标识符(语言的语法的一部分)和符号(语言中的值)之间具有内置的对应关系。这种对应使得支持变得容易,它实现了用户定义的语言语法扩展。例如,可以使用“方法名称”(由类系统定义的语法概念)与符号之间的隐式对应关系,将类系统实现为宏库:

(send obj meth arg1 arg2)
=>
(apply (lookup-method obj 'meth) obj (list arg1 arg2))

(在其他Lisps中,我所说的大部分都是真实的,但还有其他一些事情需要了解,比如包和功能与可变插槽,IIRC。)

答案 2 :(得分:7)

lisp中的符号是人类可读的标识符。他们都是单身人士。因此,如果您在代码中的某处声明'foo然后再次使用'foo,它将指向内存中的相同位置。

样本使用:不同的符号可以代表棋盘上的不同部分。

答案 3 :(得分:5)

符号只是值的特殊名称。值可以是任何值,但该符号用于每次引用相同的值,并且此类事物用于快速比较。正如你所说的那样,你在思考它们,它们就像C中的数字常量,这就是它们通常被实现的方式(内部存储的数字)。

答案 4 :(得分:3)

来自计算机程序的结构和解释第二版,作者:Harold Abelson和Gerald Jay Sussman 1996:

  

为了操纵符号,我们需要在我们的语言中使用新元素:   引用数据对象的能力。假设我们要构建列表   (a b)。我们无法用(列出一个b)完成这个,因为这个表达式   构造a和b的值的列表而不是符号本身。   这个问题在自然语言的背景下是众所周知的   和句子可以被视为语义实体或字符   字符串(句法实体)。自然语言中的常见做法是使用引号来表示要处理单词或句子   字面意思是一串字符。例如,“约翰”的第一个字母是   显然是“J。”如果我们告诉某人“大声说出你的名字”,我们希望听到   那个人的名字。但是,如果我们告诉某人“大声说出你的名字”,   我们希望听到“你的名字”这个词。注意我们被迫窝   用引号来描述别人可能会说的话。     我们可以按照相同的做法来识别列表和符号   被视为数据对象而不是要评估的表达式。   但是,我们的引用格式与自然语言的格式不同   我们放置一个引号(传统上,单引号')   仅在要引用的对象的开头。我们可以在Scheme语法中使用它,因为我们依赖空格和括号来分隔   对象。因此,单引号字符的含义是引用   下一个对象。     现在我们可以区分符号及其值:

{{1}}
  

包含符号的列表看起来就像我们语言的表达式:

{{1}}

示例:符号分化