Está en la página 1de 7

Cmo y porqu programar con buen estilo

Porqu
Sobre los lenguajes de programacin
Un lenguaje de programacin es, como todo lenguaje, una forma de comunicacin. Es decir, permite transmitir informacin entre dos entidades de forma que la idea original del transmisor pueda ser recuperada por el receptor. Los lenguajes de programacin tienen la particularidad de cumplir un doble rol. Por un lado sirven para comunicar humanos con computadoras. Son la forma de transformar una serie de abstracciones como algoritmos, mdulos, tipos de datos y sistemas en algo que una computadora pueda ejectuar. El segundo rol, y que no se ve tanto a primera vista, es que un lenguaje de programacin sirve para comunicar humanos con humanos. Por ejemplo, para que alguien le cuente un algoritmo a otro. O en muchos casos para que un programador pueda maana recuperar las ideas que volc en cdigo hoy. La capacidad de expresar un significado usando un lenguaje depende tanto del lenguaje, como del emisor. Pero el emisor usualmente influye mucho ms: es claro que la forma de construir un mensaje puede impactar muy fuertemente en su claridad. En el caso de los lenguajes de computadoras, la claridad tambin depende de a quien se dirija el lenguaje. Por ejemplo, para lo computadora son equivalentes las funciones:
float f(float a, float b) {return a*b ;}

typedef float longitud ; typedef float area ; area area_rectangulo (longitud base, longitud altura) { /* Devuelve el area de un rectangulo de base `b' y altura `h' */ return base*altura ; }

Pero a una persona le transmite mucha ms informacin y contenido la segunda funcin. En el sentido inverso, para la mayora de la gente son iguales:
a = 1 b = 2

a = 1 ; b = 2 ;

Aunque una computadora probablemente se confunda por los errores de sintaxis (los ';' faltantes).

Los objetivos
Dado lo anterior, debera ser clara la motivacin para poner atencin en el estilo de programacin. Los

aspectos que normalmente se denominan "estilo" son aspectos relacionados a los lenguajes como medio de comunicacin entre personas, y que usualmente no influyen en la comunicacin humano-mquina. La meta final del programador es construir programas. Y el ideal es construir "buenos" programas. Hay diversas cualidades generalmente aceptadas de lo que es un programa "bueno", y cualquier herramienta, tcnica o mtodo que nos ayude a mejorar esas cualidades es bienvenida. Las cualidades que se ven beneficiadas de forma ms directa por un buen estilo son:

Extensibilidad: La facilidad con que se adapta el software a cambios de especificacin. Un buen estilo de cdigo fomenta programas que no slo resuelven el problema, sino que tambin reflejan claramente la relacin problema/solucin. Esto tiene como efecto que muchos cambios simples en el problema reflejen de forma obvio los cambios a hacer en el programa. Verificabilidad: la facilidad con que pueden comprobarse propiedades de un sistema. Si el estilo de cdigo hace obvia la estructura del programa, eso ayuda a verificar que el comportamiento sea el esperado. Reparabilidad: la posibilidad de corregir errores sin demasiado esfuerzo. Capacidad de evolucin: la capacidad de adaptarse a nuevas necesidades. Comprensibilidad: la facilidad con que el programa puede ser comprendido.

Cmo
Principios
1. El estilo del cdigo no es un resultado final, sino algo para preservar a lo largo de toda su escritura. Motivo: Es cierto que las primeras veces escribir con estilo requiere un esfuerzo consciente, una vez que uno se acostumbra al estilo, seguirlo deja de ser un esfuerzo adicional. Usualmente es ms trabajo "arreglar un cdigo despus, que escribirlo bien desde el principio". 2. El estilo debe ser uniforme en un mismo proyecto. Motivo: Al leer un cdigo, uno se acostumbra al estilo usado en una forma que permite entenderlo con un vistazo general. Si hay cdigo con estilos mezclados, leer algo con un estilo despus de haberse acostumbrado a leer algo con otro puede ser confuso. Por ejemplo, si dos tramos de cdigo usan distintas abreviaturas para lo mismo, o distintas formas de indentar (que pueden hacer que dos estructuras de control iguales se vean diferentes). 3. El estilo de cdigo debe promover programas que pueden ser comprendidos de forma inmediata (suponiendo el conocimiento del problema que ste resuelve). Motivo: Los problemas de computacin ya son complejos y no hay motivo para aumentar su complejidad con cdigo rebuscado. Los programas deberan ser soluciones, no problemas. 4. El estilo no debe promover fragmentos de cdigo que le dan demasiada importancia a detalles irrelevantes. Motivo: Escribir demasiado, le da relevancia a aspectos no fundamentales, y ocupa la atencin en aspectos secundarios del programa. Un buen programa debera enfocar la atencin en lo importante, y permitir abstraerse de los detalles. 5. El estilo de indentacin debe permitir ver la estructura del cdigo sin mirar el cdigo en s (es decir, con solo ver la distribucin de espacio en blanco y espacio escrito). Motivo: Cuando se busca un tramo de programa o se lee rpido, uno puede visualizar la distribucin

de espacio blanco/no blanco pero no tiene tiempo para ver estructuras, o concordancia de parntesis/llaves/corchetes. 6. El estilo de indentacin debe poder usarse de la misma forma en distintos lenguajes y verse similar (para construcciones lingsticas similares). Motivo: Muchas veces es necesario cambiar de lenguaje (entre un proyecto o entre varios), y preservar un estilo uniforme permite no tener que estar fabricando reglas nuevas cada vez. Adems, un estilo que no puede ser preservado, probablemente implica dependencia de lingsmos especficos y no de abstracciones generales. 7. El estilo de cdigo debe permitir fcilmente realizar cambios bsicos en el cdigo: agregar una lnea a un bloque, borrar una lnea de un bloque, mover lneas en un bloque. Motivo: Este tipo de cambios es muy usual, y si el estilo dificulta realizarlos interrumpe en la forma de trabajo. 8. El nombre de un objeto cualquiera del programa (funcin, variable, tipo), debe permitir identificar el objeto de forma no ambigua rpidamente dentro del rea de visibilidad del objeto. Motivo: Un estilo de esta forma permite leer el cdigo sin tener que detenerse en cada identificador a recordar (o buscar) donde estaba definido y que era.

Reglas
No hay un "estilo correcto", sino que hay muchos. Definitivamente hay distintos criterios sobre cul de ellos es el mejor, y discusiones bizantinas al respecto. De todos modos, si hay un acuerdo bastante generalizado sobre varias cosas que se consideran "mal estilo". Las siguientes reglas no son rgidas, sino que buscan cumplir los principios dados antes, y cada una da algunas variantes. Cuando hay variantes para elegir, la idea es elegir una y slo una, y mantenerla, al menos dentro de un mismo proyecto. La mezcla de estilos hace que un lector del cdigo no pueda acostumbrarse a las reglas y tenga que estar mirando el texto del programa cuando quiere ver la estructura. Cundo escribir con estilo? Hay que convencerse de que no hay que decir "escribo el cdigo as noms y despus lo arreglo, total al final voy a tirar un montn de lneas...". Cambios de estilo Las reglas de estilo son flexibles. Esto no significa que uno va escribiendo y cambiando de estilo. Es muy importante dentro de un mismo proyecto mantener siempre las mismas reglas rgidas, aunque estas sean distintas a las que uno usa en otros proyectos. Incluso, cuando se trabaja sobre un proyecto escrito por otro, es mejor adaptarse al estilo en que est escrito en vez de mezclarlos. Cunto escribir Usualmente, se puede hacer variar la forma en un rango que va desde lo abreviado/implcito hasta lo

palabrero/explcito ('terse' y 'verbose' son los trminos ms encontrados en los textos en ingls). Ejemplos:
/* abrev. */ for (i=-1; s[++i];) ;

/* Esta es en cambio la versin palabrera (o 'verbose') del mismo * programa para calcular la longitud de una cadena. */ posicion = 0 ; /* Posicin inicial de la cadena */ caracter = cadena[posicion] ; while (caracter != TERMINADOR_CADENAS) { /* Avanzar a la posicin siguiente */ posicion = posicion + 1 ; caracter = cadena[posicion] ; } longitud = posicion ;

Se aconseja buscar una forma intermedia, que no distraiga la atencin innecesariamente con detalles obvios, pero sin perder claridad:
/* Calcular longitud de s en len*/ len = 0 ; while (s[len] != '\0') len++ ;

Nombres de objetos (variables/funciones) No ayuda nada ahorrarse un par de letras llamando a una variable global pri_ele en vez de primer_elemento (y evitamos confundirla con primo_elegido), o una funcion global strsz (impronunciable) en vez de string_size. Es por ello que se recomienda no usar abreviaturas, a menos que sea una abreviatura clara y ampliamente usada en el rea de aplicacin del software (como AFIP en un sistema contable, o CPU en un programa de diagnstico de hardware). De todas maneras, un nombre excesivamente largo corre peligro de no ser recordado, requiriendo ir y volver a lo largo del cdigo. De sto se deduce que se debe evitar la redundancia (por ejemplo, un campo llamado 'longitud_secuencia' en una estructura 'secuencia' debera en realidad llamarse 'longitud'). Incluso una variable local de contador probablemente pueda llamarse i en vez de contador sin perder claridad (y permitiendo concentrar la atencin en otras cosas). El tamao del cdigo usualmente depende mucho ms del buen diseo que de la longitud de los identificadores. Otra convencin que beneficia la lectura y el entendimiento de un cdigo es el uso adecuado de maysculas/minsculas. En general los nombres de los diveros objetos combinan de manera consistente maysculas/minsculas, en cambio la declaracin de constantes es toda con maysculas. Algunos ejemplos de posibles variantes para nombres de objetos y definiciones:
twoWords twowords two_words

#undef SERIAL_PARANOIA_CHECK #define CONFIG_SERIAL_NOPAUSE_IO #define SERIAL_DO_RESTART #undef CONFIG_SERIAL_CONSOLE #define INT_MIN #define INT_MAX (-INT_MAX - 1) 2147483647

Indentacin Dados los principios anteriores algo esencial en cualquier estilo de indentacin es que las componentes de una instruccin compuesta (es decir, las instrucciones condicionales de un if dentro del if, o las instrucciones que se repiten dentro de un while) deben ir a la derecha de esta instruccin. Hay muchas formas aceptadas de hacer esto, por ejemplo:
if (<cond>) { <body> } /* Conocido como el estilo K&R */ if (<cond>) { <body> } /* Conocido como el estilo BSD */ if (<cond>) { <body> } /* Conocido como el estilo Whitesmiths */ if (<cond>) { <body> } /* Conocido como el estilo GNU */

La cantidad de espacios con que se indenta, tambin es algo para elegir. Normalmente se usa al menos 2, y hasta 8. Lo ms usual es 4 u 8. La ventaja de usar indentacin chica es que se puede ver ms cdigo en la pantalla (o al imprimir), y la de usar indentaciones ms grandes es que la estructura es ms visible. Dado que la mayora de las pantallas/impresoras tienen 80 columnas de texto, conviene no pasarse de ese lmite, partiendo las lneas muy largas. Para indentar se pueden usar TABs o espacios. Para que el cdigo se vea bien en cualquier entorno o editor, hay que ser muy cuidadoso con no mezclar inadecuadamente TABs con espacios. La forma ms fcil es usar solamente espacios. La forma ms elegante es usar TABs para marcar indentacin (al principio del rengln), y espacios para encolumnar cosas cuando se parten lneas o se ponen comentarios a la derecha. Ejemplo:
/* Nota: los --- denotan espacios, y los /######/ TABs */ if (condicin) { /######/instruccin ; /######/while (condicin) { /######//######/instruccin ;----------/* comentario */ /######//######/otra instruccin ;-----/* otro comentario */ /######/} /######/ /* Este tab puede ir o dejarse la lnea en blanco */ /######/if (condicin 1 && /######/----condicin 2 && /* Notar el TAB seguido de espacios */ /######/----condicin 3) { /######//######/instrucciones ;

/######/} }

Cuando se parten expresiones largas en varias lneas conviene partir en los operadores de menos precedencia. Por ejemplo, a[2]==5 || i!=7 conviene partirlo despus del ||, no despus del [ o del ==. Si una lnea larga es un llamado a funcin, conviene separar en las comas que distinguen parmetros. Tambin puede separarse una cadena en dos. Algunos ejemplos (tomados del fuente del kernel de Linux, busmouse.c).
if (put_user((char)buttons | 128, buffer) || put_user((char)dxpos, buffer + 1) || put_user((char)dypos, buffer + 2)) return -EFAULT; printk(KERN_ERR "busmouse: trying to free mouse on" " mousedev %d\n", mousedev);

...

Pueden revisarlos en el archivo anterior, donde adems puede verse la combinacin apropiada de TABs y espacios. Algo que se hace bastante seguido es poner al mismo nivel cadenas de if/else if/else if/.../else, de esta forma:
if (cond1) { bloque 1 } else if (cond2) { bloque 2 } else if (cond3) { bloque 3 } else { bloque 4 }

A pesar de que lingisticamnte cada if y cada bloque debera ir a la derecha del anterior, se usa esta estructura vertical ya que usualmente esa es la estructura del significado del cdigo. Es decir, con lo anterior uno normalmente trata de decir:
if # # # # fi cond1 --> bloque1 cond2 --> bloque2 cond3 --> bloque3 not (cond1 or cond2 or cond3) --> bloque4

Comentarios Es de extremada importancia la inclusin de comentarios dentro de los cdigos. Los mismos facilitan la comprensin del significado y/u objetivo de las funciones, secuencias de control, sentencias en general. O sea, no es necesario comentar cada lnea, sino bloques estratgicos, resultados de retornos de funciones, guardas de if's o de bucles, o declaraciones de variables y/o constantes que jugarn un papel protagonista en el programa.

En general se distinguen las siguientes categoras de comentarios: 1. Comentarios en las funciones/variables: se hace una breve descripcin de la funcionalidad de la rutina o de la variable, destacando el aspecto de relevancia en cada caso. 2. Comentarios en los archivos: la explicacin del contenido del archivo, resumiendo lo que se encierra dentro del mismo, o hablando del TAD que representa, etc. 3. Comentarios en el cdigo: de tipo aclaratorios, slo cuando algo necesita o es digno de una explicacin o justificacin. 4. Comentarios de cierre: aclaraciones relevantes que inducen al entendimiento completo del programa en cuestin. Constantes Para lograr los objetivos planteados inicialmente, y poder introducir modificaciones en el cdigo sin necesidad de rehacer el mismo, debemos tener siempre en cuenta cuntas lneas deberamos retocar ante determinados cambios. Supongamos que estamos trabajando con informacin provista por ciertos archivos. Supongamos adems, que la ruta actual a esos archivos es /home/pepe/info/, y digamos que abrimos archivos en ese directorio unas 100 veces. Cmo impactara (en la actualizacin del cdigo) si de repente pepe deja de existir y toda la informacin se muda a /var/juan/data/? S, abra que modificar unas 100 lneas de cdigo por lo menos, una por cada fopen y unas cuntas ms por cada fclose. Pero podemos ahorrarnos ese trabajo teniendo declarada una constante que representa la ruta al directorio de inters, sea cual sea esa ruta. En nuestro ejemplo, teniendo definido
#define DATA_SOURCE /home/pepe/info

basta con hacer un nico cambio a


#define DATA_SOURCE /var/juan/data

y a lo largo del cdigo utilizar DATA_SOURCE como ruta constante al directorio de inters. Vale aclarar que este ejemplo se extiende a constantes de todo tipo (enteras, flotantes, de caracteres, etc.)

También podría gustarte