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 版本通过将键路径与最终的叶键分开以 dissoc (可变参数)来处理多个路径。Medley, useful 和 plumbing 版本仅适用于映射,并删除空映射。

我无法想象我们会在核心(-Core)中做一个特定于映射的实现(因为所有其他-in 函数都是通用的),因此我得出结论,我们需要一个能够留下空集合的 dissoc-in。鉴于这一点,我不确定 dissoc-in 能否提供足够的价值超过 update-in + dissoc 以值得在此时添加到核心中,特别是鉴于它存在于各种实用程序库中(在很多情况下具有不同的语义)。我们可能会破坏(或至少使)许多现有 dissoc-in 实现的用户感到不便。我将为此留下评论,但此时我倾向于拒绝这个增强功能。

+1

评论者:alexmiller

是的,尽管我认为更新情况中因素平衡方式不同。在更新中实现较少,它们与我们打算添加的内容相匹配。因此,它们为用核心功能替换现有内容创造了潜力。

我认为通用工具库实现(flatland/useful/plumbing)实际上正在满足一个不同的需求 - 仅在映射上进行更新-in、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中的dissoc-in进行比较,我偶然遇到了它。我看它们看起来不同,但还没有检查是否有任何行为差异。

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])
{}

而此补丁中的dissoc-in(正如我所期望的)则不会这么做

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

评论者:stu

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

0

评论者:andrewhr

保留空路径真的是最期望的操作吗?我认为,因为{{assoc-in}}/{{update-in}}会在过程中创建路径,这种行为看起来像是真正的“双重”。

{{nil}} punning可能处理不好的坏事情有哪些?这些问题对于{{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替代品(如update-in以及dissoc等)的地方,他们期望的行为是什么?

0
by
评论由:michalmarczyk

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

然而,如果我们想在路上接受向量,那么保留空路径在这种情况下会使得语义更加清晰。


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


相比之下,移除空路径似乎会导致必须通过限制移除路径的行为仅限于映射或当子路径嵌套在向量中成为条目时抛出问题。任何一种方法似乎都不太理想。
0
by

评论由:michalmarczyk

我们也可以技术上接受一个标志来决定是否移除空路径,并让用户确保只有在没有向量的情况下才传递{{true}}。但我并不特别喜欢这个方法,因为这在我看来,额外参数的更自然目的是为dissoc提供附加路径以匹配可变参数的{{dissoc}}和{{dissoc-in}}语义(参见表格CLJ-1771)。

0
by

评论者:bronsa

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

将它们添加到核心确实会导致在使用某些库时出现警告(这不会破坏任何内容,引起update中断的AOT错误已经被修复),但我不认为这真的是个大问题;这些库的新版本将很快发布,即使不会这样,警告也不是世界末日。

...