请在 2024年Clojure状态调查! 中分享您的看法。

欢迎!有关如何使用本网站的一些更多信息,请参阅 关于 页面。

+4
Clojure

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

我个人很少使用partial,并且总是优先选择匿名函数,因为

  • 匿名函数在调用时需要进行变量解引用,这意味着我可以在开发中重新定义blepify-with,并且新定义会自动使用。这在开发中非常有用,在生产环境中与直接链接一样高效;
  • partial通过隐藏函数参数数量,使代码可读性降低。明确性优于隐晦性,Cursive可以立即告诉我是否给函数传递了错误的参数数量

我也很少使用comp。除了变量解引用的相同问题之外,它会使我不得不从右到左阅读代码。在小示例中这真的无关紧要,但当代码量增加时,threading宏会大大提高可读性。
我发现comp有用的唯一一次是当函数应用的反序被数据处理的反序抵消时,例如transducers:(comp (filter even?) (map inc)) 按从左到右的顺序读取。尽管首先调用(map inc),但这个transducer处理的数据将首先通过even?谓词,然后通过inc转换。

我的问题是,我是否遗漏了有关partialcomp的更多内容?也许这只是口味问题,我只是还没有习惯它们,它们本身就是可读的,而且不需要重新定义使用位置是过时的?我应该在什么情况下优先选择comppartial函数而不是匿名函数?

2 条回答

+7

在我看来,你应该优先选择匿名函数而不是partial和comp,这是Clojure中的惯用解决方法。

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

+3

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

调试的难度是编写代码的两倍。
因此,如果你尽可能巧妙地编写代码,那么你在
定义上,不足以调试它。

—— Kernighan的定律

我的偏好是避免过于聪明或过分关注代码简洁,以至于忽略其他考虑。

正如别人所说的,匿名函数更常见,但我也偶尔使用partial。我很少使用comp,通常只在transducer中使用,因为它使应用顺序更容易理解;否则,我使用threading宏。只有在函数应用非常简单的情况下,我才有所有除了最后一个参数之外的参数,我需要在高阶函数中使用它时,才会使用partial。保持简单和直接。
欢迎来到Clojure问答社区,在这里你可以向Clojure社区成员提问并获得答案。
...