将清洁代码原则应用于功能语言


16

我目前正在阅读Robert Martin的Clean Code。我认为这很棒,在编写OO代码时,我会牢记他的课程。特别是,我认为他的建议是使用带有有意义名称的小函数,这使我的代码流程更加流畅。最好通过以下引用来总结:

[W] e希望能够像读取一组TO段落一样阅读该程序,每个段落都描述了当前的抽象级别,并在下一层向下引用了后续的TO段落。

清洁代码,第37页:“ TO段落”是一个以不定式表达的句子开头的段落。“要做X,我们执行步骤Y和Z。”“要做Y,我们...”等。 ) 例如:

对于RenderPageWithSetupsAndTeardowns,我们检查该页面是否为测试页面,如果是,则包括设置和拆卸。无论哪种情况,我们都以HTML呈现页面

我也为我的工作编写功能代码。马丁在书中的例子确实读起来好像是一段段落,而且非常清楚-但我不确定“读起来像一组段落”是否适合功能代码使用。

Haskell标准库为例:

maximumBy               :: (a -> a -> Ordering) -> [a] -> a
maximumBy _ []          =  error "List.maximumBy: empty list"
maximumBy cmp xs        =  foldl1 maxBy xs
                        where
                           maxBy x y = case cmp x y of
                                       GT -> x
                                       _  -> y

从马丁的建议中可以得到尽可能远的信息,但这是简洁,惯用的Haskell。与他的书中的Java示例不同,我无法想象有任何方法可以将其重构为具有他所要求的节奏的东西。我怀疑按照清洁代码标准编写的Haskell 可能会long之以鼻且不自然。

我是否认为(至少是一些)干净代码与功能编程最佳实践不符?是否有一种明智的方式可以用不同的范式重新解释他的言论?


1
函数式程序员倾向于编写过于简洁的代码,这是事实。即使在那种环境下,我也不会远程考虑这是一种最佳实践。
Telastyn 2014年

原谅无知,但TO段落是什么?
Shashank Gupta 2014年

4
正如最近在另一个问题中提到的那样,迪杰斯特拉(Dijkstra)写了一篇关于“自然语言编程”的愚蠢的文章,我倾向于同意他的观点,即像散文一样读的代码简直是白痴。我认为在Haskell中尤其如此,因为它纯粹是象征性地表达了价值之间的平等,而不是产生效果的步骤序列。我认为重要的是引用的代码是惯用的。例如xs,这是一个不好的名字,但在函数语言中i和循环变量一样常见。
Doval 2014年

@ShashankGupta我编辑了该问题,并提供了到书中特定页面的链接以及我对鲍伯叔叔所写内容的理解。

@ShashankGupta他举了一些例子,但想法是应该像散文一样读。“要查找列表的最大值,请检查每个元素……”
帕特里克·柯林斯

Answers:


11

清洁代码首先是样式手册。用克林贡语写作时,《斯特兰克和怀特》不适用。这个想法是,您想让可能会读取您的代码的程序员清楚。您需要具有模块化且易于重组的代码。与其他语言一样,Haskell中有多种方法可以执行此操作,但是具体细节会有所不同。

话虽如此,Haskell有许多样式指南。堆栈溢出相当全面指南。保持编码逻辑简单明了似乎很稳定。还强调了功能的通用性,因为它导致了模块化。与清除代码相同,也强调了DRY代码。

最后,Clean Code和Haskell的编码指南力求做到同一件事,但最终还是走自己的路到达那里。


1
我觉得这个答案使Clean Code教给的原则打折扣,这些原则在所有语言中都非常适用,这是所提问题的核心。我可以理解为什么人们将Clean Code视为样式手册,而且我认为这部分是正确的,但还不够真实,无法将整本书视为一本。
艾伦(Allan)

我不认为《马丁的清洁法典》是样式手册。我觉得这本书的教导实际上介于风格指南和设计模式之间。
Michael R

15

我不确定我遵循您的意思是什么。正如他所描述的,段落不需要冗长的内容。他并不意味着代码应该像英语一样读。重要的部分是在逻辑上以相同的抽象级别对功能进行分组。那是一个超越编程范式的理论结构概念。

以鲍勃·马丁(Bob Martin)的“ TO段落”格式表示,我将您的示例理解为:

  • 要计算maximumBy,您需要一个排序函数和一个列表,结果是该列表的元素。
  • 要计算 maximumBy空列表和任何排序函数都是错误的。
  • 要计算maximumBy列表的xs,您可以使用maxBy函数。
  • 要计算maxBy两个列表元素的,请使用给定的排序函数将它们进行比较。如果第一个元素较大,请选择它。否则,请选择第二个。

就像命令性示例中一样,您将从最一般的概念开始,并逐步进行详细介绍。“ TO段落”的想法是,您可以在获得足够详细的信息后在某个点停止阅读,而不必上下跳动页面。这里肯定是这种情况。

几个名称可能会更好,但是它们是该语言的通用约定,尤其是在编写通用的高阶函数时。高阶函数名称也不能很好地转换为命令式动词短语,如书中的示例,因为它们更多地描述了动词之间的关系。

有一些方法不遵循“ TO段落”准则。放弃显式类型签名将忽略更高级别的“概述”语句。您可以使用if表达式来进行错误处理,而不要使用模式匹配,这会不恰当地与另一个抽象级别混淆。你可以内联maxBy作为匿名函数,而不必给它提供一个稍后将详细描述的名称。

实际上,我认为像这样的构造where实际上适合段落格式,因为您可以使用它们以更详细的名称命名,其方式与我们用英语表达方式相近,并且类似地将其范围限制为明确“段落”上下文的方式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.