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代替仅仅使用macroexpand。

0

评论人:jafingerhut

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

0

评论者:tsdh

我将补丁重新建立在当前主分支上,使其再次可以干净地应用。

0

评论者:tsdh

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

与CLJ-1165相比,我的补丁针对此问题的一个细微差别在于,这里我使用了包含文件/行/列信息的CompilerException,而在CLJ-1165中我使用了ex-info。我认为CompilerException更合适/更有信息量,因为错误已经在宏展开期间触发。

0
by

评论者:michaelblume

基于master更新

0
by

评论者:michaelblume

如果这个问题能被合并,那就好了。我刚刚收到一个使用varargs协议的pull请求,这个请求似乎是无意中工作的,因为只有在调用varargs arity时,它才用两个额外的参数被调用,这与接口中的'&和'args匹配。这让我非常困惑,直到我弄清楚到底发生了什么。

...