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

欢迎!请参阅关于页面以获取更多关于此如何工作的信息。

0
Clojure

Collection类通过委派给{{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\"]"

附带的补丁通过在集合{{toString}}实现中用新的{{RT.prString}}方法替换对{{RT.printString}}的调用,以解决这个问题。

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

7 个答案

0

评论者:alexmiller

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

0
_评论者:michalmarczyk_

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

用户当然无法期待任何对动态变量的依赖,或者除参数之外的其他任何东西——这是一个纯值。

在Google群组线程中的原始示例是懒惰的序列,它本质上是一个值 - (lazy-seq [(str ["a string"])]) - 它返回不同的{{pr-str}}(和{{print-method}})表示形式,这取决于是否在创建它和对其调用{{pr-str}}之间将其传递给{{print}}。


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


在这里,用户可能会期望{{pr-str}}调用与{{print}}调用无关,因为前者只在后者返回后进行,但仍然存在一种神秘的联系。

该补丁修复了这个问题


Clojure 1.9.0-master-SNAPSHOT
user=> (let [x (lazy-seq [(str ["a string"])])] (print x) (pr-str x))
(["a string"])\"(\\\"a string\\\")\"
user=> (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
by

评论由:pbwolf发起

原始问题从{{toString}}开始。一个更生动的问题是,这个问题证明了{{pr}}在生成EDN时的不可靠性。

presence 或 absence of the intervening {{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
by
参考:https://clojure.atlassian.net/browse/CLJ-2248(由michalmarczyk报告)
...