请在

欢迎!请参见关于页面以了解如何使用本网站的更多信息。

0投票
Clojure

PersistentQueue实现了Sequential接口,但没有实现java.util.List接口。列表和Sequential对象都构成一个等价类。这意味着您可能会遇到非传递性相等的情况。

(def q (conj clojure.lang.PersistentQueue/EMPTY 1 2 3)) ;=> #user/q (def al (doto (java.util.ArrayList.) (.add 1) (.add 2) (.add 3))) ;=> #user/al (def v [1 2 3]) ;=> #user/v (= al v) ;=> true (= v q) ;=> true (not= al q) ;=> true

这是因为PersistentQueue是Sequential接口,但不是List接口,ArrayList是List接口,但不是Sequential接口,而PersistentVector则两者都是。

19回答

0投票

评论者:ppotter

啊,根据http://dev.clojure.org/display/design/JIRA workflow,我应该在提交这个工单之前向clojure-dev发送电子邮件。以下是讨论内容:

https://groups.google.com/d/topic/clojure-dev/ME3-Ke-RbNk/discussion

0投票

评论者:ppotter

附加文件:001-make-PersistentQueue-implement-List.diff,2012年9月15日

注意:此补丁与CLJ-1070中添加的补丁存在轻微冲突,因为两者都向PersistentQueue添加了额外的接口,本例中是List接口,CLJ-1070中是IHashEq接口。

0投票

评论由:[email protected] 发布

菲利普,补丁看起来相当不错——感谢你完成这项工作。几点备注

这只是我的个人观点,但我更喜欢将导入项列出来时不使用通配符,即使这意味着在 .java 文件顶部多出几行。

我注意到 "List stuff" 代码是复制自 ASeq 和 EmptyList 中的内容。我想这是复制的,因为 EmptyList 和 PersistentQueue 扩展了 Obj,因此无法扩展 ASeq。这是唯一的原因吗?重复这些方法定义似乎有点可惜,但我不确定是否有更好的解决方案,你知道吗?

如果测试也检查一下你实现的一些 List 方法会更好。

0投票

评论由:[email protected] 发布

哦,还有 "git am" 拒绝应用补丁,但我不确定原因。"patch -p 1" 运行完美。

0投票

评论者:ppotter

你在 git am 中使用了 --keep-cr 选项吗?

我很难确定是否应该在行尾添加 CR,因为我正在编辑的文件在这一点上并不一致。如果你在 emacs 中打开它们,一半的行都以 ^M 结尾。

0投票

评论者:ppotter

我将提交另一个补丁,其中更改了导入。我将考虑列表实现,看看我能想出什么主意。

0投票

评论者:ppotter

附加文件:002-make-PersistentQueue-implement-Asequential.diff

此补丁是 001-make-PersistentQueue-implement-List.diff 的替代方案

所以我考虑到你关于 ASeq 的看法,但我觉得直接让 PersistentQueue 实现 ISeq 并不完全合适。

所以我将 ASeq 分成两部分——ASequential,它实现了 j.u.{Collection,List} 并管理 List-equality 和 hashcodes;以及 ASeq,它……坦白说,似乎不再做什么了。

作为额外的奖励,此补丁还修复了 CLJ-1070,因此我添加了该票据的测试来证明这一点。它还通过删除所有 equals/hashcCode 东西和所有 Collection 东西来整理 PersistentQueue。

(结果证明,由于ASeq已经实现了Obj,持久队列实现Obj实际上并没有成为使用它的障碍。)

欢迎对这个方法提出评论,以及它与之前这个补丁和CLJ-1070上的补丁有何不同。

0投票
作者:

评论者:ppotter

在查看EmptyList实现List时,它与其他的相同,但它不应该如此。我认为indexOf的实现是最大的罪魁祸首 - 它应该只返回'return -1;',但它有一个巨大的for循环!但这超出了这次票证的范围,所以我不会在这里修复它。

0投票
作者:

评论者:jafingerhut

Philip,现在CLJ-1070的补丁已经应用,这些补丁不再应用正常。你愿意更新它们吗?如果愿意,请删除这些废弃的补丁。

0投票
作者:

评论者:ppotter

Andy,非常感谢你为让人们注意到这些而努力。我确实将提交新的补丁,希望在本周晚些时候。

0投票
作者:

评论者:ppotter

将现有的补丁替换为新的补丁,这些新的补丁可以干净地应用到master上。

有两个补丁

001-clj-1059-make-persistentqueue-implement-list.diff

这个补丁通过使持久队列直接实现List来解决相等性问题。我还利用这个机会移除了通配符导入,并添加了对List方法的测试,与补丁的先前版本相比。

002-clj-1059-asequential.diff

这个补丁通过创建一个新的抽象类ASequential,并使持久队列扩展了这个类来解决问题。

我最喜欢的解决方案仍然是ASequential补丁,但我将两者都留在这里进行对比。

0投票
作者:

评论者:halgari

审核中。

0投票

评论者:jafingerhut

菲利普,我认为这次是CLJ-1000中的提交补丁导致您的补丁002-clj-1059-asequential.diff未能干净地应用。我时常修复陈旧的补丁,其中更改直接且机械,但在此情况下,您正在移动CLJ-1000补丁已更改实现的一些方法,因此最好有人想出一种在不破坏CLJ-1000更改的情况下更新此补丁的方法。

0投票

评论者:ppotter

谢谢安迪。提交了一个新的补丁,002-clj-1059-asequential-rebased-to-cached-hasheq.diff,它取代了002-clj-1059-asequential.diff。

补丁001-clj-1059-make-persistentqueue-implement-list.diff仍然可以干净地应用,并且仍然是002-clj-1059-asequential-rebased-to-cached-hasheq.diff的另一种选择。

0投票

评论者:jafingerhut

由于在2014年1月30日前的那个星期对Clojure master所做的提交,特别是对hasheq的更改,补丁002-clj-1059-asequential-rebased-to-cached-hasheq.diff不再可以干净地应用。

补丁001-clj-1059-make-persistentqueue-implement-list.diff仍然可以。

...