2024年Clojure调查问卷!中分享您的想法。

欢迎!请参阅关于页面,了解有关此平台的更多信息。

0
Clojure

这与许多其他问题/ Jira 工单有关,但我没有找到专门针对此问题的。

因为:or会被解构成键/符号等的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)通过使用`init-expr`暗示`:as`比`:or`先绑定,但这并不明确,也没有示例显示它们不起作用。你会接受一个展示该行为补丁吗?
by
在这种情况下,我更希望有一个关于这个问题的issue,而不是一个PR
by
我会做到的,谢谢。
...