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

欢迎!有关如何使用此功能的更多信息,请参阅关于页面。

0
错误

我尝试在 defprotocol 中的方法签名中使用 &。显然(见下文),这样编译会使 & 成为简单的参数名称,并且没有对可变数量参数的特殊处理。我认为在使用协议签名时应检测 & 的使用,并立即抛出异常(我也认为这个签名上的限制应该被记录在文档中;尽管在文档中未指定(当然,后来意识到是由 defprotocol 创建的 Java 接口暗示的))。

user=> (defprotocol Applier (app this f & args))
Applier
user=> (deftype A () Applier (app _ 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而不是只是macroexpand。

0

评论者:jafingerhut

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

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 arities被调用时,它才调用两个额外的参数,匹配接口中的'&和'args。在我弄清楚发生了什么之前,这让我很困惑。

...