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

这不都是一个现有代码通过无序映射的 seq 顺序的偶然来工作的案例吗?如果是这样,任何依赖于现有行为的代码在 Clojure 在 1.5.1 到 1.6.0 和 1.6.0 到 1.7.0 之间的映射 seq 排序更改时有时会中断,有时不会中断。

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](https://clojure.atlassian.net/browse/CLJ-1613)(由 michalmarczyk 提出)
...