请在 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之前吗?

如果运行上述代码,它总是会返回一个唯一值吗?
我想象Clojure maps是带有特殊`bind`或`>>=`操作符的集合,它可以返回该元素绑定的任意值。

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

我想我会因为“序列化可预测性”而使用`sorted-map`,当涉及到地图的唯一通用标识时。

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

感觉有点奇怪,那些应该在运行时生存的数据结构,在没有更多有关序列化协议的信息的情况下,其序列化形式是无法比较的。
我可能会使用向量。
(此信息假设您想要计算具有如下特性的哈希/摘要函数D:对于任何两个无序集合s1和s2,如果(= s1 s2)为真,那么 (= (D s1) (D s2))也为真。
同样适用于无序Clojure映射。)

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

如果您想使用一个哈希/摘要函数,该函数的输入数据的顺序改变会导致函数的输出也改变,那么我建议您可能不会得到想要的结果。

2 答案

+1

被选为最佳答案
 
最佳答案

映射(除了有序映射以外)是无序的,并且可能会因Clojure版本、JVM版本以及您可能安装的任何自定义Clojure打印系统(该系统可以修改和扩展)而按不同的顺序打印。

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

这样说对以下内容是否也适用?

'(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的一个纯粹理论方面的。它不涉及性能或实现或持续性限制。类似于“数据驱动的集合论”。
...