UNIVERSIDAD NACIONAL DE PANAMÁ CENTRO REGIONAL UNIVERSITARIO DE VERAGUAS FACULTAD DE INFORMÁTICA, ELECTRONICA Y COMUNICACIÓN INGENIERIA EN INFORMÁTICA
Los Siete Pecados Capitales de la Introducción al Diseño de los Lenguajes de Programación. FACILITADOR: DIEGO SANTIMATEO ESTUDIANTE: FÁTIMA DEL R. ÁLVAREZ 9‐722‐549
II SEMESTRE 2007 Análisis Los 7 pecados capitales en la introducción a los lenguajes de programación, radican principalmente en el proceso de enseñanza del lenguaje, ya que se tiende a proyectar a los estudiantes cientos de conceptos que hablan por ejemplo de abstracción, recursividad, encapsulación de la información presentándolas como una opción fácil y elegante a la hora de programar, pero que pedagógicamente para un principiante representa una oscuridad y dificultad a la hora de interpretar y aplicar. Se producen muchos desperdicios en los rasgos de los lenguajes, ya que una pequeña parte del lenguaje es ignorado porque se tienden a enseñar a como manejar su estructura y no su funcionalidad. Un lenguaje es completo cuando los estudiantes usan su semántica, pero en realidad parte del lenguaje nunca se les ha explicado. Las trampas gramaticales representan uno de las mayores dificultades a la hora de introducirnos a un lenguaje, ya que la semántica y sintáctica varía de un lenguaje a otro, puede ser que existan distintas maneras de escribir una declaración, además el estudiante tendrá que aprenderse las palabras reservas y los operadores del lenguaje aunque solo valla a realizar un pequeño programa, pero que de lo contrario no podrá realizar su tarea.
En la aplicación de un lenguaje, no te enseñan a como manejar las dependencias del hardware y cuando estos interfieren en el desarrollo de nuestras aplicaciones representan un verdadero dolor de cabeza para cualquier estudiante. Las bases para lograr un mayor rendimiento ante estas adversidades pedagógicas, se presentan en orientar mayores esfuerzos en el diseño de material didáctico y textos para la introducción a un lenguaje. 1. Ejemplifique utilizando un lenguaje de programación 3 de los siete pecados capitales. Ejemplo 1: Trampas Gramaticales Este programa en Prolog construye una serie de listas que contienen, la información de un grupo de personas. Como se aprecia en la programación lógica existen muchas trampas gramaticales ya que las listas en Prolog podrían definirse del mismo modo que los árboles puesto que los términos se pueden anidar todas las veces que sea necesario.
Por ejemplo, la lista anterior se puede representar así: lista(1,lista(2,lista(3,lista(4,lista(5,vacio))))) Afortunadamente, las listas están predefinidas en el lenguaje para una mayor comodidad De modo que la lista anterior la podemos escribir así: [Fátima, Álvarez, González, dir[Montijo, Santiago, Montijo] 999‐81‐31] Esta es la forma de escribir las listas definiendo todos los elementos, pero podemos manipular las listas distinguiendo cabeza y resto: [C|R]. Donde la variable C representa la cabeza, y R el resto. Por ejemplo: L = [Fátima, Álvarez, González, dir[Montijo, Santiago, Montijo] 999‐81‐31], M = [0|L]. La lista M sería equivalente a [0Fátima, Álvarez, González, dir[Montijo, Santiago, Montijo] 999‐81‐31]].
Es importante no confundir los términos [C|R] y [C,R]. La diferencia es muy sutil: L = [1, 2, 3, 4, 5], M = [0,L]. El resultado sería M = [0,[Fátima, Álvarez, González, dir[Montijo, Santiago, Montijo] 999‐81‐31]], que es una lista de dos elementos. Resultado del programa anterior nos muestra todas las personas que pertenecen a la misma ciudad.
Como se puede observar en el ejemplo otro problema que dan los lenguajes de programación en el aspectos pedagógico es la confusión en la sintáctica y la semántica. Un estudiante para poder programar deberá aprender todas las formas posibles de interpretar una instrucción de manera de que los resultados sean los esperados. En este lenguaje los homónimos sintácticos (estructuras que son sintácticamente el mismo, pero que tiene dos o más semánticas dependiendo del contexto) son frecuentes. Alternativa: Para eliminar las trampas gramaticales de los lenguajes de programación, primero se debería estudiar y reestructurar las sintaxis, para que las expresiones que se utilicen sean las más comunes y que se usen de una sola forma; de esta manera se evitaría la utilización de una misma expresión para denotar varias tareas diferentes dentro de un programa, ocasionando confusiones y malas aplicaciones del lenguaje. Ejemplo 2: Dependencia del Hardware Uno de los problemas pedagógicos más comunes se presenta en que el estudiante no solo tiene que batallar con la sintáctica y semántica de los lenguajes, sino es obligado a menudo manejar los detalles del hardware. Por ejemplo, pascal es muy utilizado para realizar operaciones matemáticas y desarrollar teoremas que requieren de una precisión en sus cálculos. En el programa a continuación se presenta el método Newton Rapshon para encontrar la raíz aproximada después de un número de iteraciones determinados por el usuario.
Las máquinas comunes no están diseñadas para manejar cálculos mayores por ello el resultado esperado, quizás no sea el final. Ejemplo los tipos int estándares a pueden ir de 16 a 32 bits, que se representan dependiendo de la máquina y de la implementación. program prog3; {Programa 3: determina la solución de la ecuación Sen(x) ‐ x + 1 Utilizando el método Newton Rapshon} var error,error1:real; //Toma los valores de error de aproximación x,x1:real; //Toma el valor de xi y xi‐1 respectivamente i,n:integer; //contadores begin writeln(ʹMetodo: metodo Newton Rapshon.ʹ); writeln; write(ʹIndique la cantidad de iteraciones ʹ); readln(n); if n < 0 then begin write(ʹAviso: las iteraciones no pueden ser negativas el valor ʹ,n); n := n * ‐1; writeln(ʹ fue cambiado por ʹ,n); end; write(ʹIndique el error ʹ); readln(error1); write(ʹIndique X0 ʹ); readln(x); writeln; writeln(ʹDeterminando solución para la ecuación: Sen(x) ‐ x + 1ʹ); writeln(ʹF(x) = sin(x) ‐ x + 1ʹ); writeln(ʹFʹʹ(x) = cos(x) ‐ 1ʹ); writeln(ʹResolviendo por el Método: Newton Rapshon.ʹ); writeln; i := 0; error := 1;
x1 := 0; writeln(ʹiʹ:2,ʹxiʹ:16,ʹF(xi)ʹ:18,ʹFʹʹ(x)ʹ:18,ʹerrorʹ:18); write(ʹ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ʹ); writeln(ʹ‐‐‐‐‐‐‐‐‐‐‐ʹ); repeat x1 := x; writeln(i:2,x:18:4,sin(x) ‐ x + 1:16:4,cos(x) ‐ 1:18:4,error:18:4); x := x ‐ (((sin(x) ‐ x) + 1)/(cos(x) ‐ 1)); //calculo de la función de error := (x ‐ x1) / x; // iteración if error < 0 then error := ‐1 * error; i := i + 1; until ((i >= n) or (error <= error1) or (error = 0)); writeln(i:2,x:18:4,sin(x) ‐ x + 1:16:4,cos(x) ‐ 1:18:4,error:18:4); writeln; if error = 0 then begin writeln(ʹRaiz: ʹ,x:10:4); end else begin if error < error1 then writeln(ʹRaiz aproximada: ʹ,x:10:4) else writeln(ʹLa raiz no fue encontrada en ʹ,n,ʹ iteracionesʹ); end; readln; end.
_ El resultado esperado era una raíz aproximada, pero debido a la cantidad de iteraciones (cálculos) que se realizaron basándose en el método Newton Rapshon, la máquina presenta un problema de hardware y no tiene la capacidad de realizar tantas iteraciones. Por ello la salida es un número negativo; las raíces no son negativas y no se espera una raíz imaginaria así que nuestro programa solo funcionara para realizar cálculos pequeños no mayores a 100 iteraciones. Alternativa: Estos problemas de hardware están siempre presente cuando trabajamos con lenguaje de programación, más cuando estamos utilizándolo para realizar cálculos y almacenamiento de información a gran capacidad en donde se producen los desbordamientos de la memoria del computador. Por ejemplo en java recomendaría utilizar el garbage colection, para que valla limpiando las basuras de la memoria. Analizar las posibilidades que me brindan los lenguajes que estoy utilizando para aprovechamiento de la memoria y en caso de necesidad ampliar la capacidad del hardware del computador. Capacitar al estudiante sobre las complicaciones que se dan entre programación y los detalles del hardware del computador por que muchos ignoran las relaciones que tienen estos al momento de resolver los problemas que ejecutamos comúnmente.
Ejemplo 3: Violación de las expectativas Declaración de un predicado, que luego Unificara un valor a la variable anónima. Este instrucción se encarga de hacer la labor de un contador de componentes de mi lista.
Prolog ofrece un sistema de programación basada en el predicado lógico, pero con advertencias silenciosas y terribles para los resultados que esperamos. El principiante y estudiante para crear una definición recursiva como la que resalto en la figura; deberá crear un predicado razonable, algo como: • longitud([_|Resto],Longitud):‐ • longitud ([] ,0). • longitud(Resto,[Resto|_]). que lógicamente esta bastante correcto, pero que incurre en una violación a las expectativas por que el orden de la declaración de predicados determina la sucesión de unificación del predicado en prolog, este tipo de problemas se me presento mucho en la construcción de mis programas cuando trabaje con este lenguaje.
El lenguaje prolog rompe con los esquemas que acostumbrados a ver en otros tipos de lenguajes como C o Java en donde la el diseño de un programa se basa en la lógica tradicional que aprendemos desde 1 año. Pienso que un lenguaje como prolog debe estar orientado para un profesional de la informática o un estudiante de mayor nivel porque la verdad es que requiere una cierta formación en lógica matemática y en técnicas de programación. Alternativa: Las violaciones semánticas de las expectativas son las más comunes lamentablemente, pero en la actualidad programas como eclipse que han logrado un gran desarrollo sobre la plataforma java; constan con una herramienta que te muestra las posibilidades que tienes para construir una instrucción. Recomendaría sacar el máximo provecho de las herramientas que están disponibles para trabajar muchos lenguajes populares como Dev C++, Eclipse, NetBeans, que tienen muy buenos depuradores que permiten evaluar los resultados de la ejecución por segmentos, por variables, de esta forma nos aseguraremos donde están nuestros errores, ya que muchas veces las violaciones semánticas se escapan de nuestros ojos. 3. Evaluación de dos lenguajes de programación, utilizando los criterios de la lectura.
He decidido evaluar el lenguaje C porque es uno de los lenguajes más populares y representa una de los lenguajes que más uso. Además evaluare el lenguaje Prolog ya cuando lo utilice me pareció súper interesante pero a la vez significo todo un reto a la hora de desarrollar un programa. Lenguaje C El lenguaje se denomina como un lenguaje de nivel medio, puesto que combina elementos de lenguajes de alto nivel (FORTRAN, Pascal, Basic…) con el funcionamiento del lenguaje ensamblador. En la actualidad C permite el manejo de bits, bytes y direcciones los elementos básicos con que funciona una computadora. Otra característica del C es que posee muy pocas palabras claves (32 donde 27 provienen de la versión original, y cinco añadidas por el comité de ANSI. Todas la palabras claves de C están en minúscula (C distingue entre minúscula y mayúscula). Los programas en C están compuestos por en una o más funciones. La única función que debe estar siempre presente se denomina main, siendo la primera función que es llamada cuando se ejecuta un programa. Aunque main no forma parte técnicamente del lenguaje C, hay que tratarla como si lo fuera, pues si se emplea para denominar una variable, probablemente confundirá al compilador. Estos detalles son básicos y primordiales a la hora de introducirnos en este lenguaje.
Además, los programas escritos en C tienen otras ventajas sobre el resto. Con la excepción del ensamblador, generan los programas más compactos y rápidos. El código es transportable, es decir, un programa ANSI en C podrá ejecutarse en cualquier máquina y bajo cualquier sistema operativo. Y si es necesario, proporcionan un acceso a bajo nivel de hardware sólo igualado por el ensamblador. En cuanto a la utilidad práctica de C podemos citar: C es lenguaje de programación de propósito general. Todo puede programarse con el, desde sistemas operativos y compiladores hasta aplicaciones de bases de datos y procesadores de texto, pasando por juegos, aplicaciones a medida, etc. C presenta un generador de errores en donde el compilador te indica la línea del código que debes corregir. Por ejemplo errores de enlazado en donde puede que hayamos olvidado incluir alguna librería, o algún fichero objeto, o puede que hayamos olvidado definir alguna función o variable, o lo hayamos hecho mal, de esta forma contribuye a mejorar el proceso de aprendizaje y manejo del lenguaje. Es muy recomendable explicar estos puntos a los estudiantes principiantes ya que así se aprovecha al máximo los recursos del lenguaje. Con el pasar de los años C a ido fortaleciendo sus debilidades y problemas en su diseño convirtiéndose en un lenguaje básico para la enseñanza de la programación.
Lenguaje Prolog El PROLOG es el lenguaje rey de la programación declarativa relacional. Pero enseñarlo en verdad requiere de mucha preparación ya que rompe con el pensamiento común, exigiendo mayor lógica y sutileza. En cuanto a la escasa utilidad práctica de Prolog podemos citar: •
Acceso a bases de datos desde páginas Web.
•
Paralelización automática de programas.
•
Programación distribuida y multiagente.
•
Sistemas expertos e inteligencia artificial.
•
Validación automática de programas.
•
Procesamiento de lenguaje natural.
•
Prototipado rápido de aplicaciones.
•
Bases de datos deductivas.
•
Interfacing con otros lenguajes como Java y Tcl/Tk.
•
... (la lista es interminable) ...
En cuanto a la excasa eficiencia hemos de admitir que Prolog es aproximadamente diez veces más lento que el lenguaje C. Pero también hemos de admitir que un programa en Prolog ocupa aproximadamente diez veces menos, en líneas de código y tiempo de desarrollo, que el mismo programa escrito en C. Además las técnicas de optimización de código en Prolog apenas están emergiendo en estos momentos. Algunos experimentos (optimistas) hacen pensar que la velocidad de ejecución de Prolog podría aproximarse a la de C en esta década. Para que un estudiante utilicé este lenguaje de tener conocimientos previos en: * La programación imperativa tradicional. * Tipos abstractos de datos, como listas y árboles. * Técnicas de programación, como la recursividad. El entorno de desarrollo Prolog Prolog es un lenguaje de programación seminterpretado. Su funcionamiento es muy similar a Java. El código fuente se compila a un código de byte el cuál se interpreta en una máquina virtual denominada Warren Abstract Machine (comúnmente denominada WAM). Por eso, un entorno de desarrollo Prolog se compone de:
* Un compilador. Transforma el código fuente en código de byte. A diferencia de Java, no existe un standard al respecto. Por eso, el codigo de byte generado por un entorno de desarrollo no tiene por que funcionar en el intérprete de otro entorno. * Un intérprete. Ejecuta el código de byte. * Un shell o top‐level. Se trata de una utilidad que permite probar los programas, depurarlos, etc. Su funcionamiento es similar a los interfaces de línea de comando de los sistemas operativos. * Una biblioteca de utilidades. Estas bibliotecas son, en general, muy amplias. Muchos entornos incluyen (afortunadamente) unas bibliotecas standard‐ISO que permiten funcionalidades básicas como manipular cadenas, entrada/salida, etc. Generalmente, los entornos de desarrollo ofrecen extensiones al lenguaje como pueden ser la programación con restricciones, concurrente, orientada a objetos, etc. En cuanto a su sintaxis: Existe un standard ISO que dicta las típicas normas con respecto a la sintáxis del lenguaje y a las bibliotecas básicas que se deben ofrecer. Actualmente el standard no contempla todos los aspectos del lenguaje, y además, no todos los entornos siguen el standard al pie de la letra. Por eso, programas que funcionan en unos entornos podrían no funcionar en otros, o lo que es peor, funcionar de forma diferente.
Evaluación de los Lenguajes Pecado
Lenguaje C
1. Menos es más
Lenguaje Prolog
2. Más es más
3. Las trampas gramaticales
4. Dependencia del hardware
5. Compatibilidad atrasada
6. Destreza excesiva
7. Violaciones a las
expectativas Total de puntos
6
6
Ambos lenguajes se encuentran al mismo nivel, en lo que concierne a los problemas que surgen al momento de su enseñanza, pero a pesar de tener los mismos puntos C seguirá siendo el lenguaje más popular, por ello estas dificultades pronto formaran parte del pasado.