Clojure 2024状态调查!分享你的看法。

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

0
打印
编辑

Clojure 地图序列表示是否明确定义?如果计算一个 Clojure 地图的 'pr-str' 的 CID,它是否唯一?

CID 是什么?
它是内容摘要。
比如说 SHA-256,或者任何摘要函数,都无关紧要。
我想知道当将 Clojure 地图输入到摘要函数时,是否可能产生非唯一的散列值。
```(sha-256 (pr-str {:one 1 :two 2}))```

现在我想象一个地图是一组键值向量。

```#{ [:一 1] [:二 2]  }```

在我的代码中,我首先写出了 :一。
但它是不是总是先于 :二 出现呢?

如果我运行上面的代码,它会总是返回一个唯一值吗?
by
我想象Clojure映射是带有一个特别的 `bind` 或 `>>=` 操作符的集合,这个操作符使得使用集合的某个元素时返回该元素所绑定的值。

({:一 1 :二 2} :一) => 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
我可能要使用向量了。
(此信息假设您想要计算一个具有如下属性的哈希/摘要函数D:对于任何两个无序集合s1和s2,如果(= s1 s2)为真,则(= (D s1) (D s2))也必须为真。
类似的,对于无序的Clojure映射也是如此。)

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

如果希望使用一个哈希/摘要函数,其中对其作为输入提供的元素顺序的改变会导致该函数的输出变化,那么我建议您不会得到您想要使用的结果。

2 个答案

+1

被选择
 
最佳答案

映射(除排序映射外)是无序的,并且可能会根据Clojure版本、JVM版本以及您可能已安装的Clojure打印系统(这是可修改和可扩展的)以不同的顺序打印。

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

对此类情况也可以这么说吗?

将一个无序列表映射到数组中的操作

换句话说,'无序列表映射的向量表示'是否没有指定?
这是相同的问题 - 为了添加到向量中,映射元素被访问的顺序是什么?没有定义的顺序。
0

如果我计算Clojure映射'pr-str'的CID,是否是唯一的?
我想知道当将 Clojure 地图输入到摘要函数时,是否可能产生非唯一的散列值。

这取决于摘要,而不是映射的事实,它来自Clojure,或者您是否使用pr-str
根据定义,任何合理的摘要都是一个丢失函数,因此它始终允许冲突,即使某些摘要的可能性极小。

在我的代码中,我首先写出了 :一。
但它是不是总是先于 :二 出现呢?

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

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 的一些纯粹理论方面,它不受性能或实现或持久性限制的影响。就像一种`数据驱动的集合理论`。
...