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 使用多个路径通过将键路径与最后的叶子键分离来进行 dissoc 操作(变长参数)。Medley、useful 和 plumbing 仅支持映射并且移除空映射。

我无法想象在核心库中创建此类映射特定版本(因为其它所有 -in 函数都是通用的)并且因此我得出结论,我们需要一个在某些情况下要求修改的核心库 dissoc-in,特别是鉴于它在多种实用库中存在(在很多情况下有不同语义)。这样我们可能会打破(或者至少给现有 dissoc-in 实现的用户带来不便)。我将在这里开放对此事的评论,但我倾向于在这个阶段拒绝此增强功能。

+1

评论由:alexmiller 撰写

是的,虽然我认为更新情况下的因素平衡有所不同。在更新中,实现方式更少,并且它们与我们提出的添加内容相匹配。因此,它们创建了用核心功能替换现有内容的机会。

我认为通用的实用库实现(flatland/useful/plumbing)实际上满足了不同的需求 - 仅在图上执行更新+删除(dissoc)+路径删除。因此,如果目标是覆盖常见用法,那么我们只需要它在图上运行,并删除留下的空路径。然而,我认为这与其他核心-in 函数有点不一致。我想也许有一个折衷方案来做路径删除,但使其工作范围超出了图 - 这将满足实用库表明的需求,并且像其他-in 函数一样通用。如果您需要留下空集合(colls),您现在可以这样操作 - 更新+删除。

0

评论者:jafingerhut

2012年9月13日的补丁clj-1063-add-dissoc-in-patch-v2.txt取代了2012年7月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
by

评论者:stu

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

0
by

评论者:andrewhr

保留空路径是不是最希望做的事情?我说,因为{{assoc-in}}/{{update-in}}都会在过程中创建路径,这种行为看起来像是真正的“双生”。

{{nil}}双关修辞无法妥善处理什么样的问题可能会导致不好的事情?这些问题对于{{dissoc-in}}用户来说可能过于晦涩难懂?

0
by

评论由:alexmiller 撰写

补丁中的测试过于简单。应该测试多个级别、记录、向量等。

0
by
Comment made by: [email protected]

正在测试“clj-1063-add-dissoc-in-patch-v2.txt”


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


这种行为相当令人意外。虽然孵化器版本没有这个问题,但它确实会删除空映射。

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

评论者:[email protected]

@alex,你希望保留还是删除空路径?两种方式都可以,虽然从整体来看,我稍微倾向于保留它们。一旦我知道你想走哪条路,我就可以进行测试。

0
by

评论由: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-indissoc

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

...