请在 2024 Clojure 状态调查!分享您的想法。

欢迎!请查看关于页面,了解更多关于该网站如何运作的信息。

0
语法和reader
编辑

目前,Clojure 允许包含 &rest 参数的解构模式

user=> (let [[a b & c] (range 5)] [a b c])
[0 1 (2 3 4)]

Python 允许这样做,同时还可以将所谓的“通配符”放入前端和中间位置(PEP 描述

>>> a, *b, c = range(5)
>>> a
0
>>> c
4
>>> b
[1, 2, 3]

Clojure 有没有考虑过类似的功能?这可以看起来像这样

user=> (let [[a & b c] (range 5)] [a b c])
[0 (1 2 3) 4]

我觉得这可能通过当前的 core 函数的解构方式实现,但也许我还是不了解某些细节。

1 个答案

+1

选中
 
最佳答案

在什么场景下这会有用?


重新显示
其他情况中使用的相似场景
* 我有一系列带有某些数据范围的项,我想获取边界(最早和最晚,例如)。我可以不使用任何解构式[get-first s, get-last s, get-next-to-last s],但解构使这更简单。
* 我有一个后进先出队列,并希望选取最后一个项和倒数第二个项进行下一步处理 [[init second-item first-item]]

在这所有情况下,都可以自己构建选定的项,但使用Clojure的所有解构方法也可以这样做。使用解构语法的确是一种既好又一致的方式来实现此目的,而无需在let块中填满大量繁琐的工作。

此外,将其作为核心理法文的一部分,这将在嵌套中使用,并且任何性能改进都将自动被所有人感受到。
对于顺序(可能非索引)输入,这样的案例通常效率不高。现在在spec(通过s/conform和正则规范)中已经支持这样的更广泛场景。

在您提到的第二种情况下,我认为我们甚至不愿也不鼓励这样做——这样的东西只是在制造性能混乱。

虽然我偶尔看到过像这样东西的需求,但远远比不上目前支持的情况(且往往对性能有不良影响),所以我并不确定添加这一点是否合理。
很有道理,大体上就是我预期的答案。您愿意查看一个关于`解构`的补丁,并且包含一些性能比较吗?
不太感兴趣,我认为你低估了在尾位置假设可变参数数量的地方和进行此类更改所需的努力。再结合缺乏用例,这并不是值得花费时间的。
非常好,非常感谢。
@Noah,这可以在库中作为宏实现,对社区带来的好处差不多,而不必在clojure.core中进行修补。虽然语言 squad 不愿意把慢操作写入语法中,但是程序员也知道在需要清晰的前提下,解构也是有价值的。
@pbwolf 是的,我也考虑过这一点。也许我会试试。

@alexmiller 经过思考,我对您的说法有点困惑,即有很多人假设可变参数,并且需要做的工作量。问题是不是人们依赖于 Clojure 读取器在没有尾位置的可变参数时抛出错误?
如上所述,规格和符合已经可以处理这种情况。

(let [{:keys [a b c]} (s/conform (s/cat :a int? :b (s/* int?) :c int?) (range 5))] [a b c])

;;=> [0 [1 2 3] 4]
我在谈论Clojure实现中的很多假设末尾有剩余参数。
啊哈哈哈,Clojure实现内部。我以为这只在`destructure`函数中处理过。这更有意义。
欢迎来到Clojure问答社区,您可以在这里提出问题并从Clojure社区成员那里获得答案。
...