【问题标题】:in Clojure, why have Strings, Keywords AND Symbols?在 Clojure 中,为什么有字符串、关键字和符号?
【发布时间】:2012-07-24 04:48:36
【问题描述】:

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

或者,既然与 Java 的互操作是 Clojure 必须具备的,那么至少要有 Java String 类型和 KeywordSymbol 数据类型。

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

【问题讨论】:

标签: types clojure symbols


【解决方案1】:

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

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

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

编辑:


您可以通过defing 将符号转换为关键字

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

关键字自己评估

【讨论】:

  • 这无助于为什么关键字和字符串必须分开。例如,在 Ruby 中,字符串和符号都是必需的,因为一个是可变的,另一个不是。为什么你不能只有关键字或字符串,而那个有查找自己的界面?
  • 我真的很喜欢关键字在地图中的表现以及这些类型的行为这一事实,但您也可以使用具有相同功能的字符串。关于实现可运行,也许我只是对同质性和“编写代码的代码”的东西没有足够深入的了解,因为我只看到像:(1)(def x +) (x 2 3) 和(2)(def x '+) (x 2 3) 做无论如何都是一样的(其中“+”代表任何函数名)
  • 我将添加更多关于这背后的设计决策
  • 也许我遗漏了一些东西,但我不明白使关键字与引用符号不同的情况。你不能用' 替换: 并去掉关键字吗?我误解了引用吗?
  • 我认为它专注于目标的明确性。关键字被设计为数据查找,符号被设计用于编译时查找。您可以保证只有一个关键字具有给定名称,但地图不存在该保证。我认为不只是扩展字符串的其他原因是由于关键字能够被命名空间以及由于自定义实习行为关键字的使用。
【解决方案2】:

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

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

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

【讨论】:

  • 我认为在一些较新版本的 JVM 中,如果对它们的所有引用都丢失了,则实习字符串有资格进行垃圾回收。我现在找不到可靠的来源,所以我可能是错的。无论哪种方式,您都不应该经常将字符串与== 进行比较,这是绝对正确的。
  • 有趣,我不知道 JVM 的实习字符串(你可能发现我不是 Java 人,我从完全不同的背景来到 Clojure,也许这就是我的方式发现一些受 Java/JVM 影响的语言设计决策很奇怪 :) ) ...也许我应该在 Clojure 之前开始使用 Scheme,以获得关于 Lisps 的更好“直觉”...
猜你喜欢
  • 2010-12-04
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 2012-01-30
相关资源
最近更新 更多