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

欢迎!请查阅 关于 页面以获得更多关于如何使用本网站的信息。

0
Clojure

集合类通过将 {{toString}} 委派给 {{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}} 的调用,该方法是显式绑定 * } 的。

请参阅 https://groups.google.com/d/msg/clojure/S13swxLy1ng/FKLYdY9HAgAJ 了解有关 {{lazy-seq}}、{{print}} 和 {{str}} 之间相互作用的原报告,这些交互作用最终由上述问题引起。

7 个答案

0

评论者:alexmiller

我不清楚当前的这种行为是否正确或为何如此。

0
_Comment made by: michalmarczyk_

我预计在应用于不可变项的持久集合时,{{str}} / {{toString}} 应该是稳定的。换句话说,当应用于不可变输入时,我预计它应该是一个仅由显式传入的参数确定的纯函数。

用户当然无法期待这里有任何对动态变量的依赖,或者除参数(一个纯值)之外的其他事物。

Google 群组线程中的原始示例是一个惰性序列,表面上是一个值 - (lazy-seq [(str ["a string"])]) - 根据是否在创建和对其调用 pr-str(打印方法)之间传递给它,它返回不同(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 大师,我对 toStrings шън没有期望。通常在 Java 中,它们建立在可变字段上,并且非常不稳定,所以我当然不同意你的期望。 :)

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

我并不一定反对这里的改动。我只是没觉得它是显然正确的事。

从一般角度出发,我认为“最小惊讶原则”实际上比人们发现的惊讶之处要普遍得多,所以我对此不太重视。我更重视从某些规定的原则中衍生出的论证。但我认为这个领域尚缺乏文档/尚未明确。

0
by

评论者:pbwolf

原始问题从 {{toString}} 开始。一个更明显的问题是,这个问题表明 {{pr}} 无法可靠地发出 EDN。

中间的 {{print-str}}(调用者可能与此无关)的有无会产生重大影响。

`
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
by
参考:[https://clojure.atlassian.net/browse/CLJ-2248](https://clojure.atlassian.net/browse/CLJ-2248)(由 michalmarczyk 报告)
...