请在 Clojure 2024 调查问卷! 中分享您的想法。

欢迎!请访问 关于 页面以了解更多信息。

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 的 map 就像是配备了特殊 `bind` 或者 `>>=` 操作符的集合,它可以使得用集合的任何一个元素调用‘invoking’返回该元素绑定的任何值。

({:one 1 :two 2} :one) => 1
https://www.reddit.com/r/Clojure/comments/foqt7o/when_and_why_would_you_want_to_use_sorted_maps/

我觉得为了确保 map 的标识符唯一性,我可能会“排序 map”来达到“序列化预测性”。

碰巧 JSON 也是无序的。
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
by
被选中 by
 
最佳答案

映射(除有序映射外)是无序的,并且可能因为Clojure版本、JVM版本以及您在Clojure打印系统中可能进行的任何自定义而以不同的顺序打印(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中的集合和映射,在许多其他事物中,是可调用的——就是这样。

归并冲突几乎不可能发生,所以我并不担心这一点。
我担心的是“双重消化结果”的反面案例,这种情况可能和两个人同时抛出正面的硬币几率一样高,发生在有两个条目的映射中。
这似乎与问题的其余部分无关。但是,就这一点而言,Clojure 中关于集合或映射没有特别之处,Clojure 也没有运算符。
Clojure 中的集合和映射,以及其他一些东西,是可调用的——就是这样。

我只是在描述一个理论模型,这是在我的 Clojure 内部和性能问题有限的知识下我能够想象的最好的模型。

我对 Clojure 有一个纯粹理论的观点,它不受性能、实现或持久性约束的困扰。类似于“数据驱动的集合论”。
...