View
5
Download
0
Category
Preview:
DESCRIPTION
Plan de Tesis
Citation preview
Universidad Nacional de Lomas de Zamora
Facultad de Ingeniería
PLAN DE TESIS
Para optar al título de
Licenciado en Informática
La influencia del paradigma de programación funcional en la formación profesional en las carreras universitarias
informáticas
Julio Rodolfo Silva
Lomas de Zamora, julio de 2007
Planteo del problema
Uno de los objetivos más importantes en el desarrollo de software consiste en el
diseño y construcción de programas que resuelvan en forma exitosa las necesidades de las
personas que los utilizan. Esta definición de éxito involucra conceptos tales como fiabilidad
del producto, reducción de la tasa de errores a cero1, alta capacidad de mantenimiento del
software y estricto cumplimiento de los requisitos especificados. Sin embargo, diversos
problemas que no se limitan solamente a errores en el funcionamiento de los programas, sino
que se encuentran asociados a todo el ciclo de vida del software, hacen que los desarrollos
informáticos sean cada vez más costosos, menos confiables, menos manejables y más difíciles
de probar a medida que crecen en magnitud. Estos problemas influyen decisivamente en los
aspectos de no–calidad del software2.
Se han planteado diversas alternativas con el fin resolver estos problemas. Estas
alternativas incluyen la adopción de un enfoque de ingeniería, distintas innovaciones en los
paradigmas y metodologías de desarrollo – como la programación estructurada o las
metodologías orientadas a objetos –.
Se han ofrecido diferentes explicaciones para este problema. Una de ellas consiste en
la imposibilidad – dentro del paradigma dominante actual – de ofrecer una demostración
formal del cumplimiento efectivo de los requisitos de especificación. Este sentido de
1 La industria informática se ha preocupado históricamente por los fallos de hardware. Actualmente, sin embargo, con la amplia disponibilidad de hardware existente, el énfasis se desplaza hacia el software, ya que las fallas en el software son la causa principal en un alto porcentaje de fallas operacionales de los sistemas. Es por ello que existe lo que se denomina Software con Tolerancia a Fallos, el cual tiene la capacidad de detectar y recuperarse de un fallo que esta ocurriendo o ha ocurrido, para proporcionar servicio de acuerdo con las especificaciones.Inclusive el “software libre de errores” no se mantiene libre de errores; la inversión en desarrollo es superado aproximadamente en dos o tres veces por los gastos eventuales de mantenimiento, y cada modificación en un software existente puede resultar en la introducción de nuevos errores.BHARATHI, VKUMAR. Version programming method of Software Fault Tolerance: A Critical Review. National Conference on Nonlinear Systems & Dynamics, páginas 173 – 176. Indian Institute of Technology, Kharagpur, 2003. Traducción propia. Extraída en Enero 2007 desdehttp://www.cts.iitkgp.ernet.in/~ncnsd/cd_ncnsd/html/pdf/173-176.pdfBANKER, R. ET AL. Software Errors and Software Maintenance Management. Information Technology and Management Nº 3, páginas 25 – 41, Kluwer Academic Publishers, Holanda, 2002. Traducción propia. Extraída en Enero 2007 desdehttp://www.pitt.edu/~ckemerer/CK%20research%20papers/SoftwareErrors&Maintenance_Banker2002.pdf
2 Una definición de calidad del software: “Concordancia con los requisitos funcionales y de rendimiento explícitamente establecidos, con los estándares de desarrollo explícitamente documentados, y con las características implícitas que se espera de todo software desarrollado profesionalmente”.PRESSMAN, ROGER. Ingeniería de Software. Un enfoque práctico (5º edición). McGraw Hill, Madrid 2002.
1
formalidad está relacionado con el rigor matemático que se aplica durante las distintas etapas
del desarrollo de software. Esto incluye, entre otros conceptos, la especificación formal de
sistemas, el análisis y la demostración de la especificación, el desarrollo transformacional y la
verificación de programas3. La capacidad de demostración formal resultante implica la
seguridad de funcionamiento del sistema dentro de los parámetros establecidos por la
especificación4.
Los profesionales de la computación deben estar capacitados para estudiar los
fundamentos de su disciplina. El núcleo central de las carreras informáticas en su mayoría está
constituido en buena parte por materias relacionadas con matemáticas. En consecuencia, un
especialista en computación debe estar en condiciones de usar las herramientas básicas y las
técnicas de dichas áreas. Esto le permitirá una adecuación rápida y eficaz a los acelerados
cambios tecnológicos, que son una constante en la disciplina5.
En nuestro país, la cantidad de estudiantes de las carreras relacionadas con el
desarrollo de software ha crecido en estos últimos años, a pesar de la dura crisis sufrida por
nuestro país a fines de 2001. La educación superior argentina produce cada vez más
profesionales de Informática6; sin embargo, el notable crecimiento evidenciado por el sector
informático en los últimos años, en comparación con otras ramas de la industria, provoca que
esta cantidad de profesionales, a pesar del aumento nominal, sea insuficiente para satisfacer
los requerimientos del mercado7. Los problemas de capacidad profesional para adaptarse y
3 SOMMERVILLE, IAN. Ingeniería de Software (7º edición). Pearson Educación, Madrid 2005.
4 PRESSMAN, ROGER, op.cit.
5 MARTELLOTTO, PAOLA ET AL. Teoría de Tipos y Coq en la Enseñanza de Programación Funcional e Imperativa. Taller de Construcción Formal de Programas. Departamento de Computación, Universidad Nacional de Río Cuarto, Argentina, 2002. Extraída en Enero 2007 desdehttp://lsm.dei.uc.pt/ribie/docfiles/txt200332618221A035.pdf
6 La cantidad de alumnos en las universidades nacionales de gestión estatal cursando carreras relacionadas con Informática entre 2000 y 2004 aumentó un 0,96% a nivel nacional, y un 16,97% a nivel local, considerando algunas de las universidades nacionales ubicadas dentro del ámbito geográfico de la Universidad Nacional de Lomas de Zamora (Universidad de Buenos Aires, Universidad Nacional de La Plata, Universidad de La Matanza y Universidad Nacional de Lanús).MINISTERIO DE EDUCACIÓN, CIENCIA Y TECNOLOGÍA. Anuario 2004 de Estadísticas Universitarias. Alumnos, Nuevos Inscriptos y Egresados de Instituciones Universitarias de Gestión Estatal., Capítulo 2, Página 54–56. Ministerio de Educación, Ciencia y Tecnología. Secretaría de Políticas Universitarias. Buenos Aires, 2004. Extraída en Enero 2007 desdehttp://www.me.gov.ar/spu/documentos/publicaciones/pmsiu_anuario2004.zip
7 Según datos de la Encuesta Estructural a PyME de Servicios a la Producción, durante 2005 las ventas del sector se incrementaron un 16% en términos nominales. Asimismo, siguiendo la tendencia de creciente inserción
2
desempeñarse según las diferentes necesidades del mercado laboral quedan evidenciados por
las dificultades por parte de las distintas empresas para satisfacer determinados perfiles8.
Es interesante analizar y evaluar cómo influye un paradigma que abarque conceptos y
métodos formales en la formación profesional en las carreras universitarias informáticas.
Objetivo general
Analizar la influencia del paradigma funcional en la formación profesional en las
carreras informáticas, con el fin de estar en condiciones de definir criterios para mejorar el
perfil profesional y la flexibilidad de los profesionales informáticos, para que puedan utilizar
herramientas básicas y técnicas que faciliten una adecuación rápida y eficaz a los cambios
tecnológicos actuales.
Objetivos específicos
Describir el contexto histórico de la evolución de los paradigmas de desarrollo
de software, en especial el paradigma imperativo y el funcional.
Analizar los aspectos más característicos de dichos paradigmas.
Establecer fortalezas y debilidades de dichos paradigmas.
Identificar los diferentes ámbitos de aplicación de desarrollos de software
realizados en lenguajes funcionales.
Estudiar las influencias de las metodologías de desarrollo de software.
internacional, durante 2005 la base exportadora se aproximó al 25% mientras que la apertura exportadora se ubicó en torno al 7%.CESSI ARGENTINA. Informe 2005 | 2006. Situación actual y desafíos futuros de las PyME de Software y Servicios Informáticos. Primera sección, Página 6. Fundación Observatorio Pyme. Cámara de Empresas de Software & Servicios Informáticos. Buenos Aires, 2006. Extraída en Enero 2007 desdehttp://www.observatoriopyme.org.ar/pdf/Informe%20Software.pdf
8 Como ejemplo, se detallan los puestos con mayores problemas para cubrir:1. SAP: Analistas funcionales, analistas técnicos; 2. Java y J2EE: Desarrolladores, Analistas funcionales y analistas programadores; 3. Oracle: Analistas funcionales, analistas técnicos y DBA; 4. Visual Basic con componentes: Analistas Programadores; 5. DBA Oracle; 6. ASP y ASP.NET; 7. C , C++, C#UNIVERSOBIT. Informe mensual del mercado laboral de IT. Boletin Empresas Nro 12 - Año 1 - Actualización a Buenos Aires, Octubre 2005. Extraída en Enero 2007 desdehttp://www.universobit.com/universobit/news_empre.nsf/2f851bbb109dfaf403256fb70066360a/ba2c9f4ae84e791a032570bd0078a797/$FILE/Informe%20octubre%202005.doc
3
Evaluar el rol del paradigma funcional de desarrollo de software en relación
con su influencia en la formación profesional, en la educación superior informática en
general, y en las carreras universitarias informáticas en particular.
Establecer el impacto del paradigma funcional en los aspectos teóricos y
prácticos de la disciplina de programación.
Justificación
Ya en 1978 John Backus, una de las personas más influyentes en el mundo de la
programación, criticó el modelo tradicional de programación en estos términos:
“Los lenguajes de programación están en problemas (…). … pocos lenguajes hacen
que programar sea lo suficientemente económico o más confiable para justificar el costo de
producir y aprender a usarlos (…). Los lenguajes convencionales de programación se están
volviendo cada vez más y más voluminosos, pero no sucede lo mismo con su fortaleza. La
causa de que sean a la vez pesados y débiles son defectos inherentes al nivel más básico: su
estilo de programación heredada de su antecesor en común – la computadora de Von
Neumann – (…) y su carencia de propiedades matemáticas útiles para razonar acerca de los
programas.”
Y continuó su argumentación con gran contundencia, diciendo:
“ … (Este estilo de programación) constituye un cuello de botella intelectual que nos
ha mantenido atados a un pensamiento de ‘una-palabra-a-la-vez’, en vez de alentarnos a
pensar en términos de unidades conceptuales más grandes (…). Los lenguajes de
programación convencional son básicamente versiones complejas de alto nivel de la
computadora de Von Neumann9 (…). Nuestra fijación en los ‘lenguajes Von Neumann’
continuó la supremacía de la computadora de Von Neumann, y nuestra dependencia de ‘ella’
hizo que los lenguajes ‘no–Von Neumann’ fueran antieconómicos, limitando su desarrollo.
La ausencia a gran escala de estilos de programación basados en los principios ‘no–Von
9 Backus aclara: “Los ‘lenguajes Von–Neumann’ usan variables para imitar las celdas de almacenamiento de memoria de la computadora, estructuras de control elaboradas para simular las instrucciones de salto y testeo, e instrucciones de asignación para imitar la aritmética, la recuperación y el almacenamiento de datos. La instrucción de asignación es el ‘cuello de botella de Von–Neumann’ de los lenguajes de programación, y nos mantiene atados a pensar en términos de ‘una-palabra-a-la-vez’ (…). Queda claro que al referirme a los lenguajes de programación convencionales como ‘lenguajes Von–Neumann’ lo hago para tomar nota de su origen y estilo, sin endilgarle ningún tipo de culpa al gran matemático.”
4
Neumann’ ha despojado a los diseñadores de una base intelectual para nuevas arquitecturas
de computadoras.”
La programación funcional, con su estilo revolucionario de resolver problemas, ofrece
una alternativa para solucionar estos problemas, al permitir producir software a bajo costo,
más confiable, manejable y formalmente demostrable desarrollando a la vez gran capacidad
de abstracción. Simon Thompson lo expone claramente, al afirmar:
“Gracias a sus fundamentos sencillos, los lenguajes funcionales brindan la
visión más clara posible de las ideas centrales de la computación moderna, incluyendo
abstracción (en una función), abstracción de datos (en un tipo de datos abstracto),
genericidad, polimorfismo y sobrecarga. Esto significa que los lenguajes funcionales
proporcionan no solamente una introducción ideal a las ideas modernas de programación,
sino también una perspectiva útil hacia enfoques más tradicionales, como el imperativo u
orientado a objetos.”
La incorporación de los conceptos de distintos paradigmas de programación en las
carreras informáticas (considerando como “paradigma” un estilo determinado de
programación) es crucial para sentar bases sólidas que permitan desarrollar software exitoso.
Michael R. Hansen y Jens Thyge Kristensen lo plantean de esta manera:
“La enseñanza de programación a los universitarios recién iniciados es una tarea que
plantea los siguientes desafíos:
Los estudiantes deben resolver problemas interesantes utilizando una
computadora.
La programación debe ser enseñada como una actividad intelectual.
El primer punto motiva a los estudiantes a programar, mientras que el segundo
asegura el aprendizaje de habilidades generales esenciales. Más aún, el primer punto se
relaciona directamente a la elección del lenguaje de programación, lo que determina lo que
es realizable en un curso de duración limitada, y el segundo punto se relaciona con la actitud
que se desea hacia la actividad de programar como tal; frecuentemente, los estudiantes no
pueden ver su importancia. En este aspecto, es importante enseñar conceptos básicos, que
5
sean bien aprendidos, para así formar una base sólida para la educación posterior en las
ciencias informáticas.”
Esto pone de manifiesto la influencia benéfica de utilizar las características de los
lenguajes de programación funcional para la incorporación de los fundamentos del desarrollo
de software por parte de los futuros profesionales informáticos.
Considerando la coyuntura actual del mercado de desarrollo de software en Argentina,
el nivel de instrucción necesario para dar satisfacción a las necesidades que plantea esta
coyuntura, y la currícula de las carreras informáticas en las instituciones universitarias de
gestión estatal en Argentina (en particular, las ubicadas dentro del ámbito geográfico de la
Universidad Nacional de Lomas de Zamora), es conveniente analizar el impacto del
paradigma de programación funcional en la formación profesional en las carreras
universitarias informáticas.
Delimitación del problema
Este trabajo hace referencia a las tendencias actuales en lo que concierne a la
influencia de los paradigmas de desarrollo de software, en particular el paradigma funcional,
en la formación profesional en las carreras de orientación informática que se dictan en las
instituciones universitarias de gestión estatal de Argentina, en particular las ubicadas dentro
del ámbito geográfico de la Universidad Nacional de Lomas de Zamora (Universidad de
Buenos Aires, Universidad Nacional de La Plata, Universidad de La Matanza y Universidad
Nacional de Lanús).
Hipótesis general
Es posible analizar la conveniencia de la adopción del paradigma funcional como
enfoque de enseñanza en las materias introductorias de las carreras informáticas, con el fin de
definir criterios para mejorar la calidad y flexibilidad de los profesionales informáticos, para
que estén en condiciones de usar herramientas básicas y técnicas que faciliten una adecuación
rápida y eficaz a los cambios tecnológicos actuales.
6
Hipótesis secundarias
Es posible describir el contexto histórico de la evolución de los paradigmas de
desarrollo de software, en especial el paradigma imperativo y el funcional.
Es posible analizar los aspectos más característicos de dichos paradigmas.
Es posible establecer fortalezas y debilidades de dichos paradigmas.
Es posible identificar los diferentes ámbitos de aplicación de desarrollos de
software realizados en lenguajes funcionales.
Es posible estudiar las influencias de las metodologías de desarrollo de
software.
Es posible evaluar el rol del paradigma funcional de desarrollo de software en
relación con su influencia en la formación profesional, en la educación superior
informática en general, y en las carreras universitarias informáticas en particular.
Es posible establecer el impacto del paradigma funcional en los aspectos
teóricos y prácticos de la disciplina de programación.
Marco teórico
Los primeros lenguajes de programación se desarrollaron con un objetivo simple:
proporcionar un método para controlar el comportamiento de las computadoras. No es
sorprendente que estos primeros lenguajes reflejaran bastante bien la estructura subyacente de
las máquinas. A pesar de su aparente grado de racionabilidad, este punto de vista tuvo que
cambiar por dos razones:
Es obvio que lo que parece razonable desde el punto de vista de la máquina,
puede no serlo desde el punto de vista del ser humano.
El aumento de diversidad de clases de computadoras generó la necesidad de un
lenguaje común para programar a todas ellas.
A partir de los primeros lenguajes ensamblador, se desarrolló una gran cantidad de
lenguajes de alto nivel. Esta cantidad fue tal, que hubo necesidad de clasificarlos en familias
que reflejaran un paradigma o estilo de programación común. Una consecuencia natural de
esto es el debate continuo acerca de qué lenguaje o familia de lenguajes es la mejor10.
10 Queda claro que es deseable que los programas puedan ser escritos más rápidamente, en forma más concisa, con un nivel de abstracción más elevado, que sea más ameno en lo referente al razonamiento y análisis formal, y
7
Los lenguajes de programación se clasifican generalmente a partir de dos paradigmas
diferentes: el paradigma imperativo y el paradigma declarativo o funcional.
El paradigma imperativo.
Los lenguajes imperativos se caracterizan por tener un estado implícito que es
modificado por constructores o comandos. Como resultado de esto, estos lenguajes tienen
adquirida la noción de secuencia de comandos para permitir un control preciso y determinista
sobre el estado. Se pueden asociar a estos lenguajes con el concepto “convencional” del
modelo de computadora ideado por Von Neumann a fines de los años ’40. El primero de los
lenguajes imperativos fue FORTRAN, desarrollado por John Backus a principios de los años
’50.
Estos lenguajes de programación convencionales son básicamente abstracciones
complejas del modelo computacional de Von Neumann. Usan variables para emular la
memoria de almacenamiento de la computadora, estructuras de control para imitar las
instrucciones de salto y control, y el concepto de asignación para reproducir el
almacenamiento y cálculo de datos. En esencia, los lenguajes imperativos expresan “cómo”
algo se ha de ser computado.
La vigencia del modelo computacional de Von Neumann derivó en la supremacía de
los lenguajes de programación imperativos, en lo que se refiere a su uso como lenguajes de
desarrollo de software. Pueden existir distintas variaciones, como los lenguajes de
programación estructurada o los lenguajes de programación orientados a objetos, pero en lo
fundamental todos estos lenguajes tienen las características que agrupan a los lenguajes
imperativos.
Queda claro que, al ser el paradigma dominante, la mayor parte de las decisiones en lo
que respecta a la elección de la enseñanza de lenguajes de programación se inclina hacia
lenguajes imperativos, en particular en los niveles introductorios de la educación superior. A
través del tiempo, desde FORTRAN y COBOL, pasando por Pascal y C, hasta llegar a Visual
Basic y Java, los lenguajes imperativos fueron constantemente seleccionados como primer
que pueda ser ejecutado más fácilmente en arquitecturas de cómputo paralelas. Por supuesto, muchas de estas características “deseables” involucran conceptos tan subjetivos, que es una de las razones por las que los debates indudablemente persistirán, al menos mientras las computadoras necesiten de programadores.
8
lenguaje de enseñanza de programación en los diferentes planes de estudio de las carreras
informáticas a lo largo del tiempo.
El paradigma funcional.
El paradigma funcional surge de un modo diferente al imperativo. El modelo de
cómputo procede de las matemáticas, y es incluso históricamente anterior a la aparición de las
computadoras. Dicho modelo es el cálculo lambda, desarrollado por Alonzo Church y
Stephen Kleene entre 1932 y 1941. En particular, el primer lenguaje de programación basado
en la noción de funciones matemáticas fue LISP, desarrollado a principios de los años ’60 por
John McCarthy. Es paradójico que John Backus, uno de los pioneros desarrolladores del
primer lenguaje imperativo – FORTRAN – fuera una de las principales causas del renovado
interés en los lenguajes funcionales. El artículo preparado por Backus para la entrega de los
premios Turing11, es uno de los documentos de mayor influencia y más frecuentemente
citados que exaltan el paradigma de programación funcional.
Los lenguajes frecuentemente se clasifican en funcionales (o aplicativos), y
relacionales (o lógicos). En los lenguajes de programación funcional el modelo subyacente de
cómputo es el concepto matemático de función. En cambio, en los lenguajes de programación
lógica el modelo de cómputo corresponde al concepto matemático de relación o predicado.
Un programa desarrollado en este tipo de lenguajes de programación no posee estados
implícitos. Toda la información necesaria sobre un estado determinado debe ser manipulada
en forma explícita.
La ejecución de un programa funcional consiste, en esencia, en la aplicación de una
función a unos datos. La expresión que resulta se reduce mediante reescritura de sucesivas
expresiones equivalentes, cada vez más sencillas, hasta llegar a una expresión que no es
posible reducir más. Esta expresión irreducible se considera el resultado de la ejecución del
programa para los datos de partida.
Los lenguajes de programación funcional expresan “qué” es lo que ha de ser
computado, en lugar de “cómo” ese algo es computado. Asimismo, permiten a los
programadores concentrarse en el problema a resolver, sin verse obligado a pensar en detalles
11 1977 Association for Computing Machinery Turing Award Lecture
9
de implementación. Esta característica, entre otras, hace que los lenguajes de programación
funcional sean ideales en la enseñanza introductoria de programación.
La programación funcional incorpora características tomadas de diferentes fuentes
junto con otras características originales que, en conjunto, dan al paradigma una gran potencia
expresiva.
De la programación imperativa toma muchas de las facilidades presentes en los
lenguajes modernos: disciplina fuerte de tipos, tipos predefinidos, tipos definibles por
el programador, tipos abstractos de datos, módulos, compilación separada y otras.
De las matemáticas, y en particular de la lógica, toma su aspecto declarativo.
Las funciones se definen mediante ecuaciones. Incorpora propiedades algebraicas
útiles para razonar, la más importante de las cuales es la de transparencia referencial,
según la cual cada identificador o expresión denota un único valor independientemente
del contexto en el que sean utilizados.
De los lenguajes de especificación algebraica toma la definición mediante
patrones y algunas ideas sobre genericidad.
Además, incorpora conceptos originales como polimorfismo paramétrico, funciones de
orden superior y el mecanismo de evaluación perezosa que posibilita la definición de
funciones y tipos de datos no estrictos y estructuras infinitas de datos. Estos dos últimos
conceptos son los más específicos del paradigma, los que confieren al mismo la mayor parte
de su potencia y versatilidad.
Características de los lenguajes funcionales.
La programación funcional toma su nombre por el hecho de que los programas
consisten enteramente en funciones. El programa principal (que es en sí mismo una función)
se define en términos de otras funciones, las cuales a su vez son definidas a partir de otras
funciones, hasta que en el nivel más bajo las funciones son primitivas del lenguaje.
Las principales características y ventajas de la programación funcional se pueden
resumir en lo siguiente:
10
Los programas de programación funcional no tienen instrucciones de
asignación, por lo que las variables, una vez que se le asigna un valor, no cambian a
medida que se ejecuta el programa.
Los programas de programación funcional no contienen efectos colaterales. Es
decir, una llamada a una función no tiene otro efecto más que el de calcular su
resultado. Esto elimina la mayor fuente de errores, y hace que el orden de ejecución
sea irrelevante; una expresión puede ser calculada en cualquier momento. Esto releva
al programador de la preocupación de controlar el flujo de ejecución del programa.
Como las expresiones pueden ser evaluadas en cualquier momento, se pueden
reemplazar variables por sus valores y viceversa. A esto se lo denomina transparencia
referencial. Esto hace que los programas funcionales posean propiedades matemáticas
muy interesantes.
Los lenguajes de programación funcional hacen gala de su “pereza”. Nunca
ejecutan un cálculo, a menos que sea necesario. Esto no es solamente una
optimización: es una manera muy poderosa de ver el mundo. Código que en cualquier
otro lenguaje generaría ciclos sin fin, o consumo de vastas cantidades de memoria, son
trabajo de todos los días en los lenguajes funcionales.
Los lenguajes de programación funcional proporcionan tipos polimórficos, o
sea, tipos de datos que son cuantificados universalmente sobre todos los tipos. Tales
tipos describen esencialmente familias de tipos.
En los lenguajes de programación funcional, las funciones se comportan de la
misma manera que lo hacen otros valores (listas, números etc.). Por ejemplo las
funciones tienen un tipo, pueden retornar otras funciones como resultado, y pueden ser
parámetros de otras funciones. Con la última posibilidad, se pueden escribir funciones
globales, cuyo resultado depende de una función (o más) que es uno de los parámetros
de la función global. A las funciones que tienen funciones como parámetros se las
llama funciones de orden superior, para distinguirlas de funciones numéricas simples.
La instrucción de asignación
John Backus definió a la instrucción de asignación como el “cuello de botella
intelectual” que mantenía a los programadores de lenguajes tradicionales a pensar en función
11
de una-palabra-a-la-vez, neologismo que grafica la manera en que fluye la información en la
computadora (y en la mente de los programadores).
Un programa típico consta de una serie de instrucciones de asignación que operan
sobre un cierto número de variables. Cada asignación modifica una sola variable, produciendo
un solo resultado. El programa debe ejecutar estas instrucciones de asignación de manera
repetida, en forma secuencial, para permitir que los distintos valores deseados se vayan
almacenando de manera adecuada, también de a una a la vez. Parte de la tarea del
programador consiste en administrar el flujo de cada una de estas modificaciones en forma
implícita, diseñando el anidamiento preciso de las distintas instrucciones de asignación, para
que vayan entregando los distintos resultados a medida que se producen las repeticiones. Un
ejemplo clásico es el cálculo del factorial de x:
n := x;a := 1;while n > 0 do
a := a * n;n := n – 1;
end while…
Fig. 1. Implementación imperativa del cálculo del factorial de x.
Esto no sucede en los lenguajes funcionales. En ellos, los resultados se logran a partir
de la modificación de los estados en forma explícita en vez de implícita; y las iteraciones se
consiguen a través de la recursión en lugar de la secuenciación. Siguiendo el mismo ejemplo,
el cálculo del factorial de x:
fact x 1 where fact n a = if n>0 then fact (n - l) (a * n) else a
Fig. 2. Implementación funcional del cálculo del factorial de x.
Aquí se ve claramente que los parámetros n y a son declarados en forma explícita, y
que la estructura recursiva fue definida de manera tal que reproduzca lo más fielmente posible
el comportamiento de ciclo del primer ejemplo. Nótese también que el condicional en este
programa es una expresión, es decir, que se puede reemplazar por un valor. Como valor
agregado está el hecho de que el resultado de este último programa es el factorial deseado, en
vez de haber sido hallado en forma implícita, como en el primer ejemplo.
12
Efectos colaterales y transparencia referencial
El término “transparencia referencial” frecuentemente es utilizado para describir una
de las características fundamentales de los lenguajes funcionales; significa que “los iguales
son reemplazados por iguales”. Es normal dentro de los lenguajes funcionales encontrarnos
con expresiones de este tipo:
. . . x + x . . .where x = f a
Fig. 3. Ejemplo de una expresión en un lenguaje funcional.
La aplicación de la función (f a) puede ser sustituida por cualquier ocurrencia de x
dentro del alcance de la función. En los lenguajes imperativos no es tan inmediato; hay que
asegurarse de que no se realizan asignaciones a x entre su definición inicial y uno de sus usos
subsiguientes. Cualquier asignación a x en estos casos alteraría el resultado final de la
expresión.
Gracias a la transparencia referencial se pueden sustituir términos equivalentes,
independientemente del lugar que ocupe dentro del programa.
Evaluación perezosa de expresiones
El método de evaluación (la manera en que se calculan las expresiones) de los
lenguajes funcionales se llama evaluación perezosa (en inglés “lazy evaluation”). Con
evaluación perezosa se calcula una expresión (parcial) solamente si realmente se necesita el
valor para calcular el resultado. El opuesto de evaluación perezosa es evaluación voraz (en
inglés “eager evaluation”). Con evaluación voraz se calcula directamente el resultado de la
función, si se conoce el parámetro actual.
Sin embargo, cabe preguntarse si la evaluación perezosa es útil para los
programadores. La respuesta es sí, y por los siguientes motivos:
La evaluación perezosa libera al programador de preocuparse por el orden de
evaluación de las expresiones. Más aún, elimina la preocupación acerca de la
eficiencia de los programas, al no tener que evaluar expresiones que no son
absolutamente necesarias. Esto tiene un impacto directo en el concepto de
modularidad del programa.
13
El uso de listas potencialmente infinitas es posible gracias a evaluación
perezosa. En lenguajes que usan evaluación voraz (como todos los lenguajes
imperativos), las listas infinitas no son posibles. Muchas veces es difícil comprender
qué pasa exactamente durante la ejecución. Pero tampoco es necesario saberlo: si se
está escribiendo un programa, se puede suponer que las listas infinitas realmente
existen; el “cómo” ejecutar las cosas es tarea del intérprete.
Polimorfismo paramétrico y ad hoc
El sistema de tipos de los lenguajes funcionales posee una característica que lo
distingue de otros lenguajes de programación. El sistema de tipos tiene dos propiedades
importantes: en primer lugar, se garantiza que toda expresión bien tipificada tenga un único
tipo principal, y en segundo lugar, el tipo principal puede ser inferido automáticamente. En
comparación con un lenguaje con tipos monomórficos, como C, el polimorfismo enriquece la
expresividad, y la inferencia de tipos reduce la cantidad de tipos usados por el programador.
Existe otro tipo de polimorfismo llamado ad hoc o sobrecarga. Estos son algunos
ejemplos de polimorfismo ad hoc:
Los literales 1, 2, etc. son usados para representar tanto valores enteros de
precisión arbitraria, como enteros de precisión limitada.
Los operadores numéricos, como +, suelen estar definidos para distintos tipos
numéricos.
El operador de igualdad suele estar definido para bastantes tipos de datos
(como los numéricos y caracteres) aunque no para todos.
Obsérvese que el comportamiento de estas funciones u operadores sobrecargados suele
ser distinto para cada tipo de dato (de hecho, el comportamiento está indefinido o es erróneo
en ciertos casos), mientras que en el caso del polimorfismo paramétrico, el comportamiento
de la función no depende del tipo. En los lenguajes funcionales, las clases de tipos
proporcionan un modo estructurado de controlar el polimorfismo ad hoc o sobrecarga.
El tipo principal de una expresión o función es el tipo más general que, intuitivamente,
“contiene todos los ejemplares de la expresión”. La existencia de un único tipo principal es la
14
característica esencial del sistema de tipos de Hindley-Milner12, que es la base del sistema de
tipos de muchos lenguajes funcionales.
Un ejemplo simple pero a la vez importante es la igualdad. Hay muchos tipos para los
cuales es deseable que la igualdad estuviese definida, y algunos para los que no. Por ejemplo,
la determinación de la igualdad de funciones es, en general, considerada no computable,
mientras que la comparación de listas es algo habitual. (El tipo de igualdad considerado es
“comparación de valores”, y es distinto a la igualdad de punteros que aparece en otros
lenguajes, como el operador = = de Java. La igualdad de punteros rompe la transparencia
referencial y, por tanto, no es apropiada para un lenguaje funcional puro).
Funciones de orden superior
Si las funciones son tratadas como valores de primera clase (es decir, que pueden
almacenarse en estructuras de datos, ser pasadas como argumentos, y devueltas como
resultados) se las llama funciones de orden superior.
La función map es un ejemplo de una función de orden superior. Esta función está
basada en el principio general “recorrer todos los elementos de una lista”. La función
parámetro de map se aplica a cada elemento de la lista.
Se puede definir la función map de la siguiente manera:
map :: (a->b) -> [a] -> [b]map f [] = []map f (x:xs) = f x : map f xs
Fig. 4. Definición en lenguaje funcional de la función map.
En la definición se usan patrones y se distinguen dos casos: o el segundo parámetro es
una lista sin elementos, o es una lista con por lo menos un elemento (x es el primer elemento,
xs es el resto). Es una función recursiva: si la lista no está vacía, entonces se llama a la
12 El algoritmo comúnmente utilizado para realizar inferencia de tipos normalmente se denomina algoritmo de Hindley-Milner o algoritmo de Damas-Milner. Tiene sus orígenes en el algoritmo de tipos para el cálculo Lambda tipificado, propuesto por Haskell B. Curry y Robert Feys en 1958. En 1969 Roger Hindley extendió ese trabajo y demostró que ese algoritmo siempre deduce el tipo más general posible. En 1978 Robin Milner, de forma independiente al trabajo de Hindley propuso un algoritmo equivalente para el lenguaje de programación ML. En 1985 Luis Damas, estudiante de Milner, finalmente demostró que el algoritmo de Milner es completo y lo extendió para dar soporte a la noción de referencia polimórfica.
15
función map otra vez. El parámetro es más corto en este caso (xs en vez de x:xs), de modo
que en última instancia se utilizará la parte no recursiva de la función.
El principal argumento filosófico para las funciones de orden superior consiste en que
las funciones, en definitiva, son valores como cualquier otro. Sin embargo, queda claro que
las funciones son el primer mecanismo de abstracción sobre los valores; por lo tanto, facilitar
el uso de funciones incrementa el uso de este tipo de abstracción.
Métodos formales y calidad del software.
La calidad del software es una meta importante en cualquier proyecto de desarrollo.
Roger Pressman la define como:
“Concordancia con los requisitos funcionales y de rendimiento explícitamente
establecidos, con los estándares de desarrollo explícitamente documentados, y con las
características implícitas que se espera de todo software desarrollado profesionalmente.”
Esta definición hace hincapié en tres puntos importantes:
Los requisitos son la base de las mediciones de la calidad. La falta de
concordancia con los requisitos es una falta de calidad.
Los estándares especificados definen un conjunto de criterios para el
desarrollo. Si no se siguen estos criterios, casi siempre habrá falta de calidad.
Existe un conjunto de requisitos implícitos que a menudo no se mencionan,
como usabilidad, mantenimiento, etc. La calidad también queda evidenciada en estos
requisitos.
La calidad del software está íntimamente relacionada con la especificación precisa de
los requisitos y de los criterios de desarrollo. En este sentido, los métodos formales juegan un
papel preponderante.
Los métodos formales son técnicas de base matemática para describir las propiedades
de un sistema. Normalmente viene dado por un lenguaje formal de especificación, y
proporciona una forma de definir de manera precisa nociones tales como consistencia,
completitud, especificación, implementación y corrección.
16
La utilización de herramientas matemáticas brinda una serie de ventajas:
Se pueden describir situaciones, objetos o acciones de manera exacta y sucinta.
La transición de una especificación formulada de manera formal hacia las
etapas posteriores tiene una complejidad aceptable.
Los conceptos matemáticos favorecen la abstracción y constituyen una
herramienta excelente para el modelado.
Proporcionan un elevado nivel de verificación cuando son utilizadas como
medio de desarrollo de software.
Tipo de diseño
No experimental, exploratorio y descriptivo.
Cronograma
01 29 de marzo
Reuniones preliminares02 12 de abril03 19 de abril04 26 de abril05 03 de mayo
Revisión por parte de Universidad – Aprobación del Plan de Tesis06 10 de mayo07 17 de mayo08 24 de mayo09 31 de mayo
Presentación formal de la tesis
10 07 de junio11 14 de junio12 21 de junio13 28 de junio14 05 de julio15 12 de julio16 19 de julio
Bibliografía
BACKUS, JOHN. Can programming be liberated from the von Neumann style?: a functional
style and its algebra of programs. Communications of the ACM. Volumen 21, Nº 8, Páginas:
613 – 641, 1978. Traducción propia. Extraída en Enero 2007 desde
http://www.stanford.edu/class/cs242/readings/backus.pdf.
17
BANKER, R. ET AL. Software Errors and Software Maintenance Management. Information
Technology and Management Nº 3, páginas 25 – 41, Kluwer Academic Publishers, Holanda,
2002. Traducción propia. Extraída en Enero 2007 desde
http://www.pitt.edu/~ckemerer/CK%20research%20papers/
SoftwareErrors&Maintenance_Banker2002.pdf
BHARATHI, VKUMAR. -Version programming method of Software Fault Tolerance: A Critical
Review. National Conference on Nonlinear Systems & Dynamics, páginas 173 – 176. Indian
Institute of Technology, Kharagpur, 2003. Traducción propia. Extraída en Enero 2007 desde
http://www.cts.iitkgp.ernet.in/~ncnsd/cd_ncnsd/html/pdf/173-176.pdf.
CESSI ARGENTINA. Informe 2005 | 2006. Situación actual y desafíos futuros de las PyME de
Software y Servicios Informáticos. Primera sección, Página 6. Fundación Observatorio Pyme.
Cámara de Empresas de Software & Servicios Informáticos. Buenos Aires, 2006. Extraída en
Enero 2007 desde
http://www.observatoriopyme.org.ar/pdf/Informe%20Software.pdf.
HANSEN, MICHAEL R. ET AL. Experiences with Functional Programming in an Introductory
Curriculum. ACM Computing Surveys. Volumen 21, Nº 3, Páginas: 359 – 411, 1989.
Traducción propia. Extraída en Enero 2007 desde
http://www.spop.dk/chap-v3/funcProg.pdf.
HUDAK, PAUL ET AL. A Gentle Introduction to Haskell Version 98. Yale University, 1999.
Traducción de Gallardo, José et al. Universidad de Málaga, Dpto. de Lenguajes y Ciencias de
la Computación, 2001. Extraída en Enero 2007 desde
http://haskell.org/tutorial.
HUDAK, PAUL. Conception, Evolution, and Application of Functional Programming
Languages. ACM Computing Surveys. Volumen 21, Nº 3, Páginas: 359 - 411, 1989.
Traducción propia. Extraída en Enero 2007 desde
http://wiki.ittc.ku.edu/ittc/images/e/e1/Hudak.pdf.
JOOSTEN, STEF ET AL. Teaching functional programming to first–year students. Department
of Computer Science, University of Twente. Holanda, 2005.
Traducción propia. Extraída en Enero 2007 desde
http://wwwhome.cs.utwente.nl/~vdberg/articles/Joosten%20Berg%20Hoeven,%201993.pdf.
MARTELLOTTO, PAOLA ET AL. Teoría de Tipos y Coq en la Enseñanza de Programación
Funcional e Imperativa. Taller de Construcción Formal de Programas. Departamento de
Computación, Universidad Nacional de Río Cuarto, 2002. Extraída en Enero 2007 desde
18
http://lsm.dei.uc.pt/ribie/docfiles/txt200332618221A035.pdf
MINISTERIO DE EDUCACIÓN, CIENCIA Y TECNOLOGÍA. Anuario 2004 de Estadísticas
Universitarias. Alumnos, Nuevos Inscriptos y Egresados de Instituciones Universitarias de
Gestión Estatal., Capítulo 2, Página 54–56. Ministerio de Educación, Ciencia y Tecnología.
Secretaría de Políticas Universitarias. Buenos Aires, 2004. Extraída en Enero 2007 desde
http://www.me.gov.ar/spu/documentos/publicaciones/pmsiu_anuario2004.zip.
MINISTERIO DE ECONOMÍA Y PRODUCCIÓN. Libro Azul y Blanco. Plan Estratégico de
Software y Servicios Informáticos 2004–2014. Plan de Acción 2004–2007. Foro de
Competitividad de Software y Servicios Informáticos. Buenos Aires, 2005. Extraída en Enero
2007 desde
http://www.industria.gov.ar/foros/soft_inf/documentos/fssi_libro_ayb.pdf.
PRESSMAN, ROGER. Ingeniería de Software. Un enfoque práctico (5º edición). McGraw Hill,
Madrid 2002.
SOMMERVILLE, IAN. Ingeniería de Software (7º edición). Pearson Educación, Madrid 2005.
THOMPSON, SIMON. Haskell. The craft of functional programming (2nd edition). Addison–
Wesley, Nueva York 1999.
UNIVERSOBIT. Informe mensual del mercado laboral de IT. Boletin Empresas Nro 12.
Buenos Aires, Octubre 2005. Extraída en Enero 2007 desde
http://www.universobit.com/universobit/news_empre.nsf/
2f851bbb109dfaf403256fb70066360a/ba2c9f4ae84e791a032570bd0078a797/$FILE/Informe
%20octubre%202005.doc
19