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

欢迎!请查看关于页面以获取更多有关如何使用本站点的工作方式的信息。

0
Clojure

这与许多其他问题/票证相关,但我还没有找到关于特定于此的。

因为 :or 被解构为 get 调用解构键/符号等的 not-found 值,如果您用 :as 绑定一个对象并将默认值包含在 :or 中,则对象将没有默认值

(defn example [{:keys [a b]
                :or {a 1 b 2}
                :as opts}]
  (println a b opts))

(example {:a 5})
;=> 5 2 {:a 5}

这导致我们的代码库中出现了微妙的错误,我们期望存在默认值,但实际上没有,或者我们使用 {:pre [some-pred]} 来检查一个不变性,当我们修改函数以使用除特定值之外的 :as 时,该不变性被违反。

要合并它们,您需要先构建映射,然后 opts (conj defaults-map opts),但这需要再次遍历键/符号/字符串,仅选择 :or 映射中的名称,并需要创建另一个映射,或者反复调用 assoc

我认为是可行的,但这需要一点麻烦来编写。

我很想知道,这是否只是出于信息目的发布的,还是在Clojure中请求一个更改?

(更改 :or 在解构中的行为将是破坏性的语言更改 -- :as特定绑定原始映射值到符号)
_
编辑
我很希望能对其进行修改。我发现它令人 confusion,我在教授 Clojure 时也将其视为一种尴尬且令人惊讶的行为。但据我所知,大多数请求都会被拒绝,因为 Clojure 的现有行为大多是固定的。最好检查一下。

1 答案

+1
_
选中
 
最佳答案

这是语言的预期行为。:as 有关解构中提供的值。:keys 或其他解构有关绑定值。:or 有关为缺少的绑定值提供默认值。如果您有“始终包含”的默认值,那么我认为您应该在通过某种方式解构之前进行此操作

(defn example [opts]
  (let [defaults {:a 1 :b 2}
        defaulted-opts (merge defaults opts)
        {:keys [a b]} defaulted-opts]
    (println a b defaulted-opts)))

您可以合并其中的一些,只是尝试更明确地表达。

_
感谢你的回答。在页面(https://clojure.org/reference/special_forms#binding-forms)中,通过使用 `init-expr` 暗示 `:as` 的绑定早于 `:or`,但并不是明确的,而且没有显示他们不起作用的示例。你能否接受一个展示这种行为的补丁呢?
by
在这种情况下,我更愿意有一个与这个问题相关的问题,而不是一个PR。
by
我会做的,谢谢。
...