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 以及特定的值时,这个不变量被违反。

要合并它们,你想要构建一个map,然后执行 opts (conj defaults-map opts),但这需要第二次遍历键/syms/strs,选择仅存在于 :or map中的名称,需要创建另一个map,或者可能多次调用 assoc

我认为这是可行的,只是写起来可能有些繁琐。

我很感兴趣,这只是一个信息发布,还是希望改变Clojure?

修改 :or 在解构中的行为将是一项破坏性语言更改 — :as 特定地绑定原始map值到符号)

编辑
我希望能对其进行更改。我发现它很令人困惑,并且在我教授 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` 绑定得早,但这并不明确,并且没有示例显示它们不可用。你会接受一个展示该行为的补丁吗?
在这种情况下,我更愿意为这个问题而非 PR 创建一个问题。
好的,谢谢。
...