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

欢迎!请查看关于页面,了解更多关于这里的工作方式的信息。

+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 一个通过将 key 路径与要 disoc 的最终叶键分开来处理多个路径(可变参数)。medley、useful 和 plumbing 这些仅适用于 map,并移除空 map。

我想象不出我们会在 core 中添加特定于 map 的版本(因为其他 -in 函数都是通用的),因此我得出结论,我们需要一个允许留下空集合的 dissoc-in。鉴于这一点,我不确定 dissoc-in 是否提供了超过 update-in + dissoc 的足够价值以添加到 core 中,尤其是考虑到它存在于各种实用库中(许多情况下的语义不同)。我们可能会打破(至少是不方便)许多现有的 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中的相应功能进行比较,我偶然发现了它。我看它们看起来不同,但还没有检查它们的行为是否有任何差异。

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

亚历克斯,你希望保留空路径还是删除?两种方式都可以接受,尽管综合来看我稍微偏向于保留。一旦你知道想要走哪条路,我可以为这个功能编写测试。

0

评论者:alexmiller

两种方式之间的权衡是什么?

在人们使用dissoc替代者(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错误已修复),但我认为这并不是什么大问题;这些库的新版本将很快发布,即使这样,警告也不是世界末日。

...