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

欢迎!有关如何操作,请参阅 关于 页面以获取更多信息。

0
错误

我尝试在 defprotocol 的方法签名中使用 &。显然(见下文),这会被编译成简单的参数名,并且没有对可变参数数量进行特殊处理。我认为在协议签名中使用 & 应该能够检测到并立即抛出异常(我也认为对这个签名的限制应该被文档化;尽管我在后来意识到这一点后,在当前文档中并没有找到这个规定的具体说明(不过当然,这是由 defprotocol 创建一个 Java 接口所暗示的))。

(defprotocol Applier (app (link: this f & args)))
Applier
(deftype A (link: ) Applier (app (link: _ f & args) (prn f & args) (apply f args)))
user.A
(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在内的多个地方使用可变参数和结构化形式。我的补丁在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
by

评论者:coventry

当然,Tassilo。已经完成了。

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

最好的问候:
Alex

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

0
by

评论者:tsdh

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

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

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

0
by

评论者:tsdh

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

0
by

评论者:jafingerhut

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

0
by

评论者:tsdh

我已经将补丁基于当前的master重新提交,以便再次干净地应用。

0

评论者:tsdh

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

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

0

评论者:michaelblume

基于master分支进行合并

0

评论者:michaelblume

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

...