Applicazione dei principi di Clean Code alle lingue funzionali

15

Attualmente sto leggendo Codice pulito di Robert Martin . Penso che sia grandioso, e quando scrivo il codice OO sto prendendo a cuore le sue lezioni. In particolare, penso che il suo consiglio di usare piccole funzioni con nomi significativi faccia fluire il mio codice molto più agevolmente. La cosa migliore è riassunta da questa citazione:

[W]e want to be able to read the program as though it were a set of TO paragraphs, each of which is describing the current level of abstraction and referencing subsequent TO paragraphs at the next level down.

( Pulisci codice , pagina 37: un "paragrafo TO" è un paragrafo che inizia con una frase espressa nell'infinito. "Per fare X, eseguiamo i passi Y e Z." "Per fai Y, noi ... "ecc.) Ad esempio:

TO RenderPageWithSetupsAndTeardowns, we check to see whether the page is a test page and if so, we include the setups and teardowns. In either case we render the page in HTML

Scrivo anche codice funzionale per il mio lavoro. Gli esempi di Martin nel libro sicuramente sono letti come se fossero una serie di paragrafi, e sono molto chiari - ma non sono così sicuro che "si legge come un insieme di paragrafi" è una qualità desiderabile per il codice funzionale di avere .

Prendendo esempio dalla libreria standard 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

Questo è il più lontano che si possa ottenere dal consiglio di Martin, ma questo è conciso, idiota Haskell. A differenza degli esempi di Java nel suo libro, non riesco a immaginare un modo per ricondurlo a qualcosa che ha il tipo di cadenza che chiede. Sospetto che Haskell abbia scritto sullo standard di Clean Code sarebbe venuto fuori tempo e innaturale.

Ho sbagliato a considerare (almeno alcuni) Pulisci codice in contrasto con le best practice di programmazione funzionale? Esiste un modo ragionevole per reinterpretare ciò che dice in un diverso paradigma?

    
posta Patrick Collins 28.08.2014 - 00:14
fonte

2 risposte

11

Clean Code è prima di tutto un manuale di stile. Strunk and White non si applica quando stai scrivendo in Klingon. L'idea è che vuoi essere chiaro ai programmatori che leggeranno probabilmente il tuo codice. Vuoi avere un codice che sia modulare e facile da ristrutturare. Ci sono modi per farlo in Haskell così come ci sono modi per farlo in qualsiasi altra lingua, ma i dettagli precisi possono variare.

Detto questo, ci sono un certo numero di linee guida di stile là fuori per Haskell. Stack Overflow ha anche una guida abbastanza completa. Mantenere la logica di codifica semplice e breve sembra essere abbastanza costante. Anche la generalizzazione delle funzioni viene sottolineata poiché conduce alla modularità. Anche il codice DRY è stressato, come con Clean Code.

Alla fine, Clean Code e le linee guida di codifica di Haskell cercano la stessa cosa, ma finiscono per prendere le proprie strade per arrivarci.

    
risposta data 28.08.2014 - 00:41
fonte
13

Non sono sicuro di seguire ciò che intendi con il tuo esempio. I paragrafi, come li descrive, non richiedono prolisso tempo. Non significa che il codice dovrebbe leggere come l'inglese. La parte importante è il raggruppamento di funzionalità allo stesso livello di astrazione, in una progressione logica. Questo è un concetto strutturale teorico che trascende i paradigmi di programmazione.

Espresso nel formato "TO paragrafo" di Bob Martin, ho letto il tuo esempio come:

  • Per calcolare maximumBy , hai bisogno di una funzione di ordinamento e di un elenco e il risultato è un elemento di tale elenco.
  • Per calcolare il maximumBy di una lista vuota e qualsiasi funzione di ordinamento è un errore.
  • Per calcolare il maximumBy di una lista xs , passi su quell'elenco usando la funzione maxBy .
  • Per calcolare il maxBy di due elementi dell'elenco, li confronti utilizzando la funzione di ordinamento fornita. Se il primo elemento è maggiore, sceglilo. Altrimenti scegli il secondo.

Stai iniziando con i concetti più generali e procedendo con maggiori dettagli, proprio come negli esempi imperativi. L'idea dei "paragrafi TO" è che puoi smettere di leggere a un certo punto quando hai ottenuto abbastanza dettagli, senza dover saltare su e giù per la pagina. Questo è certamente il caso qui.

Un paio di nomi potrebbero forse essere migliori, ma sono convenzioni comuni della lingua, specialmente quando si scrivono funzioni generiche di ordine superiore. Anche i nomi delle funzioni di ordine superiore non si traducono bene in frasi verbali imperative come gli esempi nel libro, perché descrivono più le relazioni tra i verbi.

Ci sono modi per implementare ciò che non segue le linee guida del "paragrafo TO". Lasciando fuori la firma del tipo esplicito ometterebbe la frase "panoramica" di livello superiore. È possibile utilizzare un'espressione if per la gestione degli errori anziché la corrispondenza del modello, che potrebbe confondere tale inopportunamente con un altro livello di astrazione. Puoi definire maxBy come una funzione anonima anziché assegnargli un nome che possa essere descritto più avanti in seguito.

In effetti, penso che costrutti come where in realtà siano migliori adatti al formato di paragrafo, perché puoi usarli per dare un nome ad un dettaglio più profondo in un modo che è vicino a come lo esprimiamo in inglese e limitiamo allo stesso modo la sua portata in modo chiaro al contesto del "paragrafo".

    
risposta data 28.08.2014 - 03:05
fonte

Leggi altre domande sui tag