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 来?

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


({:one 1 :two 2} :one) => 1
(本信息假设您想要计算一个具有以下属性的哈希/摘要函数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的一个纯粹理论方面,它不考虑性能或实现或持久性约束。就像一个“数据驱动的集合论”。
...