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

欢迎!有关如何使用此平台的更多信息,请查看关于页面。

+5
Clojure

尽管有 assoc-in,但没有 clojure.core/dissoc-in。
确实,dissoc-in 可以通过 update-in 和 dissoc 构建,但这同样是对 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 版本通过将键路径与最终的叶键分开来处理多个路径(变长)。medley、useful 和 plumbing 则是仅使用映射,并移除空映射。

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

+1

评论者:alexmiller

是的,尽管我认为在更新情况下,各个因素平衡方式不同。在更新时,实现较少,它们与我们拟添加的是匹配的。因此,它们为现有功能替换核心功能创造了可能性。

我认为常见的通用库实现(flatland/useful/plumbing)实际上满足的是不同的需求——仅在映射上进行更新、删除和不匹配路径。所以,如果目标是覆盖常见的用法,那么我们可能需要让它仅在映射上工作,并删除留下的空路径。然而,我认为这与其他核心-in功能有些不一致。也许有一个折中年份可以在处理路径删除的同时使其工作在映射之外——这将满足通用库的需求,同时也会像其他-in功能一样通用。如果你需要留下空集合,你可以做你现在所做的那样——更新-in+删除。

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]

@alex,你希望保留空路径还是删除?两种方式都可以接受,但我稍微倾向于保留它们。一旦我知道你要走哪个方向,我可以为这个做测试。

0

评论者:alexmiller

两者之间的权衡是什么?

在哪里使用dissoc-in替代品(update-in与dissoc等)的地方,他们期望的行为是什么?

0
评论由:michalmarczyk_ 发表

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

然而,如果我们想在途中接受向量,那么保留空路径在该情况下将具有清晰的语义


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


相比之下,删除空路径似乎会导致必须解决的某些问题,要么将路径删除行为限制为映射,要么在子路径嵌套在向量中成为条目时抛出异常。任何一种方法似乎都不太理想。
0

评论由:michalmarczyk 发表

此外,我们可以在技术上接受一个标志来决定是否应该删除空路径,并让用户确保只有在没有向量的情况下才传递 {{true}}。但我不确定我是否很喜欢这种方法,因为它在我看来,额外的参数更自然的目的是为了提供额外的路径供 {{dissoc}} 和 {{dissoc-in}} 匹配变长语义使用 (cf. CLJ-1771)。

0

评论者:bronsa

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

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

...