请在2024 状态 Clojure 问卷调查!分享您的想法。

欢迎!请查看关于页面了解更多关于其工作方式的信息。

0
打印
编辑

Clojure 映射的序列表示是否无歧义地定义?如果我为 Clojure 映射计算'pr-str'的 CID,它是唯一的吗?

CID 是什么?
它是内容的一个摘要。
比如 SHA-256,或者任何摘要函数,都无关紧要。
我想知道 Clojure 映射提供给摘要函数时是否可能有非唯一的哈希值。
```(sha-256 (pr-str {:one 1 :two 2}))```

现在我将映射想象成一个键值向量集

```#{{:one 1} {:two 2}  }```

我在我的代码中首先编写了 :one。
但它总是在 :two 之前出现吗?

如果运行上述代码,它是否会始终返回一个唯一的值?
by
我想Clojure的集合是配备了特殊的`bind`或`>>=`运算符的集合,该运算符可以使使用集合中的任一元素时返回绑定给该元素的任何内容。

({:one 1 :two 2} :one) => 1
by
https://www.reddit.com/r/Clojure/comments/foqt7o/when_and_why_would_you_want_to_use_sorted_maps/

我认为我将为了“序列化可预测性”而使用`sorted-map`,当集合的通用唯一身份受威胁时。

碰巧JSON也是无序的。
by
https://groups.google.com/g/golang-nuts/c/opEBtevDCyI

嗯嗯。感觉有点奇怪,那些应该跨越运行时存在的数据结构在缺失有关序列化协议的额外信息的情况下,其序列化形式是不可比较大小的。
by
我可能会使用向量。
by
(本消息假设您希望计算一个具有以下性质的哈希/摘要函数 D:对于任意两个无序集合 s1 和 s2,如果 (= s1 s2) 为真,则 (= (D s1) (D s2)) 也为真。
类似地,对于无序的 Clojure 映射也是如此。)

请注意,完全有可能开发出适用于无序对象(如无序集合和 Clojure 映射)的确定性的摘要/哈希函数。事实上,`clojure.core/hash` 就是这样一个函数。这样的函数必须始终产生相同的结果,不管其元素的顺序(对于集合)或键/值对的顺序(对于 Clojure 映射)。这给函数的计算方式带来了限制,并且许多用于摘要的函数 _不适用_ 于该目的。

如果您想要使用一种哈希/摘要函数,改变作为输入传递给它的元素的顺序会导致该函数的输出改变,那么我建议您得到的结果可能不是您想要的。

2 个答案

+1
by
selected by
 
最佳答案

映射(除了排序映射外)是无序的,并且可能会根据 Clojure 版本、JVM 版本以及您可能在 Clojure 打印系统中安装的任何自定义项打印不同的顺序。

在运行时,同一个映射实例将始终以相同的顺序打印其元素 - 这就是您的唯一保证。

by
以下说法是否相同?

'(into [] a-map)

换句话说,“无序映射的向量表示”是否未指定?
这是一个同样的问题——为了添加到向量中,地图元素是按照什么顺序被访问的?没有定义的顺序。
0

如果我对clojure地图中'pr-str'的CID进行计算,它是唯一的吗?
我想知道 Clojure 映射提供给摘要函数时是否可能有非唯一的哈希值。

这取决于摘要,而不是地图,这与Clojure有关,或者您使用了`pr-str`。
按照定义,任何合理的摘要都是一种损耗函数,因此它总是允许冲突,即使某些摘要的概率极小。

我在我的代码中首先编写了 :one。
但它总是在 :two 之前出现吗?

哈希集合/映射的顺序是未定义的。但对于相同的对象来说,它是相同的。
然而,即使内容相同,它们对于不同的对象可能会有所不同

user=> (mapv hash [0 0.])
[0 0]
user=> (pr-str (hash-map 0 0 0. 0))
"{0 0, 0.0 0}"
user=> (pr-str (hash-map 0. 0 0 0))
"{0.0 0, 0 0}"

如果运行上述代码,它是否会始终返回一个唯一的值?

根据上述内容,这并不能保证。对于像摘要这样的损耗函数,绝对不能保证。

我设想Clojure映射是带有特殊`bind`或`>>=`操作符的集合,该操作符使得使用集合的一个元素调用它时返回绑定到该元素的内容。

这似乎与问题无关。但不是的,在Clojure的集合和映射方面,没有特别之处,Clojure也不具有操作符。
Clojure中的集合和映射,与一些其他事物相关,是可调用的——就是这样简单。


编辑了
摘要冲突几乎是不可能发生的。所以我不会担心这个。
我担心的是“双重摘要结果”的反面情况,这在具有两个条目的映射中可能与投掷硬币得到正面同样可能。

编辑
"这似乎与问题中的其余部分无关。但是,在这个方面,Clojure中的集合或映射并没有什么特殊之处,Clojure也没有操作符。
Clojure中的集合和映射(以及其他一些事物)可以调用——就这么简单。

我只是在描述一个关于正在发生的事情的理论模型。这是在我有限的Clojure内部和性能关注下所能想到的最佳方案。

我认识到Clojure的一个纯粹理论方面,它不受性能、实现或持续性约束的影响。类似于“数据驱动的集合论”。
...