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等地方使用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
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中评估测试中使用的宏展开形式时,我可以看到成功地抛出了CompilerException并打印出来。但似乎它在中间某处被捕获了,因此宏展开返回了一个形式,异常没有传到(is (thrown? ...))。因此,我已经注释了这些测试,并添加了一个大的FIXME。

0
by

评论人:tsdh

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

0
by

发表评论的人:jafingerhut

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

0
by

评论人:tsdh

我已经将补丁重新应用到当前的master版本上,以便再次干净地应用。

0
by

评论人:tsdh

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

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

0
by

评论者:michaelblume

基于master分支重新打标

0
by

评论者:michaelblume

如果我们可以合并这个会怎么样——我刚刚得到了一个 pull request,使用了一个 varargs 协议,它似乎偶然工作,因为在调用 varargs arity 的唯一一次,它还调用了两个额外的参数,与接口中的 '&' 和 'args' 匹配。在我弄清楚发生了什么之前,这让我非常困惑。

...