请在2024 Clojure状态调查中分享您的想法!

欢迎!请参阅关于页面以获取更多此工作的相关信息。

+5
Clojure

尽管有assoc-in,但没有clojure.core/dissoc-in。
dissoc-in可以使用update-in和dissoc来构建,但这也是反对assoc-in的理由。
提供assoc-in的快捷方式时,也应提供dissoc-in的快捷方式,以保持一致性。
实现方式与assoc-in类似。

16 个答案

+1

评论由:alexmiller发表

我们必须考虑除了map之外的其他向量或关联数据结构。我也希望不要使用标志,而是开放以删除多个值。

有以下类似示例

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

我们将得到{{[{}]}},因此当前的这种方法确实会留下空集合。

我还看了一些现有的dissoc-in实现 - core.incubator, taoensso.encore, clj-http, medley, useful, plumbing等。大多数只使用单个键路径并留下空集合 - 这些大多来自孵化器版本。Encore以通过分离键路径和要从其删除的最终叶子键来与多个路径一起工作(可变)。Medley, useful和plumbing只处理map并删除空map。

我不能想象我们会为core创建一个特定的映射版本(因为所有其他-in函数都是通用的),因此我得出结论,我们需要一个dissoc-in,它留下空集合。考虑到这一点,我不确定dissoc-in是否提供了比update-in + dissoc更多的价值,从而值得添加到core中,特别是由于它在各种实用程序库中都存在(很多时候语义不同)。这样我们可能会破坏(或者至少不便)许多现有的dissoc-in实现的使用者。我将为此开放评论,但我觉得在此时拒绝此增强功能。

+1

评论由:alexmiller发表

是的,但我认为在更新情况下,这些因素呈现出不同的平衡。在更新中,实现较少,并且它们匹配我们提议添加的内容。因此,它们创造了现有功能被核心功能替换的可能性。

我认为常见的实用库实现(flatland/useful/plumbing)实际上覆盖了一个不同的需求 - 仅在地图上进行更新 + dissoc + 路径删除。因此,如果目标是覆盖常见用法,那么我们需要使其仅在地图上工作并删除留下的空路径。然而,我认为这与其他核心-in功能有些矛盾。我想也许中间有一个折中的方案,即去除路径,但仍使其超越地图 - 这将满足实用库所示的需求,同时像其他-in函数一样通用。如果你需要留下空集合,你可以做你现在所做的 - update-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替代品(如update-in、dissoc等)的地方,他们期望的行为是什么?

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错误都已修复),但我觉得这并不是一件大事;新的库版本将很快发布,即使不是这样,警告也不至于世界末日。

...