Anwendung der Prinzipien von Clean Code auf funktionale Sprachen

16

Ich lese gerade Robert Martins Clean Code . Ich finde es großartig, und wenn ich OO-Code schreibe, nehme ich mir seine Lektionen zu Herzen. Insbesondere denke ich, dass sein Rat, kleine Funktionen mit aussagekräftigen Namen zu verwenden, meinen Code viel flüssiger macht. Es ist am besten mit diesem Zitat zusammengefasst:

[W] Wir möchten das Programm so lesen können, als ob es eine Menge von TO-Absätzen wäre, von denen jeder die aktuelle Abstraktionsebene beschreibt und auf nachfolgende TO-Absätze auf der nächsthöheren Ebene verweist.

( Bereinigter Code , Seite 37: Ein "TO-Absatz" beginnt mit einem Satz im Infinitiv. "Um X zu tun, führen wir die Schritte Y und Z aus." "Um Y zu tun, führen wir ..." usw. ) Zum Beispiel:

Um PageWithSetupsAndTeardowns zu rendern, überprüfen wir, ob es sich bei der Seite um eine Testseite handelt, und schließen in diesem Fall die Setups und Teardowns ein. In beiden Fällen rendern wir die Seite in HTML

Ich schreibe auch Funktionscode für meinen Job. Martins Beispiele in dem Buch lesen sich definitiv so, als wären sie eine Reihe von Absätzen, und sie sind sehr klar - aber ich bin mir nicht so sicher, ob "wie eine Reihe von Absätzen liest" eine wünschenswerte Eigenschaft für funktionalen Code ist .

Ein Beispiel aus der Haskell-Standardbibliothek entnehmen :

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

Das ist ungefähr so ​​weit weg, wie Sie Martins Rat möglicherweise entziehen können, aber das ist prägnante, idiomatische Haskell. Im Gegensatz zu den Java-Beispielen in seinem Buch kann ich mir keine Möglichkeit vorstellen, dies in etwas umzugestalten, das die Art von Trittfrequenz hat, nach der er fragt. Ich vermute, dass Haskell, der nach dem Standard von Clean Code geschrieben wurde , sich als langwierig und unnatürlich herausstellen würde.

Bin ich falsch, wenn ich Clean Code (zumindest teilweise) in Widerspruch zu den Best Practices der funktionalen Programmierung halte ? Gibt es eine sinnvolle Möglichkeit, das, was er in einem anderen Paradigma sagt, neu zu interpretieren?

Patrick Collins
quelle
1
Funktionale Programmierer neigen dazu, zu knappen Code zu schreiben. Ich würde das nicht im entferntesten als Best Practice betrachten, auch in dieser Umgebung.
Telastyn
Vergib die Unwissenheit, aber was ist ein TO-Absatz?
Shashank Gupta
4
Wie kürzlich in einer anderen Frage erwähnt, schrieb Dijkstra über die Dummheit der "Programmierung in natürlicher Sprache" und ich stimme ihm eher zu, dass Code, der sich wie Prosa liest, ein Wunschtraum ist. Ich denke, dass dies besonders bei Haskell zutrifft, das, da es rein ist, symbolisch die Gleichheit zwischen Werten ausdrückt und keine Abfolge von Schritten, um Effekte zu erzielen. Ich denke, das Wichtigste ist, dass der zitierte Code idiomatisch ist. ZB xsist ein schlechter Name, aber er ist in funktionalen Sprachen genauso verbreitet wie ibei Schleifenvariablen.
Doval
@ShashankGupta Ich habe die Frage mit einem Link zu der bestimmten Seite im Buch bearbeitet und mein eigenes Verständnis dessen, was Onkel Bob geschrieben hat.
@ShashankGupta Er gibt ein paar Beispiele, aber die Idee ist, dass es sich wie Prosa lesen sollte. "Um das Maximum der Liste zu finden, überprüfen Sie jedes Element ..."
Patrick Collins

Antworten:

11

Clean Code ist in erster Linie ein Style-Handbuch. Strunk and White gilt nicht, wenn Sie auf Klingonisch schreiben. Die Idee ist, dass Sie den Programmierern klar sein möchten, die Ihren Code wahrscheinlich lesen werden. Sie möchten modularisierten Code haben, der sich leicht umstrukturieren lässt. Es gibt Möglichkeiten, dies in Haskell zu tun, genauso wie es Möglichkeiten gibt, dies in einer anderen Sprache zu tun, aber die genauen Einzelheiten variieren.

That being said, gibt es eine Reihe von Stil - Richtlinien gibt für Haskell. Stack Overflow hat auch eine ziemlich umfassende Anleitung . Die Codierungslogik einfach und kurz zu halten, scheint ziemlich konstant zu sein. Die Verallgemeinerung von Funktionen wird ebenfalls betont, da dies zu Modularität führt. Wie bei Clean Code wird auch DRY-Code betont.

Letztendlich streben die Codierungsrichtlinien von Clean Code und Haskell dasselbe an, gehen jedoch ihre eigenen Wege, um dorthin zu gelangen.

Weltingenieur
quelle
1
Ich bin der Meinung, dass diese Antwort auf die von Clean Code gelehrten Rabattprinzipien, die für alle Sprachen sehr zutreffend sind, von zentraler Bedeutung für die gestellte Frage ist. Ich kann sehen, warum die Leute Clean Code als Stilhandbuch betrachten, und ich denke, es ist teilweise wahr, aber nicht wahr genug, um das gesamte Buch als ein einziges zu verwerfen.
Allan
Ich halte das Martin's Clean Code-Buch nicht für ein Style-Handbuch. Ich bin der Meinung, dass die Lehren des Buches tatsächlich irgendwo zwischen einem Stilführer und Designmustern liegen.
Michael R
15

Ich bin mir nicht sicher, ob ich dem folge, was du mit deinem Beispiel meinst. Absätze, wie er sie beschreibt, erfordern keine Langeweile. Er meint nicht, dass der Code wie Englisch gelesen werden sollte. Der wichtige Teil ist die Gruppierung der Funktionalität auf derselben Abstraktionsebene in einer logischen Folge. Das ist ein theoretisches Strukturkonzept, das über Programmierparadigmen hinausgeht.

In Bob Martins "TO-Absatz" -Format ausgedrückt, lese ich Ihr Beispiel als:

  • Um die zu berechnen maximumBy, benötigen Sie eine Sortierfunktion und eine Liste, und das Ergebnis ist ein Element dieser Liste.
  • Das Berechnen maximumByeiner leeren Liste und einer Bestellfunktion ist ein Fehler.
  • Um die maximumByeiner Liste zu berechnen xs, falten Sie diese Liste mit der maxByFunktion um.
  • Um das maxByvon zwei Listenelementen zu berechnen , vergleichen Sie sie mit der angegebenen Sortierfunktion. Wenn das erste Element größer ist, wählen Sie es aus. Andernfalls wählen Sie die zweite.

Sie beginnen mit den allgemeinsten Konzepten und gehen, genau wie in den zwingenden Beispielen, detaillierter vor. Die Idee der "TO-Absätze" ist, dass Sie an einem bestimmten Punkt mit dem Lesen aufhören können, wenn Sie genug Details erhalten haben, ohne die Seite auf und ab springen zu müssen. Das ist hier sicherlich der Fall.

Ein paar der Namen könnten vielleicht besser sein, aber sie sind gängige Konventionen der Sprache, insbesondere beim Schreiben von generischen Funktionen höherer Ordnung. Funktionsnamen höherer Ordnung lassen sich auch nicht gut in imperative Verbalphrasen wie die Beispiele im Buch übersetzen, da sie die Beziehungen zwischen Verben besser beschreiben.

Es gibt Möglichkeiten, dies zu implementieren, die nicht den Richtlinien für TO-Absätze entsprechen. Wenn Sie die explizite Typensignatur weglassen, wird der übergeordnete Satz "Übersicht" weggelassen. Sie könnten anstelle des Mustervergleichs einen if-Ausdruck für die Fehlerbehandlung verwenden, der dies mit einer anderen Abstraktionsebene verwechselt. Sie könnten maxByals anonyme Funktion inline gehen, anstatt ihr einen Namen zu geben, der später genauer beschrieben werden kann.

Tatsächlich denke ich, dass Konstrukte wie wheretatsächlich besser zum Absatzformat passen, da Sie sie verwenden können, um einem tieferen Detail einen Namen zu geben, der dem entspricht, wie wir ihn auf Englisch ausdrücken, und den Umfang in a auf ähnliche Weise einschränken klarer Weg zum Kontext des "Absatzes".

Karl Bielefeldt
quelle