请在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发布前不久被应用,但存在一个错误(禁止太多使用),因此它被撤销,错误被关闭和拒绝。

在我被告知clojure 1.5发布后再次提出此问题。

所以,我的补丁又来了。这次它更加宽松,只在defprotocol/definterface方法声明以及在deftype/defrecord和reify方法实现中禁止使用可变参数。

0

评论者:coventry

谢谢,Tassilo。如果JIRA系统中有任何地方我能检查像这样的前辈工作,我将不胜感激。

最好的问候。
Alex

0

评论者:tsdh

我的补丁的新版本。

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

关于您的询问,Alex:搜索“可变参数”会列出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中评估测试中使用的macroexpand形式时,我可以看到CompilerException被成功抛出并打印。但它似乎在中间某处被捕获,所以macroexpand返回了一个形式,异常并没有到达(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主分支的最新提交后不再干净地应用。

0

评论者:tsdh

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

0
by

评论者:tsdh

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

我的补丁与CLJ-1165之间有一个小的差别是,这里我使用一个包含文件/行/列信息的CompilerException,而在CLJ-1165中我使用了ex-info。我认为CE更合适/更有信息量,因为错误已经在宏展开期间触发。

0
by

评论者:michaelblume

基于master分支重置

0
by

评论者:michaelblume

希望我们能合并这个——我刚刚收到一个使用变长参数协议的pull request,看起来是因为只在调用了变长参数arity的情况下调用它,调用时多加了两个参数,与接口中的'&和'args匹配。在我弄清楚发生了什么之前,这让我非常困惑。

...