请在 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 无法从:java.lang.Long 创建 ISeq
clojure.lang.RT.seqFrom (RT.java:487)

16 答案

0 投票

评论者:coventry

附带测试代码的补丁。我将它修改为抛出 CompilerException,以便显示源代码位置。不清楚这是否符合 clojure 代码的标准,但我希望更多的宏在错误处理中提供这方面的功能。

0 投票

评论者:tsdh

此问题已在CLJ-1024中进行过讨论。我在那里提供了一个补丁,禁止在defprotocol/definterface等各种地方使用varargs和destructuring forms。我的补丁在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和reifyinline方法实现的测试。

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

0 投票

评论者:tsdh

补丁的新版本现在所有测试都没有 comment,并已通过。Andy Fingerhut意识到了这一点,对于4个 deftype 和 reify 测试,我需要进行 eval 而不仅仅是宏展开。

0 投票

评论作者: jafingerhut

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

0 投票

评论者:tsdh

我已经将补丁重新基于当前的主分支,以便它可以再次干净地应用。

0 投票

评论者:tsdh

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

我的补丁与CLJ-1165之间的一个微小差异在于,这里我使用了带有文件/行/列信息的CompilerException,而在CLJ-1165中我使用了ex-info。我认为CE更合适/更具信息性,因为错误已经在宏扩展期间触发。

0 投票

评论者:michaelblume

已重新提交到master

0 投票

评论者:michaelblume

如果我们将这些合并,那将是有益的--我刚刚收到一个使用可变参数协议的合并请求,这好像是因为只有在调用可变参数的arity时才调用,并且提供了两个额外的参数,与接口中的'&'和'args'匹配。在我弄清楚发生了什么之前完全弄晕了。

...