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地图是可以调用特殊 `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 中的集合和地图在某种程度上是可调用的——就这么简单。


编辑
摘要冲突的概率极低,所以这并不是我所担心的。
我所担心的是 "双重摘要结果" 的反面案例,这种情况可能和抛硬币正面朝上的概率一样大,对于有两个条目的地图来说。
by
编辑 by
"这似乎与其他问题无关。但实际上,在Clojure中,关于集合或映射的这部分并不特殊,Clojure也没有操作符。
Clojure中的集合和映射,和其他事物一样,是可以调用的——就这么简单。

我只是描述了一个理论模型,关于正在发生的事情。这是根据我对Clojure内部和性能有限的了解所能想到最好的。

我理解Clojure的纯理论方面,不考虑性能或实现或持久性约束。就像一种‘数据驱动的集合论’。
...