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 的版本仅限于映射( ст.remove 空映射)。

我无法想像我们会在核心(因为所有其他-in 函数都是通用的)中创建特定于映射的版本,因此我得出结论,我们将需要一个可以留下空集合的 dissoc-in。考虑到这个,我不确定 dissoc-in 是否提供了比 update-in + dissoc 更多的价值,以至于值得在此阶段添加到核心中,尤其是考虑到它已经存在于各种实用库中(许多情况下语义不同)。这样,我们可能会破坏(或至少是不方便)许多现有的 dissoc-in 实现的用户。我打算对此开放评论,但我倾向于在此阶段拒绝此增强。

+1

评论由:alexmiller 制作

确实如此,尽管我可能认为在更新案例中,因素平衡有所不同。在更新中,实现较少,并且它们与我们计划添加的内容相匹配。因此,为现有内容用核心函数替换创造了可能性。

我认为通用的实用工具库实现(flatland/useful/plumbing)实际上是在满足一个不同的需求——在地图中对更新-in、dissoc和路径移除。因此,如果目标是涵盖常见用法,那么我们就需要使其仅在地图上工作并移除留下的空路径。然而,我认为这与其他核心-in函数有些矛盾。我猜也许有一个折衷方案来进行路径移除,但使其在地图之外也能工作——这样既可以满足实用库的需求,又可以像其他-in函数一样通用。如果你需要留下空集合,可以像你现在这样做——update-in+dissoc。

0

评论者:jafingerhut

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

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}} 拼音可能会处理不好哪种坏情况?这些问题对于 {{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-in}} 语义(参见 CLJ-1771)。

0

评论者:bronsa

同样的论点可以用于包含 update。事实上,updatedissoc-in 都可以在几个实用库中找到,这应该表明人们并不同意只使用 update-in + dissoc

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

...