2024年Clojure状态调查!中分享你的想法。

欢迎!请查看关于页面,了解更多有关此页面如何工作的信息。

0
错误

我在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 和解构形式。我的补丁在 clojure 1.5 发布前不久被应用,但有一个错误(禁止太多的使用),因此它被回滚,并关闭了错误并拒绝了它。

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

因此我又提交了这个补丁。这次它要宽松得多,仅禁止在 defprotocol/definterface 方法声明以及在 deftype/defrecord 和 reify 方法实现中使用 varargs。

0

评论者:coventry

谢谢,Tassilo。如果在JIRA系统中我可以检查类似问题的先前工作,我会很感激得到一些提示。

最好的敬意,
Alex

0

评论者:tsdh

我的补丁的新版本。

现在,我使用了像 Alex 一样的带正确文件/行/列信息的 CompilerException。我还添加了他的测试用例(它通过了)。

关于你的问题,Alex:搜索 "varargs" 会列出 CLJ-1024,但你可能根本不会去查看它,因为它是一个已关闭的问题...

0

评论者:tsdh

Alex,如果你不反对,我们可以删除你的补丁,取而代之的是我的补丁,它涵盖了一些更多的情况?

0

评论者:coventry

是的。我刚刚读过了 1024 及其相关的邮件列表讨论。你完全应该得到这个荣誉:你的补丁更全面,你已经参与这项工作了很长时间。:-) 谢谢你融合了我补丁的好部分。

最好的敬意,
Alex

0

评论者: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中評価测试中使用的宏展开形式时,我可以看到成功地抛出并打印了CompilerException。但似乎它在中间被捕获了,所以宏展开返回了一个形式,异常没有传到(is (thrown? ...))。因此,我已将这些测试注释掉,并添加了一个大型的FIXME。

0

评论者:tsdh

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

0

评论者:jafingerhut

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

0

评论者:tsdh

我已经将补丁重新设置为当前master,以便它可以干净地应用。

0

评论者:tsdh

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

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

0

评论者:michaelblume

已基于master分支重新建立

0

评论者:michaelblume

如果我们能合并这个就更完美了--我只是刚刚收到一个使用varargs协议的pull request,它似乎意外地成功了,因为只有在调用varargs arity时,它被调用时还有两个额外的参数,恰好与接口中的'&和'args匹配。在我弄清楚发生在什么之前,这让我困惑不已。

...