在 clojure 中,(= 'a 'a) 指的是“同一个原子”吗?

发布于 2024-09-18 17:37:47 字数 367 浏览 3 评论 0原文

在 Common LISP 的某些实现中,我们可以说以下表达式为

(eq 'a 'a)

true,因为 'a'a 是“相同的原子”。

这可能与实现相关,但似乎这个短语(在一本流行的 LISP 教学书中使用)假设相同值的原子存储在内存中的相同位置。

在Java中,两个具有相同值的interned字符串存储在内存中的相同位置。

现在 JVM 上的 Clojure 继承了 Java 的遗产,但是可以说 Clojure(在 JVM 上)中具有相同值的两个原子是同一个原子吗? (即Clojure的原子存储机制是如何工作的?)

In some implementations of Common LISP we can say that for the following expression

(eq 'a 'a)

Is true because 'a and 'a are the "same atom".

This may be implementation dependent, but it seems the phrase (used in a popular LISP teaching book) assumes that atoms of the same value are stored in the same location in memory.

In Java, two interned strings of the same value are stored in the same location in memory.

Now Clojure on the JVM inherits Java's legacy, but is it true to say that two atoms in Clojure (on JVM) having the same value are the same atom? (ie how does Clojure's atom storage mechanism work?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

痴骨ら 2024-09-25 17:37:47

首先,“原子”在 Clojure 中的含义与大多数其他 Lisp 中不同。请参阅 http://clojure.org/atoms

Clojure 的 = 函数使用基于平等。因此,即使两个对象存储在内存中的不同位置,具有相同值的两个对象也会=

要测试两个对象实际上是否是同一对象(位于内存中的同一地址),请使用 identical? 函数。

First, "atom" has a different meaning in Clojure than in most other Lisps. See http://clojure.org/atoms

Clojure's = function uses value-based equality. So two objects with equal values will be = even if they are stored in different locations in memory.

To test if two objects are actually the same object, at the same address in memory, use the identical? function.

望笑 2024-09-25 17:37:47

我认为 'a 和 'a 在底层是不同的 Java 对象。我相信这证实了这种怀疑:

user> (def foo 5)
#'user/foo
user> (System/identityHashCode 'foo)
578999228
user> (System/identityHashCode 'foo)
1724482638

如果您查看 Symbol ,您会看到符号由命名空间和名称组成,并且这些字符串必须是内部字符串。 Symbol.equals() 方法依赖于字符串实习生对这两个字符串进行身份检查。

I think 'a and 'a are going to be different Java objects under the hood. I believe this confirms that suspicion:

user> (def foo 5)
#'user/foo
user> (System/identityHashCode 'foo)
578999228
user> (System/identityHashCode 'foo)
1724482638

If you look at the actual implementation of Symbol in Clojure, you'll see that a symbol consists of a namespace and a name and those Strings MUST be interned strings. The Symbol.equals() method relies on doing identity checks on those two strings, relying on string intern.

傲性难收 2024-09-25 17:37:47

我将解释 Common Lisp 部分:

在 Common Lisp 中 (eq 'a 'a) 总是返回 T。

原因:在阅读时,读者查找 a,并且查找 a< /em> 它将查找相同的符号a。由于任何符号对其自身都是 EQ,因此表达式始终返回 T。

对于大多数类型的对象都是如此,但也有一些例外。例如,数字和字符在 Common Lisp 中并不是必需的 EQ。原因是效率。要比较它们是否是相同的数字或相同的字符,可以使用函数 EQL。

I'll explain the Common Lisp part:

In Common Lisp (eq 'a 'a) returns always T.

Reason: at read time, the reader looks up a, and for both a it will look up the same symbol a. Since any symbol is EQ to itself, the expression returns always T.

This is true for most types of objects, but with a few exceptions. Numbers and characters, for example, are not necessary EQ in Common Lisp. The reason for that is efficiency. To compare these if they are the same number or same character one can use the function EQL.

吾家有女初长成 2024-09-25 17:37:47

为了补充 Alex 和 Stuart 的答案,Clojure 中的符号无论何时 = 都不能变得相同?,主要是因为它们可能携带元数据。具有相同 .name.namespace 组件但元数据不同的两个符号将是 = 但不相同? 。

可以想象,可以这样安排事情,以便两个具有相同元数据、命名空间和名称的符号始终相同?一些符号=但不相同相同?),(2)与通常应该比较可能携带元数据的类型的值相等性(元数据对此没有贡献)的想法相反),而实际的指针相等应保留用于特殊情况(主要涉及互操作)。

请注意,Clojure 关键字是一种单独的类型,其中 = 实际上等同于 identical?。 (很明显他们不能附加元数据。)

To add to Alex's and Stuart's answers, Symbols in Clojure could not be made to be identical? whenever they are = mostly because they may carry metadata. Two Symbols which have the same .name and .namespace components but different metadata will be = but not identical?.

Things could conceivably be arranged so that two Symbols with the same metadata, namespace and name would always be identical?, but that is (1) two much hassle for no real gain (since you'd still have some Symbols = but not identical?), (2) contrary to the idea that types which may carry metadata should normally be compared for value equality (to which metadata does not contribute), whereas actual pointer equality should be reserved for special situations (mostly involving interop).

Note that Clojure Keywords are a separate type for which = is indeed equivalent to identical?. (So clearly they cannot have metadata attached.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文