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投票

选中
 
最佳答案

映射(除了有序映射外)是无序的,并且可能因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中的集合和映射可以调用,就是这样。


编辑了
散列冲突的可能性 astronomers无法估计,所以这不是我所担心的。
我担心的是“双重散列结果”的反面案例,这可能与一个有两个条目的映射抛硬币出现正面的可能性一样。

编辑了
这似乎与问题中其他部分无关。但是,与此相关,Clojure 中的集合或映射没有特别之处,Clojure 没有运算符。
Clojure 中的集合和映射,以及其他一些东西,是可调用的——就这么简单。

我只是在描述一个关于正在进行中的理论模型。这是我根据有限的对 Clojure 内部结构和性能关心所能想出的最佳方案。

我知道 Clojure 有一个纯粹理论方面的东西,它不受性能或实现或持续的约束。类似于“数据驱动的集合论”。
...