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

欢迎!请参阅关于页面以获取有关此功能的更多信息。

0 投票
Clojure

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

附带的补丁通过在集合{{toString}}实现中替换对{{RT.printString}}的调用,改为调用新方法{{RT.prString}},显式绑定* }来修复此问题

有关原始报告,请参见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}}之间的关系是否将它传递给{{print}}而返回不同的{{pr-str}}(和{{print-method}})表示。


Clojure 1.9.0-beta1
用户=> (let [x (lazy-seq [(str ["a string"])])] (print x) (pr-str x))
(["a string"])ibilb(\"[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"])ibilb(\"[\\\"a string\\\"]\")"
用户=> (let [x (lazy-seq [(str ["a string"])])] (pr-str x))
\"(\"[\\\"a string\\\"]\")"
0 投票

评论者:alexmiller

这也许是一种哲学争论,我确实没有那么确定的答案,但很高兴来回讨论。 :)

同意持久的不可变值集合是一个值。然而,有许多方法可以构建表示该不可变数据的字符串视图 - 我们在Clojure打印系统中内置了几个(pprint、pr、print)+ 一系列各种旋钮,如集合大小限制等。我看不到任何原则使我相信toString必须独立于选择该视图的旋钮。

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

0 投票

评论者:notespin

我认为这确实有点哲学性。然而,为了给补丁增加一些砝码,我认为toString和thus str通常被程序员期望是稳定的。所以我会说,当前的行为打破了“最小意外”原则。我会投票支持使str/toString稳定,但话说回来,这种更改对某人来说有很小的可能是破坏性的。

0 投票

评论者:alexmiller

作为一个久经沙场的Java老兵,我对toString没有期望。通常在Java中,它们建立在不稳定的可变字段上,因此我当然不分享你的期望。 :)

str内在涉及“打印”(创建值的字符串视图)。我认为str是“稳定的”,但并非仅是其显式输入的函数(糟糕的隐藏状态)。为了类比,有许多方法可以从日期对象中创建字符串,并使用java.util.Date的toString将字符串格式化为你的时区,这是外部隐藏状态。

我并不一定反对这里的更改。我只是没觉得这是明显正确的事情。

从一般的角度来看,我认为“最小意外”原则意味着人们对令人惊讶的共同性比对实际存在的要大得多,所以我很少考虑这一点。我更多地考虑从一些声明原则中得出的论据。我认为这个领域记录不充分/指定不充分。

0 投票

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