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\"]"

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

有关由上述问题引起的{{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))
([字符串])"(\"字符串\")"
user=> (let [x (lazy-seq [(str [字符串])])] (pr-str x))
"(\"字符串\")"


这里用户可能会预期{{pr-str}}调用与{{print}}调用独立,因为前者只在后者返回后执行,但实际上存在一种奇怪的交互。

这个补丁修复了这个问题


Clojure 1.9.0-master-SNAPSHOT
user=> (let [x (lazy-seq [(str ["a string"])])] (print x) (pr-str x))
([字符串])"(\"字符串\")"
user=> (let [x (lazy-seq [(str [字符串])])] (pr-str x))
"(\"字符串\")"
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](https://clojure.atlassian.net/browse/CLJ-2248)(由 michalmarczyk 报告)
...