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 Don't know how to create ISeq from: 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:搜索“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发表

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

0

评论由:tsdh发表

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

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

0

评论由:michaelblume

基于master分支

0

评论由:michaelblume

希望我们能将其合并——我刚刚收到一个使用可变参数协议的拉取请求,它似乎是偶然中工作的,因为在只调用可变参数arity时,它是用两个额外的参数调用的,这与接口中的'&和'args相匹配。在我弄清楚情况之前,这让我非常困惑。

...