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

欢迎!请参阅 关于 页面了解更多关于如何使用本站的信息。

0 投票
Clojure

集合类通过委托给 {{RT.printString}} 来实现 {{toString}},而 {{RT.printString}} 又受 * } 的值影响。

Clojure 1.9.0-beta1 user=> (binding [*print-readably* false] (str ["foo"])) "[foo]" user=> (binding [*print-readably* true] (str ["foo"])) "["foo"]"

附加的补丁通过在新 {{RT.prString}} 方法中替换集合 {{toString}} 实现中对 {{RT.printString}} 的调用,并显式绑定 * } 来解决这个问题。

有关原始报告(由上面的问题导致的 {{lazy-seq}}、{{print}} 和 {{str}} 之间的交互),请参阅 https://groups.google.com/d/msg/clojure/S13swxLy1ng/FKLYdY9HAgAJ

7 答案

0 投票

评论由:alexmiller

我不太清楚为什么或是否当前的行为是错误的?

0 投票
_评论由:michalmarczyk_

我期望 {{str}} / {{toString}} 在应用于不可变元素的持久化集合时是稳定的。换句话说,当应用于不可变输入时,我期望它是一个显式传递的参数的纯函数。

用户肯定无法预计这里的任何依赖 Dynamic Vars,或者除了参数之外的任何东西——参数是一个纯值。

谷歌组线程中的原始示例是一个懒序列,它表面上是一个值——(lazy-seq [(str ["a string"])])——无论是否将其传递给 {{print}},它都会返回不同的 {{pr-str}}(和 {{print-method}})表示。


Clojure 1.9.0-beta1
用户=> (let [x (lazy-seq [(str ["a string"])])] (print x) (pr-str x))
[[a string]]"(\"[[a string]]\")"
用户=> (let [x (lazy-seq [(str ["a string"])])] (pr-str x))
"(\"[[\\\"a string\\\"]]\")"


在这里,用户可能期望{{pr-str}}调用与{{print}}调用独立,因为前者仅在后者返回后发生,但的确存在一种奇怪的联系。

这个补丁解决了这个问题。


Clojure 1.9.0-master-SNAPSHOT
用户=> (let [x (lazy-seq [(str ["a string"])])] (print x) (pr-str x))
[[a string]]"(\"[[\\\"a string\\\"]]\")"
用户=> (let [x (lazy-seq [(str ["a string"])])] (pr-str x))
"(\"[[\\\"a string\\\"]]\")"
0 投票

评论由:alexmiller

这或许是一个哲学性的争论,我并没有一个确定的答案,但我很高兴来回讨论。 :)

坚持认为持久不可变值的集合具有价值。然而,有许多方式可以构建表示该不可变数据的字符串视图 - Clojure打印系统中内置了几个(pprint, pr, print)加上一系列控制选项,如集合大小限制等。我看不出有什么原则会导致我相信toString必须与选择该视图的控制选项独立。

换句话说,我并不认为这是一个需要解决的问题。

0 投票

评论者:notespin

我认为这确实是有点哲学性的。然而,为了支持补丁的一边,我认为toString及其str一般被认为是由程序员期望的稳定。因此,我会说当前的行为打破了最小惊讶原则。我会投票支持使str/toString稳定的,但说到底,这种改变可能会给某人带来微小的破坏性变化。

0 投票

评论由:alexmiller

作为一个经验丰富的Java老手,我对toString没有期望。通常,在Java中,它们基于可变字段构建,并且非常不牢固,所以我当然不分享你的期望。 :)

str本质上涉及“打印”(创建值的字符串视图)。我认为str是“稳定的”,但它不仅仅取决于其显式输入(隐藏状态)。为了做一个类比,有许多方式可以从日期对象创建字符串,java.util.Date的toString将使用你的时区格式化字符串,这是一个外部隐藏状态。

我仍然并不一定反对这里的改变。我只是不认为它显然是正确的事情去做。

从一般角度看,我认为“最少惊讶原则”暗示人们认为令人惊讶的事情比实际存在的要普遍得多,所以我对这一点信心不大。我更看重从某些声明的原则中得出的论点。我认为这个领域缺乏文献/定义不明确。

0 投票

评论者:pbwolf

原始问题始于 {{toString}}。一个更生动的问题是,该问题表明 {{pr}} 生成 EDN 不可靠。

在 {{print-str}} 中是否存在(这可能与我们调用 {{pr}} 的没有关系)会对结果产生重大影响

`
user> (clojure.edn/read-string

    (first
      (clojure.edn/read-string
        (let [mk-str (fn [] (lazy-seq [(str ["ZiZi"])]))
              a (mk-str)]
          ;(print-str a)
          (pr-str a)))))

["ZiZi"]

user> (clojure.edn/read-string

    (first
      (clojure.edn/read-string
        (let [mk-str (fn [] (lazy-seq [(str ["ZiZi"])]))
              a (mk-str)]
          (print-str a)
          (pr-str a)))))

[ZiZi]
`

0 投票
参考:https://clojure.atlassian.net/browse/CLJ-2248(由 michalmarczyk 报告)
...