请在 2024年Clojure调查! 中分享您的想法。

欢迎!有关Clojure如何工作的更多信息,请参见 关于页面

+1
编译器

Clojure中的关键词被缓存和内部化,以便

(identical? :a :a)

返回true。但符号不是

(identical? 'a 'a)

返回false。

有什么原因吗?

2 个回答

+4
 
最佳答案

符号是上下文相关的,同一个符号的不同实例可以有不同的元数据。

元数据是状态性的,并且与持久化的概念本质上是矛盾的。关键词不具有元数据,但具有快速的唯一性等价语义。
0

我相信部分原因是关键词为了在映射(以及可能的其他数据结构)中更高效地使用内存和查找性能而进行持久化。由于 Clojure 中的 = 在大多数情况下首先执行快速 identical? 检查,如果它们是相同的则返回 true。这使得它们在用作映射键时提供比其他值更好的性能特性,因为关键词经常被用于 Clojure 程序中。

尽管如此,关键词持久化在它们首次持久化时确实会有性能成本。对于关键词来说,这通常不是一个大问题,特别是对于大多数 Clojure 程序而言,那里使用的关键词集合相对较小。对于那些尝试将大量 JSON 文件中的各种 JSON 键字符串转换为 Clojure 关键词的人,这曾是一个性能问题。Clojure 在过去已经对这些用例进行了优化改进。我此刻没有 JIRA 工作项的单据,但如果有人感兴趣,我可以找到它们。

符号并不是旨在为这些用例进行性能优化的,如果尝试将它们用作映射键,从性能上讲可能会稍微差一点,但我相信这也意味着当遇到新的符号时,它们避免了持久化的性能成本。

在 Common Lisp 中有一些类似的历史,以及可能是某些其他 Lisp 家族语言。

...