Fundamentos de programación con Módula-2 (4)

 

1.6 Elementos de la programación imperativa
 
La mayoría de los lenguajes de programación actualmente en uso siguen el modelo de programación imperativa. Por esta razón se ha optado en este primer nivel de enseñanza de programación por seguir dicho modelo. El lenguaje de programación Modula-2 se utilizará en este libro (entradas de blog) como herramienta para desarrollar las ideas generales en ejemplos prácticos realizables en máquina. Modula-2 no se utiliza mucho, por el momento, en desarrollos reales, quizá por no ser un lenguaje definido como "estándar" por los organismos internacionales de normalización, pero presenta importantes ventajas para la enseñanza, por ser un lenguaje bien estructurado, permitir el uso real de programación modular de manera segura, permitir la implementación de tipos abstractos de datos, y ser un buen paso hacia el uso de lenguajes más evolucionados (y más complicados) como ocurre con el lenguaje Ada.
 
En el resto de este texto se irán desarrollando las ideas abstractas o generales de programación, junto con su realización en lenguaje Modula-2. Todo ello en el marco de la programación imperativa, cuyos elementos abstractos se describen a continuación.
 
1.6.1 Procesador, entorno, acciones
Al introducir el modelo de programación imperativa se ha definido un programa, de manera intuitiva, como una lista de órdenes o instrucciones que han de ir siendo ejecutadas por la máquina en el orden preciso que se indique.
 
La idea abstracta correspondiente al concepto físico de máquina es el procesador. Definiremos como procesador a todo agente capaz de entender las órdenes del programa y ejecutarlas.
 
El procesador es esencialmente un elemento de control. Para ejecutar las instrucciones empleará los recursos necesarios, que formarán parte del sistema en el cual se ejecute el programa. Por ejemplo, se necesitarán dispositivos de almacenamiento para guardar datos que habrán de ser utilizados posteriormente, o dispositivos de entrada-salida que permitirán tomar datos de partida del exterior y presentar los resultados del programa. Todos estos elementos disponibles para ser utilizados por el procesador constituyen su entorno.
 
Las órdenes o instrucciones del programa definen determinadas acciones que deben ser realizadas por el procesador. Un programa imperativo aparece así como la descripción de una serie de acciones a realizar en un orden preciso. Las acciones son la idea abstracta equivalente a las instrucciones de un programa real.
 
1.6.2 Acciones primitivas. Acciones compuestas
Las acciones que son directamente realizables por el procesador se denominan acciones primitivas. Estas acciones suelen ser bastante sencillas, incluso en el caso de programas descritos en lenguajes de programación simbólicos. Entender un programa descrito enteramente a base de acciones primitivas suele ser muy difícil, por el nivel de detalle con el que hay que analizar cada una de sus partes, y todas ellas en conjunto.
 
El planteamiento razonable de un programa complejo debe pasar por usar la idea de abstracción para limitar la complejidad de detalles al estudiar el programa en su conjunto. Es muy útil usar la idea de acción compuesta como abstracción equivalente a un fragmento de programa más o menos largo que realiza una operación bien definida.
 
La descripción de un programa en términos de acciones compuestas puede facilitar su compresión. Por supuesto, al desarrollar el programa habrá sido preciso describir o descomponer las acciones compuestas en otras más sencillas, hasta llegar finalmente a acciones primitivas, que son las que realmente podrá ejecutar el procesador. Las acciones compuestas son un elemento de descripción que facilita la comprensión del programa en su conjunto, o de partes importantes de él, pero no reduce el tamaño total del programa, que necesariamente deberá ser largo si se han de realizar operaciones complicadas.
 
1.6.3 Esquemas de acciones
Una acción compuesta consistirá, tal como se ha indicado, en la ejecución combinada de otras acciones más sencillas. La manera en que varias acciones sencillas se combinan para realizar una acción complicada se denomina esquema de la acción compuesta.
 
Una buena metodología de programación exige usar esquemas sencillos y fáciles de entender a la hora de desarrollar acciones compuestas. A lo largo de este libro (entradas de blog) se irán introduciendo los principales esquemas de programación imperativa, junto con recomendaciones para su aplicación en el desarrollo de programas.
 
En particular, la llamada programación estructurada sugiere el uso de tres esquemas generales denominados secuencia, selección e iteración, con los cuales (junto con la definición de operaciones abstractas) se puede llegar a desarrollar de forma comprensible un programa tan complicado como sea necesario.
 
 
1.7 Evolución de la programación
 
Las ideas sobre cuál es la manera apropiada de desarrollar programas han ido evolucionando con el tiempo. Ha habido diversos motivos para ello, que pasaremos a analizar brevemente.
 
1.7.1 Evolución comparativa Hardware/Software
Los primeros computadores eran máquinas extraordinariamente costosas, y con una capacidad que hoy día consideraríamos ridículamente limitada. Sin embargo en su momento representaban el límite en la capacidad de tratamiento de información, y hacían posible determinados trabajos de cálculo inabordables hasta entonces.
 
Como consecuencia de ello la finalidad principal de la programación era obtener el máximo rendimiento de los computadores. Los programas se escribían directamente en el lenguaje de la máquina, o a lo sumo en un lenguaje "ensamblador" en que cada instrucción de máquina se representaba simbólicamente mediante un código nemotécnico para facilitar la lectura del programa.
 
No existían ideas abstractas sobre el significado u objetivo preciso de un programa. Simplemente se consideraba que el mejor programa era el que realizaba el trabajo en menos tiempo y usando el mínimo de recursos de la máquina. La programación era, por tanto, una labor artesana, basada en la habilidad personal del programador para conseguir que el programa cumpliera con esos objetivos de eficiencia, para lo cual era imprescindible conocer en detalle el funcionamiento interno del computador, y poder así emplear ciertos "trucos" de codificación que permitían ahorrar algunas instrucciones o usar menos elementos de memoria para almacenar datos intermedios.
 
El costo de desarrollo del software resultaba, en todo caso, muy inferior al costo del equipo material (hardware), por lo que pocas personas se paraban a considerar las posibilidades de reducir los costos de desarrollo de programas.
 
Por otra parte, y dada la limitación de capacidad de las máquinas, los programas eran necesariamente sencillos, en términos relativos, y se consideraba que podían llegar a depurarse de errores mediante ensayos o pruebas en número suficiente.
 
Los avances en la tecnología electrónica han ido suministrando computadores cada vez más capaces y baratos, en términos relativos. La necesidad de preparar sistemáticamente programas muy eficientes ha ido disminuyendo, y poco a poco se ha ido haciendo rentable utilizar programas no tan eficientes.
 
La mayor capacidad de los computadores ha permitido abordar aplicaciones cada vez más complejas. En los primeros computadores el software de una aplicación podía contener algunos cientos o quizá miles de instrucciones. En la actualidad las aplicaciones consideradas sencillas tienen decenas de miles de instrucciones, y en aplicaciones de gran envergadura, tal como los grandes proyectos aeroespaciales, el volumen del software desarrollado se cuenta por millones de instrucciones.
 
Con estos volúmenes de programa el costo del desarrollo del software supera ampliamente al costo de los equipos hardware utilizados. Ya no tiene sentido dedicar un gran esfuerzo a conseguir programas eficientes. Es más barato desarrollar programas relativamente más simples, aunque no aprovechen muy bien los recursos de la máquina, y comprar un computador de mayor potencia de proceso que compense esa posible falta de eficiencia. Los lenguajes de programación simbólicos han facilitado extraordinariamente las tareas de programación, al poder invocar en un programa operaciones cada vez más complejas como acciones primitivas. De esta manera se reduce el volumen total del programa medido en número de instrucciones, que ahora pasan a ser sentencias del lenguaje simbólico.
 
1.7.2 Necesidad de una buena metodología
Los programas actuales son tan complicados que ya no es posible desarrollarlos de una manera artesanal. Es necesario aplicar técnicas de desarrollo muy precisas para controlar el producto obtenido. Ya se ha indicado que estas técnicas aplicables a proyectos desarrollados en equipo constituyen la ingeniería de software.
 
A nivel individual hay que promover el empleo de una metodología de programación apropiada, que satisfaga los objetivos de corrección y claridad mencionados anteriormente. Para aplicaciones grandes la claridad se convierte en un objetivo prioritario, ya que resulta imposible analizar y modificar un programa si no se comprende suficientemente su funcionamiento.
 
Para facilitar la obtención de programas correctos, sin fallos, se recomienda el empleo de técnicas formales, que permitan en lo posible garantizar la corrección del programa mediante demostraciones lógico-matemáticas, y no mediante ensayos en busca de posibles errores. La técnica de ensayos solo resulta útil si consigue descubrir fallos, pues así demuestra que el programa contiene errores que hay que corregir, pero es más bien inútil si no se descubre ningún fallo, porque eso no garantiza que el programa no contenga errores, los cuales pueden manifestarse (y lamentablemente se manifiestan con harta frecuencia) cuando el programa ya está en explotación, y los usuarios lo emplean en multitud de situaciones nuevas que no habían sido ensayadas nunca.
Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s