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

欢迎!请查看关于页面以获取有关如何使用该平台的更多信息。

+5
Clojure

虽然没有 clojure.core/dissoc-in,但有一个 assoc-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 是仅处理映射的,如果遇到空映射则移除。

我不认为我们会在核心库中创建一个仅限映射的版本(因为所有其他的 -in 函数都是通用的),因此我得出结论,我们需要一个可以留空集合的 dissoc-in。鉴于这一点,我不确定dissoc-in 有没有足够的附加价值超过 update-in + dissoc 以至于值得添加到核心库中,尤其是在它已经存在于各种实用库中(在很多情况下语义各不相同)。这样我们可能会破坏(或至少使)许多现有 dissoc-in 实现的用户们感到不便。我将为此保留意见,但我倾向于在此阶段拒绝此增强。

+1

评论者:alexmiller

是的,虽然在更新用例中,这些因素相互抵消的比重不同。在更新中,实现方案较少,并且与我们所提议添加的内容相匹配。因此,它们创建了用核心功能替换现有功能的可能性。

我认为常见的通用库实现(flatland/useful/plumbing)实际上覆盖了不同的需求——仅在映射上进行更新、消除和路径删除。所以如果目标是覆盖常见使用情况,那么我们就需要在只针对映射上生效并删除留下的空路径。然而,我认为这与其他核心-in函数有些矛盾。我想也许有一个折衷方案,可以在路径删除的同时突破映射的限制——这既能满足通用库所提出的需要,也能像其他-in函数一样通用。如果你需要留下空集合,可以像你现在所做的那样——update-in+dissoc。

0

评论者:jafingerhut

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

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 递归删除空映射

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

虽然这个补丁中的功能并不是按照我预期的那样工作

用户操作:(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 补替品(update-in 与 dissoc 等的更新)的地方,他们期望什么行为?

0
_评论:michalmarczyk_

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

然而,如果我们想在过程中承认向量,那么保留空路径会使该情况下的语义非常清晰


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


相比之下,删除空路径似乎会导致必须解决的问题,这些问题可能必须通过限制路径删除行为仅在映射中或当向量中的嵌套子路径成为条目时抛出。两种方法似乎都不太理想。
0

评论:michalmarczyk

技术上,我们可以接受一个标志来决定是否应删除空路径,并让用户确保只有在没有向量时才传递 {{true}}。不过,我不太喜欢这种方法,因为它似乎在我看来,额外参数的更自然目的是为 dissoc 提供额外的路径以匹配变异性语法的 {{dissoc}} 和 {{dissoc-in}}(参考 CLJ-1771)。

0

评论者:bronsa

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

当然,将其添加到核心可能会在使用某些库时导致警告(这将不会破坏任何东西,因为导致 update 破坏的 AOT 错误已被修复),但我并不认为这真的是一个大问题;那些库的新版本将很快发布,即使不是这种情况,警告也不是世界末日。

...