24

我正在学习 Clojure,我无法理解一些语言设计决策:为什么像 Clojure 这样具有不可变字符串的语言也需要关键字和符号数据类型?字符串不能只有可选的名称空间和元数据以及所有这些东西吗?对于不可变字符串比较也可以是身份基础,不是吗?

或者,由于与 Java 的互操作是 Clojure 必须具备的,因此至少具有 Java String 类型和 KeywordSymbol 数据类型。

我发现这个字符串/关键字/符号“三分法”特别奇怪,因为 Clojure 似乎非常关注“纯度”并在其他方面保持简单。

4

2 回答 2

16

他们在语言中扮演着非常不同的角色:

  • Vars 用于给事物命名。它们实现runnable并且可以直接用于调用函数。您不能运行字符串。
  • 关键字本身就是名称,并在地图中查找自己。它们确实帮助 Clojure 保持其“数据驱动”的风格。字符串没有实现在地图中查找自身所需的接口。
  • 字符串只是字符串。他们只做他们需要做的,仅此而已。

Clojure 设计的核心原则之一是拥抱您的主机平台,因此在 Clojure 中字符串是 Java 字符串,您永远不需要将 Java 字符串包装在一些convert-to-clojure-string功能以使其进入 Clojure 生态系统。这需要使用未修改的 Java 字符串以及数字类型。关键字和符号是 Clojure 添加的新结构,因此只需让它们以一种有用的方式从 Java 生态系统的其余部分访问即可。符号和关键字只需作为实现接口的类即可访问。一开始人们认为,为了让一种新语言在 JVM 生态系统中取得成功,它需要完全拥抱 Java 并最大限度地减少“阻抗不匹配”(对于流行语感到抱歉),即使这需要在语言中添加更多内容。没有这个目标就需要。

编辑:


您可以通过将符号转换为def自身来将其转换为关键字

user> a
; Evaluation aborted.
user> :a
:a
user> (def a 'a)
#'user/a
user> a
a
user> 

关键字评估自己

于 2012-07-25T17:48:44.873 回答
4

我认为 Clojure 更看重“实用性”(如果这是正确的词),而不是“纯度”。这可以从事实上看出,Clojure 除了列表之外还有映射、向量和集合的语法,并且正在使用它来定义语言。在更关注纯度 (IMO) 的 Scheme 中,您只有列表的语法。

正如 Arthur Ulfeldt 指出的那样,字符串、关键字和符号都有其预期的用例。并且按预期使用它们可以更轻松地阅读 Clojure 代码。它类似于 HTML 5 中发生的事情,它添加了语义标记。像<article>and之类的东西<section>,你可以用HTML 4 中的<div class="article">and来表示。<div class="section">

哦,您只通过身份比较字符串是错误的。这保证仅适用于实习字符串。而且你不想实习太多的字符串,因为它们存储在所谓的 permgen 中,它的大小非常有限,而且从不被垃圾收集。

于 2012-07-25T19:56:51.213 回答