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 无法从: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:搜索“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中对测试中使用的宏展开形式进行评估时,我可以看到编译器异常被成功抛出和打印。但它似乎在中间被捕获,所以宏展开返回一个形式,而异常没有到达(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。我认为编译器异常更合适/更有信息量,因为错误已经在宏展开期间引发。

0
by

评论者:michaelblume

已合并到主分支

0
by

评论者:michaelblume

如果能将其合并就太好了——我刚刚收到一个使用varargs协议的pull request,这个协议似乎是偶然工作的,因为在调用varargs arity的唯一一次,它被调用时带有两个额外的参数,与接口中的"&"和"args"相匹配。在我弄清楚发生了什么之前,这让我非常困惑。

...