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等。大多数使用单个键路径并留下空集合 - 这些似乎主要来自孵化器版本。Encore使用多个路径通过将键路径与要移除的最终叶子键分开来进行处理(可变参数)。Medley、useful和plumbing只处理映射并删除空映射。

我想难以想象我们会为这种特定于映射的制作一个核心版本(因为所有其他的-in功能都是通用的),因此我得出结论,我们需要一个保留空集合的dissoc-in。考虑到这一点,我不确定dissoc-in是否提供了足够的附加价值,以至于值得在此阶段添加到核心中,尤其是鉴于它存在于各种实用库中(在许多情况下具有不同的语义)。这样我们可能会破坏(或者至少让)现有的dissoc-in实现用户感到不便。我将保留此项供评论,但此时我倾向于拒绝此增强功能。

+1

评论由:alexmiller 提供

是的,但我认为更新案例中的因素平衡有所不同。在更新中,实现更少,并且它们与我们拟增加的内容相匹配。因此,它们为用核心功能替换现有功能创造了可能。

我认为常见的实用库实现(flatland/useful/plumbing)实际上满足了一个不同的需求 - 只在地图上进行更新、删除和路径删除。因此,如果目标是涵盖常用情况,那么我们需要让它仅在地图上工作并删除留下的空路径。然而,我认为这与其他核心-in函数有些矛盾。我想也许有一个折衷的方案,既可以在路径删除上工作,又可以让它超越地图 - 这样可以满足实用库所表示的需求,同时又像其他-in函数一样通用。如果您需要留下空集合,您可以像现在一样执行更新-in+dissoc。

0

评论者:jafingerhut

2012年9月13日发布的补丁clj-1063-add-dissoc-in-patch-v2.txt取代了2012年9月7日发布的001-dissoc-in.diff。它修复了一个错别字(在文档字符串中缺少最后的"),并为新函数添加了测试用例。

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 错误已经修复)但我认为这不是什么大问题;这些库的新版本将很快发布,即使不是这样,警告也不会是世界末日。

...