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

欢迎!请参阅关于页面以获取更多的信息。

0
Clojure

这与许多其他问题/Jira工单相关,但我还没有找到针对这个特定问题的工单。

因为`:or`被解构为`not-found`值的`get`调用解构的键/符号等,如果您使用`: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`专门绑定原始映射值到符号)

编辑
我希望对其进行更改。我觉得它很令人困惑,我在教授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)中暗示了`:as`绑定先于`:or`,但并不明确,也没有示例显示它们不会工作。你会接受一个显示该行为的补丁吗?
在这种情况下,我更希望有关于这个问题的一个问题,而不是一个拉取请求
by
好的,谢谢。
...