Download - Trabajo Funcional
2007
FECHA DE ENTREGA
17/12/2007
Paradigma de Programación Funcional
UNIVERSIDAD NACIONAL DE PANAMÁCENTRO REGIONAL UNIVERSITARIO DE VERAGUAS
FACULTAD DE INFORMÁTICA, ELECTRONICA Y COMUNICACIÓN
INGENIERIA EN INFORMÁTICA
FACILITADOR:
DIEGO SANTIMATEO
INTEGRANTES:
ÁLVAREZ FÁTIMA DEL R. 9-722-549
FLORES, KAREM 9-715-2226
SANTILLANA, FABRICIO 2-718-1147
VEGA FERNANDO 6-712-015
II SEMESTRE
2007
TABLA DE CONTENIDO
Pág.
ANTECEDENTES.........................................................................................................3
PROPÓSITO..................................................................................................................4
INVESTIGACIÓN PREVIA.......................................................................................5
PRESENTACIÓN Y COMPARACIÓN.................................................................13
CONCLUSIONES........................................................................................................18
WEBGRAFÍA..............................................................................................................19
2
ANTECEDENTES
Antes de utilizar un lenguaje de programación para resolver un problema,
el o la estudiante debe realizar un análisis del mismo para identificar los
recursos o conceptos que son necesarios para plantear las posibles
alternativas de solución.
Los diferentes paradigmas de programación ofrecen una gama de
alternativas para la solución de un problema mediante un lenguaje de
programación. La programación funcional y lógica, por ejemplo, provee
de niveles de abstracción que facilitan la formulación de alternativas de
solución, evita los efectos colaterales de la asignación, permite la
verificación formal de programas y reduce considerablemente los costos
de mantenimiento. Es por ello, que los invito a entrar a un ambiente de
programación diferente a la que acostumbramos en los cursos anteriores,
me refiero a la programación funcional.
PROPÓSITO
3
Codificar un programa utilizando el lenguaje de Programación
Haskell.
4
INVESTIGACIÓN PREVIA
Identificación de las características del paradigma de programación funcional, ventajas y desventajas respecto a la programación procedural.
Programación Funcional: La programación funcional es aquélla en la que en lugar de construir el programa utilizando instrucciones se construye utilizando funciones, es un paradigma de programación declarativa basado en la utilización de funciones matemáticas.El esquema de un programa en este tipo de lenguajes se puede expresar de la siguiente forma:
PROGRAMA = FUNCIONES + ESTRUCTURAS DE DATOS
5
6
Características Ventajas Desventajas frente a la Procedural
La característica fundamental es que no existe la asignación ni el cambio de estado en un programa.
Programación declarativa Definición y evaluación de
funciones Uso de la recursión Funciones como datos
primitivos Los cálculos se ven como
una función matemática que hacen corresponder entradas y salidas.
1. No hay noción de posición de memoria y por tanto, necesidad de una instrucción de asignación.
2. Los bucles se modelan a través de la recursividad ya que no hay manera de incrementar o disminuir el valor de una variable.
3. Como aspecto práctico casi todos los lenguajes funcionales soportan el concepto de variable, asignación y bucle.
Elegancia, claridad, sencillez, potencia y concisión
Semánticas claras, simples y matemáticamente bien fundadas
Cercanos al nivel de abstracción de las especificaciones formales/informales de los problemas a resolver
Referencialmente transparentes: Comportamiento matemático adecuado que permite razonar sobre los programas
Soportan técnicas muy avanzadas de desarrollo, mantenimiento y validación de programas
Altas dosis de paralelismo implícito
Aplicaciones variadas y de gran interés
• Técnicas muy eficientes de implementación (intérpretes y compiladores). Aquarius conseguía mejores tiempos que C• Compiladores muy “inteligentes·”• Evaluación parcial• Interpretación abstracta• Implementaciones comerciales con bibliotecas muy completas
Programación Imperativa o Procedural: En este paradigma, los conceptos centrales son el de estado (variable o región de memoria que puede consultarse y actualizarse) y el de instrucción (unidad de ejecución que, eventualmente, conduce a la modificación del estado).El esquema de un programa en este tipo de lenguajes se puede expresar de la forma siguiente: PROGRAMA = ALGORITMO + ESTRUCTURAS DE DATOS
7
Características Procedimentales: describen cómo se ha de resolver el
problema y no qué problema es. Deterministas: el resultado nunca cambia si las entradas de
información tampoco lo hacen. Necesitan un proceso que traduzca el código al lenguaje que
maneja la computadora o lenguaje máquina. Ese proceso es el de compilación.
Algorítmicos: muestran cómo resolver los problemas mediante algoritmos.
La comparación de programación funcional y la procedural
La programación funcional es muy diferente de la programación
procedural. Las diferencias más significantes provienen de del hecho que
la programación funcional evita efectos laterales que se usan en la
programación imperativa o procedural para llevar a cabo los estados de
Entrada/Salida. La Pura programación funcional desaprueba los efectos
laterales completamente. Desaprobando los efectos laterales mantiene
transparencia de las referencia que le hace más fácil para verificar el
programa, y más fácil para escribir las herramientas automatizadas para
realizar esas tareas.
Raramente se usan las funciones del orden más altas en la programación
procedural más vieja. Donde un programa procedural tradicional podría
usar una vuelta para cruzar una lista, un estilo funcional usaría a menudo
una función del orden-superior, mapa que las tomas como los argumentos
una función y una lista, aplica la función a cada elemento de la lista, e
ingresos una lista de los resultados.
EJEMPLOS
La característica fundamental del paradigma funcional es que no existe la
asignación ni el cambio de estado en un programa. Las variables son
identificadores de valores que no cambian en toda la evaluación (como
constantes definidas con un DEFINE de C). Sólo existen valores y
expresiones matemáticas que devuelven nuevos valores a partir de los
declarados.
8
En los lenguajes imperativos o procedurales, sin embargo, se realizan
asignaciones que cambian el valor de una variable ya existente.
Por ejemplo:
1. { int x = 1;
2. x = x+1;
3. int y = x+1;
4. { int x = y;
5. y = x+2; }
6. y = x;}
En este fragmento de programa se mezclan instrucciones imperativas con
instrucciones declarativas. Por ejemplo, las instrucciones 1, 3 y 4 son
declarativas, ya que están definiendo una variable con un valor asociado
(están dando un nombre a un valor). Sin embargo, las sentencias 2, 5 y 6
son imperativas, ya que están modificando el valor de una variable
mediante asignaciones de nuevos valores.
Otro elemento interesante del ejemplo es el ámbito de alcance de las
declaraciones de las variables. Por ejemplo, la variable x declarada en la
línea 4 tiene un ámbito distinto de la declarada en la línea 1. La x de la
línea 5 es la declarada en la línea 4, mientras que la x de la línea 6 es la
declarada en la línea 1. Dentro de un mismo ámbito podemos renombrar
todas las ocurrencias de una variable sin que el programa cambie.
Por ejemplo, el siguiente programa es equivalente al anterior:
Por ejemplo:
1. { int x = 1;
2. x = x+1;
3. int y = x+1;
9
4. { int x = y;
5. y = x+2; }
6. y = x;}
Los programas declarativos frente a los imperativos, para saber si un
lenguaje es declarativo basta con comprobar lo siguiente: dentro del
ámbito de declaración de las variables x1 ... xn todas las ocurrencias de
una expresión e que contiene únicamente las variables x1 ... xn tienen el
mismo valor.
Como consecuencia, los lenguajes funcionales tienen una interesante
propiedad de optimización: si una expresión e aparece en varios lugares
dentro de un mismo ámbito, sólo es necesario evaluarla una vez
En los lenguajes funcionales las variables denotan nombres asociados a
valores. En los lenguajes imperativos, sin embargo, las variables denotan
referencias a valores que existen en algún lugar del ordenador (estado) y
que pueden ser cambiados con sucesivas instrucciones. Este es otro
elemento que distingue los lenguajes imperativos de los declarativos. En
los lenguajes funcionales no existe ese concepto de valor que reside en
algún lugar del ordenador al que nos referimos mediante una variable.
Por ejemplo, el siguiente programa imperativo:
{ int a[3] = {1, 5, 7}
int *b = a;
b[0] = 3;
int c = a[0]+a[2];}
10
En este programa, las variables a y b hacen referencia al mismo array (a la
misma posición de memoria). De hecho, cuando en la tercera instrucción
cambiamos el valor de la primera componente de b, también estamos
modificando los valores a los que se refiere a, de forma que en la última
instrucción c tomará el valor de 6. Al modificar b hemos modificado a ya
que ambos se refieren (apuntan, si utilizamos una terminología de C) al
mismo valor. Esto se denomina un efecto lateral.
Un lenguaje funcional no contiene referencias en el sentido del ejemplo
anterior. Las referencias son exclusivas de los lenguajes imperativos. El
uso de referencias permite que un mismo objeto (dato, valor) sea
referenciado por más de un identificador y permite efectos laterales como
el que hemos visto. Un lenguaje funcional está libre de efectos laterales.
11
PRESENTACIÓN DE LOS EJEMPLOS Y COMPARARLOS
Ejemplo # 1: Raices de una ecuación de segundo grado
Calcular las raíces cuadrada de una ecuación de segundo grado es un
procedimiento sencillo en la matemática. Solo necesitamos utilizar la
fórmula general.
Para obtener una salida en Haskell deberemos primero calcular las
distintas partes por la cual esta constituida la fórmula en Haskell sería:
disc = b*b - 4*a*c
raizDisc = sqrt disc
denom = 2*a
Luego se procede al cálculo de la ráiz cuadrada y lo codificamos en un
código Haskell:
disc >= 0 = ((-b + raizDisc) / denom,
(-b - raizDisc) / denom)
Podemos definir que valores pueden ser permitidos mediante el operador
>= lo cual nos permite asegurar que el número del cual queremos obtener
la raíz no sea negativo.
Para indicarle al usuario si ha ocurrido algún error utilizamos el sistema
de excepciones de Haskell mediante:
otherwise = error "La ecuacion tiene raices complejas"
12
Ahora podemos definir nuestra función en Haskell como se muestra a
continuación
raices a b c
| disc >= 0 = ((-b + raizDisc) / denom,
(-b - raizDisc) / denom)
| otherwise = error "La ecuacion tiene raices complejas"
where
disc = b*b - 4*a*c
raizDisc = sqrt disc
denom = 2*a
Cuando deseemos obtener las raices cuadrada de una ecuación de
segundo grado lo haremos de la siguiente manera:
Ejemplo #2: Puntos del plano Cartesiano.
punto ::(Float,Float)->IO()
punto (x,y) = do
if(x>0)&&(y>0) then putStr "Pimer Cuadrante"
13
else if(x<0)&&(y>0) then putStr "Segundo Cuadrante"
else if(x<0)&&(y<0) then putStr "Tercer Cuadrante"
else if(x>0)&&(y<0) then putStr "Cuarto Cuadrante"
else if(x==0)&&(y>0) then putStr "Eje Y Positivo"
else if(x==0)&&(y<0) then putStr "Eje Y Negativo"
else if(y==0)&&(x<0) then putStr "Eje X Negativo"
else if(y==0)&&(x>0) then
putStr "Eje X Positivo"
else putStr "Origen"
Para ejecuta esta función debemos escribir la instrucción punto(x,y), en
el intérprete de haskell, x , y deben ser números reales de lo contrario
habrá un error en la ejecución, podemos ver en este ejemplo que a pesar
de ser haskell un lenguaje funcional, permite instrucciones como en
lenguaje imperativo, if, else, case, etc. como vemos en este caso usamos las
instrucciones if y else, aunque este no es el fuerte del lenguaje ya que
normalmente es la recursividad por ser un lenguaje funcional.
Este programa es en si una función que recibe como parámetros dos
números de tipo real, hay que tomar en cuenta cuando programamos en
haskell, que las funciones siempre devuelven algo, la instrucción IO() es
un tipo abstracto, en esta función es visto como el valor de retorno, IO()
14
no devuelve nada, es usado para que se escriba el mensaje
correspondiente en la salida estándar.
Ejemplo #3: Area de figuras Geométricas.
data POLIGONO = Triangulo (Float, Float)| Cuadrado Float| Rectangulo (Float, Float)
area:: POLIGONO -> Floatarea (Triangulo (b, h)) = (1/2) * b * harea (Cuadrado lado) = lado * ladoarea (Rectangulo (b, h)) = b * h
Para ejecutar este programa debemos escribir alguna de estas instrucciones en intérprete de Haskell(WinHugs):
area(Triangulo (4,5))area (Rectangulo (4,5))area (Cuadrado 4)
La Salida de este programa es el área de alguna de las figuras indicada
Triangulo, rectángulo, cuadrado, es un numero real.
Podemos observar como se define un tipo de dato en este caso Polígono,
este debe empezar como vemos con una letra en mayúscula y precede a
la palabra reservada data, este programa ejemplifica como se definen los
tipos en Haskell.
Polígono define el tipo de datos, como si fuera una estructura de datos en
C, ahora vemos como se utiliza este tipo de dato, en el programa.
Primero vemos que definimos una función área que recibe como
parámetros un dato de tipo Polígono y devuelve un valor de tipo Flotante.
15
CONCLUSIONES
Luego de culminado esta experiencia podemos concluir que:
Los lenguajes funcionales se apoyan en la definición de funciones y
hacen uso de la aplicación y composición de funciones, además de
considerar las funciones como objetos.
El programador en haskell especifica mediante ecuaciones lo que se ha
de calcular y no cómo ha de.
Como los programas son expresiones matemáticas, es posible sustituir
variables por valores, lo que permite manipular los programas como
16
ecuaciones funciones de alto nivel (high-order functions). Es posible
utilizar funciones como argumentos de otras funciones o devolverlas
como resultado.
Sin embargo sentimos que puede haber menor eficiencia en aspectos
que nos impiden asignar/actualizar variables.
Otra desventaja en cuanto a la utilización de este lenguaje de
programación falta de experiencia de los programadores, pues el retraso
de la implementación eficiente de estos lenguajes así como de la
implementación de entornos de programación específicos ha influido
negativamente en el número de usuarios.
WEBGRAFÍA Wikipedia, La enciclopedia libre, (2005, Octubre 8), [En línea].
“Esta página es bien completa muestra se constituyó un comité cuyo
objetivo era crear un lenguaje funcional que reuniera las características
de los múltiples lenguajes funcionales de la época.
Enlaces que me permiten accesar a las biografías de los desarrolladores
principales de los lenguajes, además consultar como se implementa o
para que el lenguaje.
Disponible http://es.wikipedia.org/wiki/Haskell [Consulta: 11 de
Diciembre 2007].
Mar, Marcos,” Introducción a la Programación Haskell” [PDF]. 9
De Febrero de 2005
17
“El objetivo de este manual es el de introducir algunos de los conceptos
fundamentales de la Programación Funcional y del lenguaje Haskell.
Conociendo sus características principales” [Consulta: 11 de Diciembre
2007].
18