请在2024年Clojure调查表中分享您的想法!

欢迎!请参阅关于页面了解有关如何使用本页面的更多信息。

0
Clojure

无法使用单个空选项序列与case一起使用,也无法与单个选项序列和默认条款一起使用。

我希望
bq. (case 1 () :a :none)

返回 :none,但它失败了,并发出了一个无用的异常:“未处理的clojure.lang.ArityException:传递给:core/max的参数数量不正确(-2)”

我希望 (case 1 () :a) 会导致“java.lang.IllegalArgumentException:没有匹配的条款”,但相反它也失败了,并带有
"未处理的clojure.lang.ArityException:传递给:core/max的参数数量不正确(-2)”

这似乎不一致,因为当存在其他选项时传递空的选项列表是可以的

bq. (case 1 () :a 2 :b :none)

返回 :none,正如预期的那样

附带的补丁在进一步转换为case**之前删除了带有空测试列表的测试条款对,并添加了测试。

8 答案

0

评论由:chrisblom

哎呀,标题中有个错别字(单字重复)

0

评论由:alexmiller

在case中,空匹配列表似乎应该是一个错误——也许它应该编译失败而不是被忽略?

0

评论由:chrisblom

在给出多个子句时,当前支持空选项列表,因此针对空列表的编译失败将是一个破坏性更改。

这适用于1.8版本

(案例1
() :never-happens
1 :ok
:default)
=> :ok

但是这不行

(案例1
() :never-happens
:default)
=> 抛出 clojure.lang.ArityException: 传递给 core/max 的参数数量错误 (-2)

当没有提供其他子句时似乎非常不一致。

0

评论由:bronsa

空列表在案例中没有任何意义,因为匹配原始空列表的正确方式是 (case () (()) :empty)。我认为让它不抛出异常没有价值,我的投票是让 case 宏在编译时每次使用 () 时都报错。

0

评论由:alexmiller

() 现在将不会匹配任何东西,因此针对 () 的失败不会破坏任何现有的匹配案例。

不过,我想象中可能存在的一种情况是创建案例并可能创建空案例列表的宏?例如:

(defmacro make-case [xs] `(defn ~'foo [e#] (case e# ~xs "matched" "nope")))

0

评论由:chrisblom

我并没有用它来匹配空列表,我是当从领域特定语言(DSL)生成 case 语句时遇到这个角落案件的。
虽然这是一个病理性情况,但我不同意这没有意义,这里的空列表仅仅表示没有备选方案,
因此,子句不会匹配,并且其结果表达式永远不会运行。

我的观点是,在 clojure 1.8 中,现在这是允许的

(case a
() :never-happens
1 :a
2 :b
:default)

(as an empty list never matches)

(case a
1 :a
2 :b
:default)

但是

(case a
() :never-happens
:default)

给出的是没有信息的错误。

我认为它应该等效于

(case a
:default)

因为拒绝 case 语句中的空列表是一处破坏性变更,
并且只有在没有其他子句时拒绝空列表是不一致的。

0

评论由:chrisblom

??() 现在永远不会匹配任何内容,因此当括号失败时不会破坏任何现有的匹配案例。??

由于在 clojure 中允许案例中的括号小于 1.8,(但不是当它是唯一条款时),让编译器拒绝它可能会破坏现有代码。

??我唯一想象的可能存在的情况是,一个宏创建了案例并可能可以编程性地创建一个空案例列表。??

这正是我遇到这个问题的原因

0
参考:https://clojure.atlassian.net/browse/CLJ-2164(由chrisblom报告)
...