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

欢迎!有关更多信息,请参阅关于页面。

0投票
集合
Michael Blume 指出,:or 默认值可能取决于其他键的值,见https://groups.google.com/d/msg/clojure/6kOhpPOpHWM/ITjWwQFS_VQJ

Michael 的 Gist https://gist.github.com/MichaelBlume/4891dafdd31f0dcbc727 显示了一个涉及 :keys 和 :or 的关联形式示例,其中锡的编译或非依赖符号 :keys 的顺序。通过微调该示例,可以得到总是编译,但根据 :keys 产生不同值的表达式


(let [foo 1
       bar 2
       {:keys [bar foo]
        :or {foo 3 bar (inc foo)}} {}]
  {:foo foo :bar bar})
;= {:foo 3, :bar 4}

(let [foo 1
      bar 2
      {:keys [foo bar]
       :or {foo 3 bar (inc foo)}} {}]
  {:foo foo :bar bar})
;= {:foo 3, :bar 2}


我相信,最自然的解决方案是要求在不存在任何拆分引入的局部变量的包围作用域中评估 :or 默认值。这种做法已被 0001 补丁采用。

10 个答案

0投票

评论者:michaelblume

我怀疑这才是正确的做法,但是我认为重要的是要指出,这将破坏现有的代码 https://github.com/ngrunwald/ring-middleware-format/blob/master/src/ring/middleware/format_params.clj#L214

0投票

评论者:michaelblume

关于我之前的评论的更新-- ring-middleware-params 已更新,不再依赖于这种行为。我认为我们确实应该合并这个补丁,以免其他人依赖于它。

0投票

评论者:mpenet

由于这涉及到 :or 键的评估,因此值得检查这将否对 http://dev.clojure.org/jira/browse/CLJ-1676 也有影响。

0投票

评论者:stu

这是一个行为变更,文档并没有承诺提供所需的行为,现有代码可能依赖于当前行为。

0投票

评论者:jafingerhut

这难道不是现有代码通过无序映射的序列顺序的意外而工作的情况?如果是这样,任何依赖于现有行为的代码在 Clojure 的映射序列顺序从 1.5.1 更新到 1.6.0,然后从 1.6.0 更新到 1.7.0 时可能会中断,有时不会中断。

0投票

评论者:michaelblume

是的,这确实是的,我已看到由于这些变化,现有的代码已经出现问题,这就是导导致此票据的讨论。

0投票

评论者:michaelblume

更新此补丁

0投票
_评论者:michalmarczyk_

@Stuart

为了证实上述说法,以下是在Clojure 1.6和Clojure 1.7的REPL中评估的相同代码片段,这两个REPL刚刚启动,结果显示不同


Clojure 1.6.0
(let [foo 1 bar 2
      {:keys [foo bar]
       :or {foo 3 bar (inc foo)}} {}]
  [foo bar])
[3 2]

Clojure 1.7.0
(let [foo 1 bar 2
      {:keys [foo bar]
       :or {foo 3 bar (inc foo)}} {}]
  [foo bar])
[3 4]


文档中并没有承诺{{:or}}和{{:keys}}之间不会有令人惊讶的交互,但正如上述所示,任何依赖于1.6行为的现有代码在1.7中已经被破坏。指定*某些*行为并坚持下去将防止未来的此类意外。

我也认为当前的行为在“随机”的意义上,因为没有任何原则上的理由可以预期它 - 因此提出了使{{:or}}默认值指向包围作用域的提议,我在补丁中实现了这一功能。
0投票

评论者:michaelblume

更新补丁以合并到主分支

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