2024 年 Clojure 状态调查!中分享您的想法。

欢迎!有关此功能的使用方法,请参阅关于页面获取更多信息。

+1 投票
编译器

Clojure 中的关键字进行缓存和重入以便

(identical? :a :a)

返回 true。但符号不是

(identical? 'a 'a)

返回 false。

有什么原因吗?

2 个答案

+4 投票

被选中
 
最佳答案

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

元数据是状态性的,与重入的概念存在冲突。关键字没有元数据,但具有快速的实体等价语义。
0 投票

我认为答案的一部分在于Clojure中关键字(keywords)是为了更有效的内存使用和映射(maps)中的键查找性能而内化的,因为Clojure中大多数情况下的=操作首先进行快速检查identical?,如果它们相同则返回true。这使它们在用作映射键时比其他值具有更好的性能表现,而在Clojure程序中,关键字通常用作映射键。

话虽如此,关键字内化确实会在首次内化时产生性能成本。对于关键字来说,这通常不是一个很大的问题,特别是在Clojure程序中使用的关键字集合相对较小的情况下。当人们读写大量JSON文件并将各种JSON键字符串转换为Clojure关键字时,这将是一个性能问题。Clojure在过去已经对这些用法案例进行了改进。我目前没有JIRA工单在手,但如果有兴趣了解这些,我可以找到它们。

符号不是为这些用例进行性能优化的,如果你尝试将它们用作映射键,可能会稍微影响性能,但我相信这也避免了在遇到新符号时的内化性能成本。

在Common Lisp中存在类似行为的历史,以及其他一些Lisp家族语言。

...