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
by
选定 by
 
最佳答案

映射(除了排序映射)是无序的,并且打印顺序可能因 Clojure 版本、JVM 版本以及您可能已安装的其他 Clojure 打印系统自定义而异(该系统是可修改和扩展的)。

运行时的映射实例将始终以相同的方式打印其元素——这是唯一保证。

by
这是否也可以适用于以下内容?

'(' 向 [] 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的一个纯理论方面,这并不意味着性能、实现或持久性约束。这就像是“数据驱动的集合论”。
...