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

欢迎!有关如何使用本网站的信息,请参阅 关于 页面。

0
错误

我试图在 defprotocol 中的方法签名中使用 &。显然(见下文),这样编译后 & 成为一个简单的参数名,没有对可变参数数量进行特殊处理。我认为在协议签名中使用 & 应该被检测到,并立即抛出异常(我也认为这个对签名的限制应该有文档记载;尽管我在当前的文档中没有找到明确规定,但当然它已经被隐含了(正如我后来意识到的那样),因为 defprotocol 创建了一个 Java 接口)。

user=> (defprotocol Applier (app (link: this f & args)))
Applier
user=> (deftype A (link: ) Applier (app (link: _ f & args) (prn f & args) (apply f args)))
user.A
user=> (app (A.) + 1 2)

<core$PLUS clojure.core$PLUS@5d9d0d20> 1 2

IllegalArgumentException 无法创建 ISeq:java.lang.Long
clojure.lang.RT.seqFrom (RT.java:487)

16 答案

0

评论由:coventry 发布

附带了带有测试代码的补丁。我让它抛出 CompilerException,以便显示源代码位置。不确定这是否符合 clojure 代码的标准,但我希望更多宏提供这种错误处理。

0

评论由:tsdh 发布

这个问题已经在 CLJ-1024 中讨论过了。在那里我提供了一个补丁,禁止在 defprotocol/definterface 等多处使用 varargs 和解构形式。我的补丁在 clojure 1.5 发布前被应用,但存在一个错误(禁止过多使用),因此被撤销,错误被关闭并拒绝。

我被告知在 1.5 发布后再次提出这个问题。

所以这里又是我提供的补丁。这次它更加宽松,仅在 defprotocol/definterface 方法声明和 deftype/defrecord 以及 reify 方法实现中禁止 varargs。

0
by

评论由:coventry 发布

谢谢,Tassilo。如果 JIRA 系统中哪里我可以查看类似问题的先前工作,我将非常感谢您的提示。

最好的问候。
Alex

0
by

评论由:tsdh 发布

我的补丁的新版本。

现在我使用 Alex 所用的带有正确文件/行/列信息的 CompilerException。我还添加了他的测试用例(已通过)。

关于您的问题,Alex:搜索“varargs”会列出 CLJ-1024,但您可能仍然不会查看它,因为它是一个已关闭的问题...

0
by

评论由:tsdh 发布

Alex,如果您没有反对,我们能否删除您的补丁,改用我的补丁,它的覆盖范围更广一些?

0
by

评论由:coventry 发布

是的。我刚刚阅读了1024号以及相关的邮件列表讨论。您完全应该得到赞扬:您的补丁更为全面,您已经在这里投入了许多时间。谢谢您融合了我补丁的好部分。

最好的问候。
Alex

0
by

评论由:tsdh 发布

好的,太好了。:-)

看起来我没有权限删除别人的附件,所以您能自己删除您的补丁吗?

0

评论由:coventry 发布

当然,Tassilo。已经完成了。

我认为此处也需要一个回归测试,针对hugod最初指出的情况。我在那里最初犯了你同样的错误,但amalloy在提交补丁之前指出了这一点(链接:1),所以这是一个自然犯的错误,可能在源代码中记录下来。

最好的问候。
Alex

(链接:1) http://logs.lazybot.org/irc.freenode.net/#clojure/2013-10-21.txt 搜索14:48:34。

0

评论由:tsdh 发布

Alex,我已经添加了你建议的回归测试。感谢你指出。

此外,我还添加了检查definterface方法声明的测试,以及使用defrecord、deftype和reify编写的内联方法实现的测试。

然而,我遇到了在deftype和reify测试中的问题,我不知道如何解决。当我将在测试中使用的宏展开形式评估到REPL中时,我可以看到编译器异常被成功抛出并打印。但它似乎被捕获到中间某处,所以宏展开返回一个形式,异常没有到达(is (thrown? ...))。因此,我已注释掉这些测试并添加了一个大FIXME。

0

评论由:tsdh 发布

补丁的新版本现在已将所有测试取消注释并通过。Andy Fingerhut让我意识到,对于4个deftype和reify测试,我需要eval而不是仅仅使用macroexpand。

0

评论者:jafingerhut

我尚未调查原因,但patch 0001-Forbid-vararg-declaration-in-defprotocol-definterfac.patch在2013年10月25日对Clojure master的最新提交后,不再干净地应用。

0

评论由:tsdh 发布

我已经将补丁重新合并到当前主分支上,使其再次干净地应用。

0

评论由:tsdh 发布

Stu,我已将此问题分配给你,因为你已被分配到CLJ-1165,我已经将其关闭为与此问题的重复。

我的补丁与此问题以及CLJ-1165之间的一个细微差别是,在这里我使用带有文件/行/列信息的CompilerException,而在CLJ-1165中我使用了ex-info。我认为CE更合适/更具信息性,因为错误已经在宏展开期间被触发。

0

评论者:michaelblume

已重新合并到master

0

评论者:michaelblume

如果我们将它合并到一起就太好了——我刚刚收到一个使用可变参数协议的pull request,它在偶然的情况下似乎工作得很好,因为只有在调用可变参数arity时才调用两个额外的参数,与接口中的'&和'args相匹配。在弄清楚发生了什么之前,这让我非常困惑。

...