关于lisp:除了“符号”之外,为什么Clojure还有“关键字”?

Why does Clojure have “keywords” in addition to “symbols”?

我从其他方面了解其他Lisps(特别是Scheme)。 最近我一直在读关于Clojure的文章。 我看到它有"符号"和"关键字"。 符号我很熟悉,但没有关键字。

其他Lisps有关键字吗? 关键字如何与除了具有不同符号(即:冒号)之外的符号不同?


这是关键字和符号的Clojure文档。

Keywords are symbolic identifiers that evaluate to themselves. They provide very fast equality tests...

Symbols are identifiers that are normally used to refer to something else. They can be used in program forms to refer to function parameters, let bindings, class names and global vars...

关键字通常用作轻量级"恒定字符串",例如对于哈希映射的键或多方法的分派值。符号通常用于命名变量和函数,除了在宏等中之外,将它们直接作为对象进行操作的情况较少见。但是没有什么可以阻止你在使用关键字的地方使用符号(如果你不介意一直引用它们)。

查看差异的最简单方法是在Clojure源中读取Keyword.javaSymbol.java。有一些明显的实现差异。例如,Clojure中的符号可以包含元数据,而关键字则不能。

除了单冒号语法之外,您还可以使用双冒号来创建名称空间限定的关键字。

1
2
3
4
user> :foo
:foo
user> ::foo
:user/foo

Common Lisp具有关键字,Ruby和其他语言也是如此。当然,它们在这些语言上略有不同。 Common Lisp关键字和Clojure关键字之间存在一些差异:

  • Clojure中的关键字不是符号。

    1
    2
    user> (symbol? :foo)  
    false
  • 除非您特别限定它们,否则关键字不属于任何命名空间:

    1
    2
    3
    4
    user> (namespace :foo)
    nil
    user> (namespace ::foo)
    "user"
  • (感谢Rainer Joswig为我提供了要看的东西的想法。)


    Common Lisp有关键字符号。

    关键字也是符号。

    1
    (symbolp ':foo) -> T

    什么使关键字特别:

    • :foo由Common Lisp reader解析为symbol关键字:: foo
    • 关键词评估自己:: foo - >:foo
    • 关键字符号的home包是KEYWORD包:keyword:foo - >:foo
    • 关键字从包KEYWORD导出
    • 关键字是常量,不允许分配不同的值

    否则关键字是普通符号。因此,关键字可以命名函数或具有属性列表。

    请记住:在Common Lisp中,符号属于一个包。这可以写成:

    • foo,当符号可在当前包中访问时
    • foo:bar,当从包BAR导出符号FOO时
    • foo :: bar,当符号FOO在包BAR中时

    对于关键字符号,这意味着:foo,keyword:foo和keyword :: foo都是相同的符号。因此通常不使用后两种符号。

    所以:foo被解析为在KEYWORD包中,假设在符号名称之前没有给出包名,默认情况下意味着KEYWORD包。


    关键字是评估自己的符号,因此您不必记住引用它们。


    对于关键字,当关键字为时,会计算并缓存哈希值
    首先构建。查找关键字作为哈希键时,它就是简单的
    返回预先计算的散列值。对于字符串和符号,哈希是
    在每次查找时重新计算。

    为什么相同的命名关键字始终相同,它们包含自己的哈希值。
    由于地图和集合中的搜索是通过散列键进行的,因此在大量搜索的情况下,搜索效率会提高,而不是搜索本身。


    :关键字也被许多集合特别处理,允许一些非常方便的语法。

    1
    (:user-id (get-users-map))

    是相同的

    1
    ((get-users-map) :user-id)

    这使得事情变得更加灵活