2024 Clojure现状调查中分享您的想法!

欢迎!请查看关于页面以了解更多有关如何使用此信息。

+5票数
Clojure

尽管存在assoc-in,但没有clojure.core/dissoc-in。
确实,可以使用update-in和dissoc构建dissoc-in,但这从另一个角度反驳了assoc-in。
当提供assoc-in的快捷方式时,为了保持一致性,也应该有dissoc-in的快捷方式。
实现方式与assoc-in类似。

16个答案

+1

评论者:alexmiller

我们必须考虑向量以及其他非映射类型的数据结构。我还更倾向于不使用标志,而是允许展开符以移除多个元素。

例如,像一个等效的函数

(update-in [{:foo 1}] [0] dissoc :foo)

这样,我们只剩下了{{[{}]}},所以现有的方法确实会留下空集合。

我还查看了一些现有的dissoc-in实现,如core.incubator、taoensso.encore、clj-http、medley、useful、plumbing等。大多数使用单个键路径,并留下空集合——这些主要源于incubator版本。Encore通过将键路径与最终要移除的叶子键分开来处理多个路径。Medley、useful和plumbing对仅针对映射,并移除空映射。

我不敢想象我们会在核心库中实现一个特定于映射的版本(因为其他所有-in函数都是通用的),因此我得出结论,我们需要一个允许留下空集合的dissoc-in。鉴于这一点,我不确定dissoc-in相对于update-in + dissoc提供了多少价值,以至于值得现在将其添加到核心库中,特别是在它已经存在于各种实用库中(在很多情况下具有不同的语义)。这样,我们可能会破坏(或至少给)现有dissoc-in实现的使用者带来不便。我将将此保持开放以供评论,但我的想法是现在不实施此增强。

+1

评论者:alexmiller

是的,但我觉得在更新案例中这些因素平衡得不同。在更新中,实现更少,并且它们与我们提议添加的内容相符。因此,它们为用核心功能替换现有功能创造了可能性。

我认为常见的实用库实现(flatland/useful/plumbing)实际上覆盖了不同的需求——只在地图上进行更新-in、dissoc 和路径删除。所以如果目标是覆盖通用用法,那么我们就需要在只有地图上工作,并删除留下的空路径。但是,我认为这与其他核心-in 功能有些冲突。我猜也许有一个中间方案可以执行路径删除,但使其工作在地图之外——这可以满足实用库所指示的需求,并且像其他-in 函数一样通用。如果您需要保留空集合,您可以像现在那样进行更新-in+dissoc。

0 投票

评论者:jafingerhut

2012年9月13日发布的补丁 clj-1063-add-dissoc-in-patch-v2.txt 取代了2012年9月7日发布的 001-dissoc-in.diff。它修复了一个错别字(doc string 中的“缺失末尾”),并为新功能添加了测试用例。

0 投票

评论者:bronsa

谢谢修复,Andy

0 投票

评论者:jafingerhut

建议的 dissoc-in 应该与 clojure.core.incubator 中的一个进行比较,我偶然发现了它。我看它们看起来不同,但我还没有检查是否有任何行为差异。

https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj

0 投票
_评论者:bronsa_

clojure.core.incubator 中的 dissoc-in 递归删除空地图

user=> (clojure.core.incubator/dissoc-in {:a {:b {:c 1}}} [:a :b :c])
{}

而在这个补丁中的则不行(正如我所期望的)

user=> (dissoc-in {:a {:b {:c 1}}} [:a :b :c])
{:a {:b {}}}
0 投票

评论者:stu

请在孵化器中完成这项工作。

0 投票

评论者:andrewhr

保留空路径真的是最期望做的吗?我认为,因为 {{assoc-in}}/{{update-in}} 都会一路上创建路径,所以这种行为看起来像是真正的“双面性”。

有哪些坏事情 {{nil}} 恶作剧处理得不好?这些问题对于 {{dissoc-in}} 用户来说过于晦涩了吗?

0 投票

评论者:alexmiller

补丁中的测试非常薄弱。应该测试多个级别、记录、向量等。

0 投票
评论者:[email protected]

测试 "clj-1063-add-dissoc-in-patch-v2.txt"


(dissoc-in {} [:a :b :c])
=> {:a {:b nil}}


这种行为相当出乎意料。孵化器版本没有这个问题,尽管它会删除空映射。

我正在为这个补丁编写测试(以及可能的新 dissoc-in),但我不太清楚是否应该保留空路径或删除它们?我不在乎哪种方式,尽管我倾向于同意 Andrew Rosa 的观点,即保留它们更为对称。
0 投票

评论者:[email protected]

@alex,你希望保留空路径还是删除它们?两种方式都可以接受,尽管从均衡的角度来看,我稍微更喜欢保留它们。一旦我知道你想走哪个方向,我可以为这个方向编写测试。

0 投票

评论者:alexmiller

这两种方法的权衡是什么?

在人们使用 dissoc-in 代替品的地方(使用 dissoc 等的 update-in)他们期望的行为是什么?

0 投票
评论由:michalmarczyk

如果我们只想处理嵌套在映射中的映射……我可能更愿意删除空子路径。

然而,如果我们想在过程中接受向量,那么保留空路径可以使该情况下的语义更加清晰


(dissoc-in [{:foo 1}] [0 :foo])
;= [{}]


相比之下,删除空路径可能会导致需要解决的麻烦,这可能需要限制删除路径的行为仅针对映射,或者当向量中的一个子路径成为条目时抛出。这两种方法似乎都不太理想。
0 投票

评论由:michalmarczyk

我们还可以从技术角度接受一个标志来决定是否应该删除空路径并让用户确保只有在没有向量存在时才传递{{true}}。但我并不特别喜欢这种方法,因为它似乎认为,额外参数的更自然用途是提供额外的路径供{{dissoc}}和{{dissoc-in}}匹配使用(参照CLJ-1771)。

0 投票

评论者:bronsa

相同的论点也可以用于包括update。实际上,updatedissoc-in可以在几个实用库中找到,这应该表明人们并不满意仅仅使用update-in + dissoc

当然,将其添加到内核中会在使用某些库时导致警告(它不会破坏任何东西,与update相关的导致破坏的AOT错误已经被修复),但我并不认为这是一个大问题;这些库的新版本将很快发布,即使不是这样,警告也并非世界末日。

...