Recientemente, estaba desarrollando un conjunto de estándares de codificación para nuestra empresa. (Somos un nuevo equipo que se ramifica en un nuevo idioma para la empresa).
En mi primer borrador, establecí el propósito de nuestros estándares de codificación para mejorar la legibilidad, la mantenibilidad, la confiabilidad y el rendimiento. (Ignoré la capacidad de escritura, portabilidad, costo, compatibilidad con estándares anteriores, etc.)
Uno de mis objetivos al escribir este documento era impulsar la idea de la simplicidad del código. La idea era que solo debería haber una llamada de función u operación por línea. Mi esperanza era que esto aumentaría la legibilidad. Es una idea que llevé de nuestro idioma anterior.
Sin embargo, he cuestionado la suposición detrás de este impulso:
¿La simplicidad siempre mejora la legibilidad?
¿Hay algún caso donde escribir código más simple disminuye la legibilidad?
Debería ser obvio, pero por "más simple", no me refiero a "más fácil de escribir", sino menos cosas por línea.
fuente
a = b
es una operación,b + c
es una segunda, lo que significa quea = b + c
es 2 operaciones. El encadenamiento de 2 funciones / operadores sigue siendo legible:foo(bar())
oa = foo()
.Respuestas:
"Simple" es una palabra usada en exceso. "Legible" se puede definir de manera rentable como "simple de entender", en cuyo caso el aumento de (esta medida de) simplicidad por definición aumenta la legibilidad, pero no creo que esto sea lo que quiere decir. He escrito sobre esto en otra parte , pero en general algo se puede llamar "más simple", ya sea por ser más abstracto (en cuyo caso, menos conceptos pueden expresar más fenómenos) o por ser más concreto (en cuyo caso un concepto no requiere tantos antecedentes). conocimiento para entender en primer lugar). Estoy argumentando que, dependiendo de la perspectiva, un concepto más abstracto puede razonablemente llamarse más simple que un concepto más concreto, o viceversa . Esto, aunque sea "abstracto" y "
Usaré como ejemplo un código de Haskell que escribí hace un tiempo. Hice una pregunta en stackoverflow sobre el uso de la mónada List para calcular un contador en el que cada dígito podría tener una base diferente. Mi solución final (sin saber mucho Haskell) se veía así:
Una de las respuestas redujo esto a:
Cuál de estos es "más simple" de entender (es decir, más legible) depende completamente de cuán cómodo se haya sentido el lector con las operaciones monádicas (abstractas) (y, para el caso, el código sin puntos). Un lector que se sienta muy cómodo con estos conceptos abstractos preferirá leer la versión (más corta) más abstracta, mientras que el que no se sienta cómodo con esas operaciones preferirá leer la versión (más larga) más concreta. No hay una respuesta única sobre qué versión es más legible para todos.
fuente
mapM
es bastante idiomático yenumFromTo
hace exactamente lo que dice en la lata. En general, creo que es más fácil cometer errores uno por uno si expande el código, simplemente hay más código para cometer un error. Esto es especialmente evidente con cosas como para bucles frente a procedimientos de orden superior en otros idiomas , pero creo que es un principio general.Si su estándar de codificación se trata de "Legibilidad, mantenibilidad, confiabilidad y rendimiento" , simplemente dígalo .
No intente y prescriba cómo lograr estas cosas, ya que siempre habrá situaciones en las que haya un contraejemplo.
Lo que debe prescribir son cosas que harán que el código se rompa si no se cumple también. Los rasgos estilísticos no romperán el código y deberían ser sugerencias (siempre y cuando la mayoría del equipo esté de acuerdo en que es legible, el resto debe ser una preferencia del desarrollador (con revisión de código para que la presión de grupo recuerde a las personas que otras personas necesitan leer el código)) .
fuente
Menos "cosas por línea", simplicidad y legibilidad no son lo mismo. Uno puede tomar un algoritmo indocumentado oscuro increíblemente complicado y codificarlo con 1 declaración por línea en lugar de 2, y no será mucho más legible.
Menos "cosas por línea" también podría requerir suministrar a los desarrolladores grandes monitores altos y altos para ver los bloques de código que ahora se extienden más verticalmente. O causar fatiga visual al leer fuentes más pequeñas.
La legibilidad es su propia métrica, que a menudo requiere un compromiso entre varias otras métricas más fáciles de medir. Restrinja previamente todas esas otras métricas, y el compromiso ya no es posible, lo que resulta en un código menos legible.
fuente
¿Siempre? - NO
Irónicamente, alcanzar el nivel correcto de simplicidad puede ser una tarea compleja. Creo que la clave está en la moderación. La simplicidad también puede estar en el ojo del espectador, por lo que si te estás pensando demasiado, simplemente déjalo en paz o vuelve a hacerlo más tarde.
Personalmente, cuando trato de regresar y simplificar algo que he escrito, me concentro en las áreas en las que cambié de opinión o probé un par de cosas para obtener lo que quería. Esas áreas generalmente se pueden suavizar. Luego, solo haga un par de pasadas a través del código para que sea más legible sin extender tanto las cosas que salte por todo el lugar para descubrir qué está sucediendo en una depuración.
fuente
Si busco simplicidad, puedo escribir código como este:
Pero si busco legibilidad, preferiré esto:
Por otro lado,
1000
es mucho más legible y simple que a1e3
menos que trabajes con números en notación científica todo el tiempo.Este es un ejemplo degenerado de un patrón mucho más general que puede encontrar en casi cualquier lugar: construir algo a partir de bloques muy simples puede volverse rápidamente ilegible / ineficiente / malo de muchas maneras diferentes. Generalizar y reutilizar, por otro lado, es más difícil al principio ("
e
¿qué es eso1343
? ¿Querían escribir ?", Alguien podría decir), pero a la larga puede ayudar mucho.fuente
100
tuvieras que realizar dos multiplicaciones y dos sumas (0+10*(0+10*1)
). Sin embargo, habiendo acostumbrado a esta notación, ni siquiera lo notas. Esto muestra nuevamente cuán subjetiva puede ser la noción de simplicidad.No necesariamente. Si tiene una operación compleja, esa complejidad tiene que ir a algún lado. Reducir el número de "cosas" que van en una línea solo significa que ocupará más líneas, lo que en realidad puede ser perjudicial para la legibilidad del código si hace que su rutina sea demasiado "alta" para caber en una pantalla.
fuente
G=0
, creo que estás loco. Si no lo estás, te estás perdiendo mi punto. Ciertamente puede abstraer detalles irrelevantes, pero no es irrelevante si sus requisitos dicen que es relevante. Si lees de nuevo, nunca afirmé que toda la complejidad es necesaria, solo que cierta complejidad es inherente a los requisitos y no se puede eliminar.Claridad + Estándares + Reutilización de código + Buenos comentarios + Buen diseño podría mejorar la legibilidad .
La simplicidad no siempre está en manos del desarrollador debido a la naturaleza de los algoritmos y la complejidad de la estructura de la aplicación en estos días.
Tome las páginas web simples que realizan tareas simples. Dada una rutina de clasificación, no es posible simplificar la lógica, pero puede aclararla con comentarios, usar nombres de variables significativos, escribirlos de manera estructurada, etc.
fuente
No. He visto muchos casos en los que hacer varias cosas más simples en una línea es menos complejo que tener varias líneas.
Existe una compensación entre menos código y un código más simple.
En general, recomendaría buscar un código más simple a menos que esté seguro de que hacerlo en menos líneas es mejor. Preferiría tener un código "demasiado detallado" sobre un código "demasiado complejo".
fuente
"Hacer las cosas lo más simple posible, pero no más simple" - Una paráfrasis a menudo de Albert Einstein
La simplicidad mejora todo . Para diferentes valores de simplicidad, por supuesto. ¿Son menos líneas de código? Tal vez. ¿Es un ejecutable más pequeño? Posiblemente. ¿Es algo en lo que su equipo necesita estar de acuerdo? Absolutamente .
fuente
¿La simplicidad siempre mejora la legibilidad? Sí. ¿Es una declaración por línea siempre más simple? No. Muchos idiomas tienen un operador ternario que, una vez comprendido, es más simple y fácil de entender que las asignaciones equivalentes if / else.
En los lenguajes que permiten establecer múltiples variables en una línea, hacerlo es con frecuencia más simple y fácil de entender que el equivalente.
Otro ejemplo: las expresiones regulares hacen mucho, generalmente en una sola línea, y el equivalente sin una expresión regular es con frecuencia mucho más difícil de leer. / \ d {3} [-] \ d {3} - \ d {4} / es el equivalente de una llamada a la función con al menos varios comentarios, y es más fácil de entender que el cuerpo de la función correspondiente.
fuente
La legibilidad y la simplicidad son términos subjetivos que, dependiendo de la persona y el contexto, generalmente pero no siempre van de la mano.
Un término más objetivo es concisión, algo que en principio se podría contar contando caracteres, aunque hay algunos defectos en eso. La concisión parece implicar simplicidad y legibilidad, pero hay excepciones (al menos en mi opinión).
Un fragmento de código más largo (y posiblemente más complejo) puede ser más legible si expresa mejor la intención. Si su definición de simplicidad se preocupa por la intención es otra cosa subjetiva: podría definir la complejidad en términos de la estructura sintáctica y la entropía de la teoría de la información, por ejemplo, sin referencia alguna a las intenciones.
Entonces, un nombre de variable más largo bien elegido puede ...
Del mismo modo, podría escribir
if (some_boolean == true)
. En comparación con la alternativa equivalenteif (some_boolean)
, esto ...Por supuesto, esto desencadenará una protesta masiva: para muchas personas, esto siempre daña la legibilidad también. Para mí, depende mucho de la fuente del booleano, por ejemplo, el nombre de la variable (o el nombre del método o lo que sea) puede no expresar claramente que el valor es "valor de verdad". Claro,
if
te dice algo, pero aún huele. Pero mucha gente me llamará idiota por creer esto.Lo cual es una prueba más de la subjetividad general, por supuesto.
fuente
A todos les faltan algunas definiciones fundamentales . Simple, desde la raíz sim-plex , significa un pliegue . Simple significa hacer una cosa . Fácil, de la raíz facilidad , los medios se encuentran cerca . Fácil significa que está al alcance de la mano . Los ejemplos de código simple que figuran en otras respuestas no son exactamente lo que parecen.
Tome la exhibición de Rotsor de un valor muy grande. Él dice que esto es simple . No es, en mi opinión, simple. Es fácil. Está a mano para escribir el número de ceros requeridos.
La versión legible es simple. Hace una cosa Expresa el número describiendo su tamaño en un propósito de notación construido para esta función.
¿Podría describir el fragmento de código "simple" de Aidan como una cosa? Contiene 10 líneas de código (sin contar los comentarios) y al menos 7 bloques (como yo los contaría). ¡Si sigues los comentarios, verás que hace al menos 4 cosas!
Pero, una de las recomendaciones para reescribir este código fue una declaración. Aidan afirma que un lector tendría que estar familiarizado con las declaraciones monádicas, el código sin puntero, etc. Está bien. Esos conceptos son singulares e independientes para aprender.
Encontrará que el código verdaderamente simple es más legible que el código fácil porque solo hace una cosa. Es posible que deba salir y aprender más "cosas únicas" para comprender el código simple. Pero siempre debería ser más legible.
fuente
Yo diría, tal vez con un poco de controversia, absolutamente no .
Podrías entregarme una clase con 200 funciones miembro en su interfaz pública, y puede ser la interfaz pública más legible por humanos que existe. Puede ser una alegría leer de forma casual dicho código y su documentación. Sin embargo, no lo llamaría "simple", porque a pesar de la legibilidad, tendría que preocuparme por la forma en que todas estas funciones interactúan entre sí y, potencialmente, estar atento a los casos extremos difíciles derivados del mal uso.
Preferiría una clase con 20 funciones miembro que no fueran tan fáciles de leer a 200, porque la "legibilidad" no es la máxima prioridad para mí en términos de prevenir errores humanos y mejorar la facilidad de mantenimiento del código (la facilidad con la que podemos cambiarlo, es decir).
Sin embargo, todo esto dependerá de nuestra definición personal de "simplicidad". "Legibilidad" normalmente no varía que violentamente entre nosotros, a menos que alguien ha adquirido tanta experiencia y fluidez que consideran expresiones regulares que ser muy "legible", por ejemplo, olvidar el resto de los mortales.
Sencillez
Hubo un tiempo, hace mucho tiempo, en el que pensaba que "simplicidad" significaba "lo más fácil de leer posible". Entonces escribiría código C con muchas funciones convenientes, tratando de mejorar la sintaxis y hacer las cosas lo más fáciles de leer y escribir posible.
Como resultado, diseñé bibliotecas muy grandes, ricas y de alto nivel, tratando de modelar una función para cada pensamiento humano natural: ayudantes sobre ayudantes sobre ayudantes, todo para dar forma al código del cliente a una sintaxis más legible. El código que escribí en ese momento puede haber sido el más "legible", pero también fue el más "imposible de mantener" y "complejo".
Ceceo
Sin embargo, tuve una breve pasión con LISP a mediados de los 90 (recién llegado). Cambió toda mi idea de "simplicidad".
LISP no es el lenguaje más legible. Esperemos que nadie piense que extraer CDR y CAR mientras se invoca una función recursiva con una gran cantidad de paréntesis anidados es muy "legible".
Sin embargo, después de luchar para que mi cerebro se envolviera en la sintaxis extraña del lenguaje y las formas totalmente recursivas de hacer las cosas, cambió permanentemente mi idea de simplicidad.
Lo que encontré con el código que escribí en LISP es que ya no estaba cometiendo errores sutiles, a pesar de que el truco de pensar de esa manera me hizo cometer errores más evidentes (pero son fáciles de detectar y corregir). No entendía mal lo que estaba haciendo una función y me perdía un efecto secundario sutil e inesperado. En general, me estaba resultando más fácil hacer cambios y escribir programas correctos.
Después de LISP, la simplicidad para mí se convirtió en minimalismo, simetría, flexibilidad, menos efectos secundarios, menos funciones pero más flexibles que se combinan en una infinita variedad de formas.
Llegué a apreciar la mentalidad de que el código más confiable de todos es el código que no existe. Si bien es solo una métrica cruda, tiendo a ver el potencial de falta de confiabilidad del código en función de su cantidad. La búsqueda de la máxima comodidad sintáctica y legibilidad tiende a aumentar esa cantidad en un factor importante.
Minimalismo
Con la mentalidad de LISP incrustada en mí, llegué a preferir API minimalistas. Prefiero una biblioteca con menos funciones, pero más confiables y flexibles, que sean menos convenientes y potencialmente más difíciles de leer que una que ofrezca una gran cantidad de ayudantes "convenientes" y que pueda hacer que el código sea fácil de "leer" pero potencialmente tropezar Más problemas con la falta de fiabilidad y las sorpresas que resultan de la mala interpretación de una de estas miles de funciones.
La seguridad
Otra cosa sobre LISP era la seguridad. Promovió efectos secundarios mínimos y funciones puras, y fue allí donde ya no me veía cometiendo errores sutiles, a pesar de que la dificultad de leer y escribir en el idioma aumentó los errores más evidentes que pude detectar 10 segundos después.
Las funciones puras y los estados inmutables se volvieron preferibles para mí cada vez que podía pagarlo, incluso si la sintaxis de:
... es un poco menos directo y distante del pensamiento humano que:
Legibilidad VS. Sencillez
Una vez más, LISP no es el lenguaje más "legible". Puede empaquetar mucha lógica en una pequeña sección de código (posiblemente más de un pensamiento humano por línea). Tiendo a preferir idealmente un pensamiento humano por línea para "legibilidad", pero no necesariamente para "simplicidad".
Con este tipo de definición de "simple", a veces "simple" en realidad podría competir con "legible". Esto está considerando las cosas más desde el punto de vista del diseño de la interfaz.
Una interfaz simple significa que necesita aprender muchas menos cosas para usarlo, y potencialmente tiene una mayor confiabilidad y menos problemas como resultado de su minimalismo. Una documentación completa sobre el tema podría encajar en un folleto en lugar de un volumen masivo de libros. Sin embargo, puede requerir un poco más de trabajo duro y generar un código menos legible.
"Simple" para mí mejora nuestra capacidad de comprender la funcionalidad de nuestro sistema a un nivel amplio. "Legible" para mí mejora nuestra capacidad de conectar cada pequeña línea de código con el lenguaje natural y el pensamiento, y podría acelerar nuestra comprensión de lo que hace una línea de código, especialmente si no hablamos el idioma con fluidez.
Regex es un ejemplo de lo que considero "extremadamente simple". Es "demasiado simple e ilegible" para mi gusto personal. Hay un acto de equilibrio para mí entre estos extremos, pero regex tiene esa calidad de simplicidad similar a LISP como la defino: minimalismo, simetría, flexibilidad increíble, confiabilidad, etc. El problema para mí con regex es que es tan simple que se ha vuelto tan ilegible hasta el punto en que no creo que pueda hablarlo con fluidez (mi cerebro simplemente no funciona de esa manera y envidio a las personas que pueden escribir código regex con fluidez).
De todos modos, esa es mi definición de "simplicidad", y es completamente independiente de la "legibilidad" y, a veces, incluso puede interferir con la otra, lo que lleva a un acto de equilibrio entre una biblioteca más "sintácticamente conveniente" y legible pero más grande o una "sintácticamente". inconveniente ", menos legible, pero más pequeña biblioteca. Siempre he encontrado la verdadera "conveniencia de comprender" y las verdaderas prioridades de "mantenibilidad" para alinearse con esta última, con la fuerte preferencia hacia el minimalismo incluso a un costo de legibilidad y sintaxis humana más natural (pero no hasta el punto de la expresión regular) . YMMV.
fuente
¿Siempre? - SI
Alcanzar el nivel correcto de simplicidad es una tarea compleja y difícil. Pero siempre vale la pena, ya que siempre mejora la legibilidad. Creo que la clave es una comprensión profunda. La simplicidad es un absoluto, medido por "nuevos conceptos" por "fragmento" de código. Algunos conceptos nuevos significan más simple.
Concéntrese en las áreas donde hay un grupo de conceptos densos y encuentre formas de "fragmentar" o "resumir" o "resumir". Haga un par de pasadas por el código para hacerlo más simple y legible.
Una buena abstracción vale su peso en oro. Una buena abstracción lo hace más simple y, en consecuencia, más legible.
fuente
Las preguntas me recuerdan esta respuesta en Stack Overflow, particularmente esta cita (sustituir calidad por simplicidad):
Creo que es importante que tenga en cuenta que un estándar de codificación codificado para todos sus beneficios no convertirá a los buenos programadores en malos. Una palabra como 'simple' puede ser interpretada de manera diferente por diferentes personas (ver la respuesta de Aidan Cully), pero eso puede no ser tan malo. Los programadores junior aún necesitarán que sus programadores revisen su código y aprendan por qué la interpretación de los programadores senior de 'simple' es mejor que la suya.
fuente
¿Una llamada de función por línea es más simple? ¡Probemos un ejemplo!
¿Qué piensas? ¿Una llamada por línea es realmente más simple?
fuente