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 之前吗?

如果运行上述代码,它是否会始终返回一个唯一的值?
我想象Clojure的map是具有特殊`bind`或`>>=`运算符的集合,通过这个运算符可以调用集合中某个元素,返回绑定到该元素上的任何值。

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

我猜测,为了确保映射的全球唯一标识符,我将使用`sorted-map`以提高“序列化可预测性”。

JSON也是无序的。
https://groups.google.com/g/golang-nuts/c/opEBtevDCyI

嗯,感觉有点奇怪,那些应该跨运行时存在的数据结构在没有任何关于序列化协议的额外信息的情况下,其序列化形式是不可比较的。
我可能会使用向量。
(此消息假设您想计算一个具有以下属性的散列/摘要函数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中的集合和映射,在其他事项中,是可以调用的——就这样。


编辑
摘要冲突发生的概率极低,所以这并不是我所担心的。
我所担心的是“双重摘要结果”的反面,这可能与一个有两个条目的映射中出现掷硬币正面朝上的概率相当。

编辑
"这似乎与问题的其他部分无关。但是,关于这一点,Clojure中的集合或映射并没有什么特别之处,Clojure也没有操作符。
Clojure中的集合和映射,在许多其他事物中,是可调用的——就是这样。

我只是在描述一个理论模型,它是基于我对Clojure内部知识有限以及对性能问题的了解而进行的。

我认识到Clojure有一个纯粹理论方面的方面,它与性能、实现或持久性约束无关。就像一种‘数据驱动的集合论’。
...