请在2024年Clojure调查!中分享您的想法。

欢迎!有关该功能如何工作的更多信息,请参阅关于页面。

+4
Clojure

在代码中有一些地方,我需要定义和使用一次的函数,在定义它们的地方定义。定义此类函数有两种主要方法,一种是无名函数
(map #(blepify-with blep (:blop %)) xs)
另一种是高阶函数
(map (comp (partial blepify-with blep) :blop) xs)

我个人不使用partial,总是倾向于使用匿名函数,因为

  • 匿名函数在调用时进行变量解引用,这意味着我可以重新定义blepify-with,新定义将自动使用。在开发期间非常有帮助,并且与直接链接一样在生产中表现良好;
  • partial通过隐藏函数参数数量,使得代码的可读性降低。明确比隐晦好,Cursive可以立即显示我是否传递了错误的函数参数数量

我也很少使用comp。除了上面提到的变量解引用外,它还让我从右到左阅读代码。在小示例中这并不重要,但随着示例的扩大,线程宏极大地提高了可读性。
我发现comp有用的唯一情况是当数据处理顺序与函数应用顺序相反时,如transducers:(comp (filter even?) (map inc))应该从左到右读取。尽管首先调用的是(map inc),但这个transducer处理的数据首先通过even?谓词,然后通过inc转换。

我的问题是,我是否错过了关于partialcomp的更多内容?也许这只是口味的问题,我只是不习惯用它们,而且它们同样易于阅读,而且不必重新定义使用位置的优点被高估了?我应该何时更倾向于使用comppartial而不是匿名函数?

2 答案

+7

在我看来,您应该优先使用匿名函数而不是部分函数和comp函数,这是Clojure的惯用方法。

我唯一会使用comp函数的时候是组合transducer链。我几乎从不使用partial。

+3

我发现我把comppartial重构为fnletfn#()语句。结果可能会更加冗长,但更容易推理和调试。

调试比最初的写代码难两倍。
因此,如果你尽可能巧妙地编写代码,
根据定义,你不够聪明去调试它。

—— Kernighan定律

我的偏好是避免过于机智或者迷恋代码简洁,导致忽视了其他因素。

正如其他人所说,匿名函数更常见,但我有时也会使用partial。我很少使用comp,通常只在transducers中使用,因为这样可以让应用顺序更容易理解;否则,我使用threading宏。只有在应用程序非常简单明了的情况下,我才有必要使用partial,此时我除最后一个参数外还有一个函数的应用参数,我需要在高阶函数中使用它。要简单明了。
...