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方法实现中使用varargs。

0 投票

评论由 coventry 提出

谢谢,Tassilo。如果我在JIRA系统中的任何地方可以检查类似的其他问题的先前工作,我将不胜感激。

最好的问候。
Alex

0 投票

评论由 tsdh 提出

我的补丁的新版本。

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

关于你的问题,Alex:搜索“varargs”会列出CLJ-1024,但你可能不会查看,因为这是一个已关闭的问题...

0 投票

评论由 tsdh 提出

Alex,如果你没有意见,我们可以移除你的补丁,改用我的补丁,它涵盖了一些更多的案例吗?

0 投票

评论由 coventry 提出

是的。刚刚读过1024和相关的邮件列表讨论。你完全应该得到这笔钱:你的补丁更全面,你已经在这方面投入了很长时间。:-)谢谢 Incorporating the good parts of my patch。

最好的问候。
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 提出

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

0 投票

评论由 tsdh 提出

Stu,我之所以将这个问题分配给你,是因为你已经分配给了CLJ - 1165,我已经将其关闭为这个问题的重复项。

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

0 投票
by

评论者:michaelblume

基于 master 重新创建

0 投票
by

评论者:michaelblume

希望这个可以合并到主分支中——我刚刚看到一个 pull request 使用了 varargs 协议,它似乎是通过错误地调用返回参数数来意外地工作的,因为返回参数数只被调用了一次,而且是与接口中的 "&" 和 "args" 匹配的两个额外参数。在弄明白发生了什么之前,这完全把我搞糊涂了。

...