Aplicando los principios del Código Limpio a lenguajes funcionales


16

Actualmente estoy leyendo el Código Limpio de Robert Martin . Creo que es genial, y cuando escribo código OO, tomo sus lecciones muy en serio. En particular, creo que su consejo de usar funciones pequeñas con nombres significativos hace que mi código fluya mucho más suavemente. Se resume mejor con esta cita:

[W] Deseamos poder leer el programa como si fuera un conjunto de párrafos TO, cada uno de los cuales describe el nivel actual de abstracción y hace referencia a los siguientes párrafos TO en el siguiente nivel inferior.

( Código limpio , página 37: un "párrafo TO" es un párrafo que comienza con una oración expresada en infinitivo. "Para hacer X, realizamos los pasos Y y Z". "Para hacer Y, nosotros ...", etc. ) Por ejemplo:

PARA RenderPageWithSetupsAndTeardowns, verificamos si la página es una página de prueba y, de ser así, incluimos las configuraciones y desmontajes. En cualquier caso, representamos la página en HTML

También escribo código funcional para mi trabajo. Los ejemplos de Martin en el libro definitivamente se leen como si fueran un conjunto de párrafos, y son muy claros, pero no estoy tan seguro de que "lea como un conjunto de párrafos" sea una cualidad deseable para que el código funcional tenga .

Tomando un ejemplo de la biblioteca estándar de 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

Eso es lo más lejos posible del consejo de Martin, pero ese es Haskell conciso e idiomático. A diferencia de los ejemplos de Java en su libro, no puedo imaginar ninguna forma de refactorizar eso en algo que tenga el tipo de cadencia que solicita. Sospecho que Haskell, escrito según el estándar del Código Limpio, se consideraría insoportable y antinatural.

¿Me equivoco al considerar (al menos algunos de) Clean Code en desacuerdo con las mejores prácticas de programación funcional? ¿Hay alguna manera sensata de reinterpretar lo que dice en un paradigma diferente?


1
Los programadores funcionales tienden a escribir código demasiado breve, es cierto. Sin embargo, no lo consideraría remotamente una mejor práctica, incluso en ese entorno.
Telastyn

Perdona la ignorancia, pero ¿qué es un párrafo TO?
Shashank Gupta

44
Como se mencionó en otra pregunta recientemente, Dijkstra escribió sobre la necedad de la "programación en lenguaje natural" y tiendo a estar de acuerdo con él en que el código que se lee como prosa es un sueño imposible. Creo que esto es especialmente cierto en Haskell que, siendo puro, simbólicamente expresa igualdades entre valores en lugar de secuencias de pasos para producir efectos. Creo que lo importante es que el código citado es idiomático. Por ejemplo, xses un mal nombre, pero es tan común en los lenguajes funcionales como ien las variables de bucle.
Doval

@ShashankGupta Edité la pregunta con un enlace a la página específica del libro, así como mi propia comprensión de lo que escribió el tío Bob.

@ShashankGupta Él da algunos ejemplos, pero la idea es que se lea como prosa. "PARA encontrar el máximo de la lista, verifica cada elemento ..."
Patrick Collins

Respuestas:


11

Clean Code es ante todo un manual de estilo. Strunk and White no se aplica cuando escribes en klingon. La idea es que quieras ser claro para los programadores que probablemente leerán tu código. Desea tener un código modularizado y fácil de reestructurar. Hay formas de hacer esto en Haskell al igual que hay formas de hacerlo en cualquier otro idioma, pero los detalles precisos variarán.

Dicho esto, hay una serie de pautas de estilo para Haskell. Stack Overflow también tiene una guía bastante completa . Mantener la lógica de codificación sencilla y breve parece ser bastante constante. La generalización de las funciones también se destaca porque conduce a la modularidad. El código DRY también se enfatiza, igual que con Clean Code.

Al final, Clean Code y las pautas de codificación de Haskell se esfuerzan por lo mismo, pero terminan tomando sus propios caminos para llegar allí.


1
Siento que esta respuesta descuenta los principios que enseña Clean Code que son muy aplicables en todos los idiomas, y eso es fundamental para la pregunta formulada. Puedo ver por qué la gente piensa en Clean Code como un manual de estilo, y creo que es en parte cierto, pero no lo suficiente como para descartar todo el libro como tal.
Allan

No pienso en el libro Martin's Clean Code como manual de estilo. Siento que las enseñanzas del libro realmente encajan en algún lugar entre una guía de estilo y patrones de diseño.
Michael R

15

No estoy seguro de seguir lo que quieres decir con tu ejemplo. Los párrafos, tal como los describe, no requieren una prolongada falta de aire. No quiere decir que el código debería leerse como inglés. La parte importante es la agrupación de funcionalidades en el mismo nivel de abstracción, en una progresión lógica. Ese es un concepto estructural teórico que trasciende los paradigmas de programación.

Expresado en el formato "TO párrafo" de Bob Martin, leí tu ejemplo como:

  • Para calcular el maximumBy, necesita una función de orden y una lista, y el resultado es un elemento de esa lista.
  • Calcular el maximumByde una lista vacía y cualquier función de orden es un error.
  • Para calcular el maximumByde una lista xs, dobla esa lista usando la maxByfunción.
  • Para calcular los maxBydos elementos de la lista, los compara utilizando la función de ordenamiento dada. Si el primer elemento es mayor, elíjalo. De lo contrario, elija el segundo.

Estás comenzando con los conceptos más generales y progresando a más detalles, tal como en los ejemplos imperativos. La idea de los "párrafos TO" es que puede dejar de leer en cierto punto cuando haya obtenido suficientes detalles, sin tener que saltar de arriba a abajo de la página. Ese es ciertamente el caso aquí.

Quizás algunos de los nombres podrían ser mejores, pero son convenciones comunes del lenguaje, especialmente cuando se escriben funciones genéricas de orden superior. Los nombres de funciones de orden superior tampoco se traducen bien en frases verbales imperativas como los ejemplos en el libro, porque describen más las relaciones entre verbos.

Hay formas de implementar esto que no siguen las pautas del "párrafo TO". Dejar de lado la firma de tipo explícito omitiría la oración de "visión general" de nivel superior. Podría usar una expresión if para el manejo de errores en lugar de la coincidencia de patrones, lo que podría confundirlo de manera inapropiada con otro nivel de abstracción. Puede alinearse maxBycomo una función anónima en lugar de darle un nombre que se puede describir más adelante con más detalle.

De hecho, creo que las construcciones como en whererealidad se ajustan mejor al formato de párrafo, porque puede usarlas para dar un nombre a un detalle más profundo de una manera cercana a cómo lo expresamos en inglés, y de manera similar limitar su alcance en un camino claro al contexto del "párrafo".

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.