请分享您的想法,参加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。我的补丁在clojure 1.5发布之前被应用了,但有一个错误(禁止使用太多),因此它被撤销了,错误也关闭了,提出了反对意见。

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

所以,我又提交了这个补丁。这次它更加宽松,只禁止在defprotocol/definterface方法声明和deftype/defrecord以及reify方法实现中使用可变参数。

0

评论者:coventry

谢谢,Tassilo。如果JIRA系统中有什么地方我可以检查类似问题的先前工作,我将不胜感激。

敬上,
Alex

0

评论者:tsdh

我的补丁的新版本。

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

关于您的问题,Alex:搜索“可变参数”会列出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中评估测试中使用的宏展开形式时,我可以看到编译器异常成功抛出并打印出来。但它在中间似乎被捕获了,所以宏展开返回了一个形式,而异常并未到达(is (thrown? ...)。因此,我已经注释了这些测试,并添加了一个大的FIXME。

0

评论者:tsdh

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

0

评论者:jafingerhut

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

0

评论者:tsdh

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

0
by

评论者:tsdh

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

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

0
by

评论者:michaelblume

重新提交到master

0
by

评论者:michaelblume

如果这个能合并就太好了——我刚刚收到一个使用varargs协议的pull request,这个协议似乎偶然地工作,因为当唯一调用varargs参数数量时,它使用了两个额外的参数,与接口中的'&'和'args'匹配。我在解决这个问题之前困惑了好久。

...