martes, 15 de enero de 2013

programa

§2  Presentación del problema
Hay bastante literatura sobre programación en general; a los académicos les gusta hablar de "Teoría de la Programación", y mucha gente se ha dedicado a especular sobre el tema. Incluso hay modas al respecto [4].  Es posible confeccionar una lista de las características que "debe" y "no debe" tener un buen programa (incluyendo la del Jefe, que solo tiene dos puntos: "Que esté para ayer;  que salga barato").  El propio Stroustrup ( TC++PL) compara las condiciones para escribir un buen programa con las de escribir buena prosa.  Según él, existen dos respuestas:  "Saber que se quiere decir" y "Práctica.  Imitar buenos escritores".  Más adelante nos recuerda que aprender a manejar bien un lenguaje puede constar tanto tiempo y esfuerzo como aprender a expresarse en un lenguaje natural o tocar un instrumento.
Por supuesto sería un atrevimiento por mi parte contradecir tan docta opinión, pero puestos a filosofar me gustaría puntualizar que el verdadero problema está en el segundo punto de la segunda respuesta; la primera, aunque ciertamente importante, me parece la verdad de Perogrullo .  Siempre me ha parecido que programar (programar bien) tiene mucho de arte.  Me parece que debe ocurrir como con la música; seguramente muchos pueden decir que debe tener una buena ejecución de violín, pero imitar a Paganini debe ser harina de otro costal.  Seguramente los profesores de armonía saben que debe tener y no tener una buena sinfonía, pero otra cosa debe ser imitar a Mozart.
Bajando a la tierra; tampoco se trata aquí de hacer "Paganinis de la programación C++" (ya me gustaría para mí); el mensaje que quisiera transmitir es doble:  El contenido en un viejo Refrán Español:  "La Universidad no presta lo que la naturaleza no da".  Como suena un poco duro, añadiré un consuelo para los que somos menos dotados;  un proverbio que leí hace tiempo, en línea con la respuesta de Stroustrup: "Por el dinero del trabajo los Dioses lo venden todo".
A continuación se comentan brevemente los pasos imprescindibles en la creación de un programa C++. Vaya por delante, que las anotaciones de los puntos §3, §4 y §5 son opinión del que suscribe basados en la propia experiencia, por tanto totalmente subjetivos y opinables.
§3  Comprender el problema.
"Custom development is that murky world where a customer tells you what to build, and you say, "are you sure?" and they say yes, and you make an absolutely beautiful spec, and say, "is this what you want?" and they say yes, and you make them sign the spec in indelible ink, nay, blood, and they do, and then you build that thing they signed off on, promptly, precisely and exactly, and they see it and they are horrified and shocked, and you spend the rest of the week reading up on whether your E&O insurance is going to cover the legal fees for the lawsuit you've gotten yourself into or merely the settlement cost. Or, if you're really lucky, the customer will smile wanly and put your code in a drawer and never use it again and never call you back".  Joel on Software "Set Your Priorities"   www.joelonsoftware.com
"As more became known about what people wanted to do with computer, it became clear that there would always be increasingly more complex problems to solve.  A part of that realization is the realization that our ability to accurately describe the problem determines the ability for the problem to be solved. Most people are incapable of clearly and precisely articulating -- to the level necessary -- the problems that they're trying to solve. This is a problem that is getting larger and not smaller".  Robert Bogue (Jupitermedia Corp) en "Breaking Down Software Development Roles".
"Often, a problem is only fully understood through the process of programming a solution for it". Bjarne Stroustrup: "Programming: Principles and Practice Using C++".

Esta es la típica obviedad que a veces se pasa por alto.  Hemos dicho que escribir un programa es establecer el comportamiento de una máquina;  parece lo más natural del mundo enterarse primero de cual es ese comportamiento.  Tener una imagen mental lo más clara posible de las características de lo que pretendemos modelar.  Esta cuestión es lo que los teóricos denominan el "espacio" del problema, "'What' domain" en la literatura inglesa.
A esta fase se la suele denominar análisis, y mi consejo particular es que después de una primera toma de contacto, el segundo paso sea definir de la forma más detallada posible el principio y el final del problema. Es decir: cual es la información de partida (incluyendo su formato y en que soporte se recibe) y cual es la información final y en que soporte se proporcionará; no es lo mismo mostrar una imagen que componer una factura o disparar un proceso si un sensor analógico-digital nos suministra una determinada señal (por citar algún ejemplo).
Normalmente en ambas cuestiones tiene mucho que decir el cliente [2], es lo que se llama especificación; el resto (lo que hay entre los datos de entrada y la salida), debe rellenarlo el programador.  Generalmente si se tienen bien definidos ambos extremos, se tiene resuelta la mitad del problema; cuando se tengan diseñados los ficheros se tendrán dos terceras partes -ver a continuación-.  Este sistema tiene además la ventaja de poner inmediatamente de manifiesto las indefiniciones de partida; a veces los clientes no saben exactamente qué desean y hay que ayudarles a centrar el problema.
Dentro de esta fase tiene especialísima importancia el tema de los límites; esto se refiere al orden de magnitudes que se manejarán.  ¿De que rango serán las magnitudes numéricas?  ¿Podrán adoptar valores negativos?  ¿Hay información alfanumérica?  ¿Como son de largas estas cadenas?.  Especialmente si el programa implica diseño de archivos (como es casi seguro),  ¿Cual podrá llegar a ser su tamaño dentro de la vida del programa?. Si se manejan ficheros u objetos binarios, ¿Como son de grandes? ¿Que concepto tiene el cliente de los que sería "rápido" o "lento"? (¿milisegundos, minutos, horas?).  En esta fase sea especialmente precavido y no se crea a pié juntillas todo lo que le digan (intente hacer de abogado del diablo).
Como postre, diseñe las líneas maestras de una estrategia de recuperación de errores de ejecución, incluyendo que hará con los no recuperables (errores fatales).  Piense por ejemplo que si algún día lo llaman para ver "que ha pasado", quizás le interese disponer de un volcado de texto ASCII en el disco con una descripción del estatus del programa como parte de las funciones de salida ( 1.5). Hoy día, cuando se empieza a hablar de frigoríficos que avisarán de que faltan provisiones o de lavadoras que avisarán al técnico si se estropean, no estaría de más que sus programas estuviesen a la altura de las circunstancias.
§4  Diseñar los ficheros y módulos
Si el programa debe utilizar ficheros que no vengan impuestos (ya existentes), y suponiendo que todo lo anterior esté suficientemente claro, este es el momento de hacerlo.  Ponga por escrito la especificación de tales ficheros, incluyendo el nombre que dará a las variables y, en su caso, el que tendrán en el disco o almacenamiento externo.  Esto puede concretarse quizás a la definición de algunas estructuras ( 4.5).  En esta fase es posible que tenga que repreguntar alguna cosa que se pasó por alto.
Teniendo ya una imagen más o menos clara de lo que hará su programa, si éste es mediano o grande, es posible que todavía tenga que realizar una labor previa antes de ponerse a escribir el código: diseñar a grandes rasgos cuales serán los módulos del programa; módulos que se corresponderán aproximadamente con la distribución del código en ficheros fuente independientes.  Quizás tenga que decidir también si algunas partes aparecerán como librerías [1].  Recuerde lo indicado al respecto al tratar de los Subespacios de Nombres ( 4.1.11).
Esta fase es especialmente importante en el caso de programas muy grandes, cuyo desarrollo se reparte entre varios programadores que se encargan de uno o varios de estos módulos.  En estos casos, el análisis, la especificación, la subdivisión en partes (con sus especificaciones particulares), y la asignación de estas como tareas a los programadores, lo habrá realizado el jefe de programación y desarrollo.
§5  Escribir el código
Suponiendo cumplimentados los pasos anteriores, el programador está en condiciones de construir una imagen mental clara de como será esa conexión entre la información de entrada y la salida, es lo que se denomina "espacio" de la solución ("'How' domain"); su forma concreta es justamente el fuente del programa que se pretende.  La codificación consiste justamente trasportar a papel (en el lenguaje de programación elegido) la imagen mental de esa conexión.
Para escribir el código fuente de un programa C++ solo se puede utilizar un subconjunto de 96 caracteres del juego total de caracteres US-ASCII ( 2.2.1a). Son los siguientes [8]:
Juego de caracteres imprimibles:

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + ­ / ^ & | ~ ! = , \ " ’
Caracteres no-imprimibles denominados separadores

Espacio horizontal;  Tabulación horizontal (TAB);  Tabulación vertical (VT);
Salto de forma (FF);  Nueva línea (NL).

No hay comentarios:

Publicar un comentario