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

欢迎!请参阅关于页面以了解此工作的更多信息。

0
ClojureScript

这是因为{{cljs.repl}}处理来自JS环境的返回值的字符串表示时,先读后打印。从版本2371开始,相关的代码片段在此

https://github.com/clojure/clojurescript/blob/r2371/src/clj/cljs/repl.clj#L156

演示此现象的代码段更多

ClojureScript:cljs.user> (array-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14) {1 2, 3 4, 5 6, 7 8, 9 10, 11 12, 13 14} ClojureScript:cljs.user> (array-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18) {7 8, 1 2, 15 16, 13 14, 17 18, 3 4, 11 12, 9 10, 5 6} ClojureScript:cljs.user> (seq (array-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18)) ([1 2] [3 4] [5 6] [7 8] [9 10] [11 12] [13 14] [15 16] [17 18]) ClojureScript:cljs.user> (hash-map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18) {7 8, 1 2, 15 16, 13 14, 17 18, 3 4, 11 12, 9 10, 5 6}

这个问题可能是描述在(link: http://stackoverflow.com/questions/26349324/clojurescript-array-map-order 文本:这个问题)中描述的问题的最可能原因。打印有序集合的“预期”方式将防止用户困惑。

7 答案

0

评论者:dnolen

Clojure中是如何处理这个问题的?

0

评论者:michalmarczyk

内置REPL简单地打印值到* }而不尝试先读取它们。

0

评论者:dnolen

REPL 的评估结果是一个字符串,与 Clojure 不同,为了在 ClojureScript REPL 中正确打印,似乎有必要重新读取结果。我认为,无论如何,array-map 并没有对顺序做出任何明确的承诺。

0
_由 michalmarczyk 发表评论_

是的——请参阅 https://clojure.org/data_structures, 其中提到


ArrayMaps
在执行代码表操作时,有时候我们希望有一个维持键顺序的映射。ArrayMap 就是这样一种映射——它简单地将键值对实现为一个数组。因此,它具有线性查找性能,只适用于非常小的映射。它实现了完整的映射接口。新的 ArrayMap 可以使用 array-map 函数创建。请注意,只有当未 '修改' 时,数组映射才会维持排序顺序。随后的 assoc-ing 最终会导致它 '变成' 哈希映射。


这个片段从我记事起就一直存在;而且这个特殊功能不时在各种在线讨论中出现。{{array-map}}(核心函数)的文档字符串在承诺在 Clojure 和 ClojureScript 中构造数组映射方面是明确的。

至于手头的这个问题,我认为它是一个非常轻微的问题(因此有“微不足道”的优先级),但是它是真实的——REPL 中打印的表示与在同一值上调用 {{pr-str}} 返回的字符串不一致。事实上,解决这个问题的方法之一是使用在 CLJS 端计算出的 {{pr-str}} 表示。但是,这里可能有一些复杂的因素,我们需要解决。
0

评论者:dnolen

感谢指出 API 承诺。好吧,我确实没有一个很好的想法来解决这个问题,但一份不太难看的补丁是受欢迎的 :)

0

Comment made by: mfikes

我认为这个问题现在无法重现。例如,{{(apply array-map (range 100))}} 会按顺序打印。在 {{repl.cljc}} 中也不再存在 {{read-string}} 调用。

0
参考资料:https://clojure.atlassian.net/browse/CLJS-872(由michalmarczyk报告)
...