2024年Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面了解更多关于这个站点如何运作的信息。

0
... 打印
编辑

Clojure映射的序列表示是否明确定义?如果我计算映射的'pr-str'的CID,它是唯一的吗?

...
什么是CID?
...
它是内容的摘要。
比如SHA-256,或者任何摘要函数都无所谓。
我想知道Clojure映射在传递给摘要函数时是否可能具有非唯一的哈希。
...
```(sha-256 (pr-str {:one 1 :two 2}))```

现在我将映射想象成一系列键值向量

```#{ [:one 1] [:two 2] }```

我已经在我的代码中写过:one 第一次。
但这是否总是出现在 :two 之前?

如果我运行上述代码,它是否总是返回一个唯一的值?
我想象Clojure映射是这样的集合,配备一个特殊的 `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有一个纯粹理论方面的特性,不关心性能或实现或持久性限制。就像是一个‘数据驱动的集合论’的样子。
...