Está en la página 1de 7

,

PROGRAMACION
FUNCIONAL:
CONCEPTOS
y PERSPECTIVAS
Fabio Augusto Gonzle: Osorio
Instructor Asociado
Departamento de Ingeniera de Sistemas
Universidad Nacional de Colombia
fgonza@ ingenieria. ingsala. unaLedu.co.

Resumen

El presente artculo muestra conceptos Existen otros paradigmas de programacin


subyacentes a la programacin funcional, as como diferentes al imperativo como la programacin
caractersticas que los hacen un enfoque particular funcional y la programacin lgica, cuyo estudio,
y novedoso de la programacin que lo convierten desarrollo y uso han estado principalmente
en una clara opcin frente al enfoque imperativo restringidos al mbito acadmico. La programacin
convencional en el rea del desarrollo de software. funcional, es casi tan antigua como la imperativa; el
primer lenguaje funcional, LlSP, fue desarrollado en
la misma poca en la que se desarroll FORTRAN.
INTRODUCCIN Sin embargo, la programacin funcional ha estado
tradicionalmente circunscrita a reas de aplicacin
El estilo de programacin imperativa (es decir, especficas como la inteligencia artificial y la
la programacin a travs de acciones que modifican computacin simblica.
el estado del computador) ha dominado el panorama
de la programacin desde sus inicios; los lenguajes A pesar de la hegemona de la programacin
de ms amplio uso estn basados en este paradigma: imperativa la programacin funcional cada vez toma
Fortran, e, C++, Pascal, Basic, etc. Una razn ms fuerza gracias a su capacidad expresiva, que
fundamental de este dominio reside en que los permite escribir programas ms compactos, y a su
lenguajes imperativos son ms cercanos a la forma transparencia referencial que posibilita la sencilla
como realmente funciona la mquina. verificacin matemtica de propiedades de los

---------=-~.::..:....:..:. INGENIERA E INVESTIGACIN 11


programas. Igualmente, caractersticas como la define en trminos de otras funciones, y stas, a su
recoleccin automtica de basura, los sistemas de vez, en trmino de ms funciones; esta cadena
inferencia de tipos, el polimorfismo, la orientacin a finaliza en funciones predefinidas o primitivas.
objetos, el emparejamiento de patrones, los
algoritmos eficientes de compilacin, se han A simple vista, un programa en lenguaje C se
desarrollado gracias al gran trabajo investigativo ajustara a la definicin de programa funcional (de
de los ltimos aos. hecho algunas personas consideran que el C es un
lenguaje funcional); sin embargo, la principal
Todo lo anterior permite ubicar a la diferencia de los programas funcionales puros
programacin funcional como una importante respecto a los programas convencionales
opcin para el desarrollo de software que facilite (imperativos) es que los nicos elementos
hacer realidad los ideales de la ingeniera de software constructores en los primeros son la definicin y la
como son: la reusabilidad, la modularidad, la aplicacin de funciones, mientras que en los
mantenibilidad y la correccin[3]. programas imperativos se utilizan, adems, variables,
asignaciones ciclos iterativos, etctera.
En el presente artculo se pretende mostrar
las ideas subyacentes a la programacin funcional, Parece muy restrictivo el hecho de no poder
as como ilustrar las caractersticas que la hacen un utilizar variables, ni asignaciones, ni ciclos
enfoque particular y novedoso de la programacin. iterativos; sin embargo se ha demostrado
De igual manera, se hablar brevemente de su matemticamente que la definicin y la aplicacin
historia desarrollo y perspectivas. de funciones era suficiente para construir cualquier
funcin computable' .
I. QU ES LA PROGRAMACIN
FUNCIONAL? Para ilustrar la diferencia entre el enfoque
imperativo y el funcional considrese el problema
Una definicin de programacin funcional de construir una funcin f que reciba como
generalmente aceptada es la siguiente: argumento un natural n y retome la suma de los
naturales desde 1 hasta n, es decir:
"El estilo de programacin que enfatiza la
evaluacin de expresiones, antes que la ejecucin n
de comandos "[6].
f (n)=L i
;=1
La definicin anterior es bastante amplia y tal
vez ambigua, pues no se precisa a qu se refiere el En un lenguaje imperativo como C, se podra
nfasis del cual habla. Esto refleja la frontera difusa definir la funcin de la siguiente forma:
que existe entre lenguajes funcionales puros y
lenguajes no funcionales; en esta frontera se ubican int f(int n)
lenguajes como LISP, SCHEME y ML, que nadie {
dudara en catalogar como funcionales a pesar de int i;
que tienen caractersticas no puras como intsuma=O;
asignaciones y efectos laterales, a diferencia de los for (i=l; i<=n; i++)
lenguajes funcionales puros, los cuales desarrollan suma=suma+ i;
todos su cmputos exclusivamente a travs de la retum suma;
aplicacin de funciones.

Una programa funcional est constituido


enteramente por funciones; el programa principal 1. Elfundamento de los lenguajes funcionales es el clculo
lambda, desarrollado por Haskell Curry en la dcada del
es una funcin que toma como argumento la entrada 30. Es un clculo de funciones basado en la abstraccin y
al programa y genera la salida del programa como la aplicacin. Curry demostr que las funciones definibles
su resultado. Tpicamente, la funcin principal se dentro de este clculo corresponden a las computables por
una mquina de Turing[lJ.

-~______;__;______;__;----
INGENIERA E INVESTIGACIN
La implementacin de esta funcin en un comporta asintticamente como fib (n) lo cual se
lenguaje funcional definitivamente exigira otra nota como t(n) = O(fib (n))). Una mejor opcin sera
estrategia, pues en estos lenguajes no se cuenta calcular fib (n) de manera iterativa, es decir,
con variables, ni asignaciones, ni ciclos. Por tanto, generando fib {J), fib (2), fib (3), etc, hasta llegar
se recurrir a una definicin recursiva- equivalente al fib (n) (en cada paso se utilizan los dos ltimos
def valores para generar el siguiente valor); el tiempo
O sin=O de ejecucin de este algoritmo t' (n) se comporta
f(n)= { f(n - 1)+ n en otro caso asintticamente como n (t'(n)=O(n)), es decir el
tiempo es una funcin lineal del argumento de la
Que en el lenguaje como CAML se vera de la funcin, el cual es claramente mejor que el tiempo
siguiente forma: del algoritmo recursivo.

let rec f= fun 0-> O A continuacin se muestra 1a implementacin


I n-> f(n -1)+ n;; del algortmo iterativo (realmente iterativo recursivo)
enCAML:
EnSCHEME
letrec fibaux (n, cont,pen,ult) =
(define f(lambda (n)(if(n=O)O (+(j(-n ln if (cont>=n ) then ult
else fibaux (n, cont+ 1, ult, pen+ult);;
En HASKELL (esta es una versin no let rec fib n = fibaux (n, 2,1,1 );;
recursiva, pero bastante elegante!):
II. DNDE RESIDE LA POTENCIA
f n= sum [l..n] DELA PROGRAMACIN FUNCIONAL?

La ineficiencia de la recursin para resolver La potencia de la programacin funcional


ciertos problemas es conocida; esto podra verse depende de varias caractersticas que poseen los
como un grave inconveniente para la programacin lenguajes funcionales; entre ellas: el manejo de
funcional la cual hace uso extensivo de la misma, funciones de alto orden, la declaracin de tipos
sin embargo, algoritmos iterativos pueden similarse algebraicos, la inferencia de tipos, el emparejamiento
a travs de la recursin. Para mostrar esto, de patrones y el manejo automtico de la memoria
analicemos el tpico algoritmo que calcula el n-simo dinmica.
trmino de la sucesin de Fibonnaci, la cual se define
como: Estas caractersticas no son exclusivas de los
lenguajes funcionales; en el caso del
si n=lvn=2 emparejamiento de patrones esta facilidad fu
fib(n) =~b(n - 1) ~ fib(n - 2) en otro caso tomada de Prolog. El manejo automtico de la
memoria dinmica, aunque tiene su origen en un
Un programa en CAML calcularfib (n) seria: lenguaje funcional,LISP, hoy en da lo poseen
lenguajes imperativos como JAVA; sin embargo
let rec fib = fun 1 -> 1 todas estas caractersticas han estado ligadas
I 2 -> 1 estrechamente al desarrollo de la programacin
I n -> fib (n - 1)+ fib (n - 2);; funcional.

Este programa, aunque bastante fiel a la A continuacin se describirn los elementos


definicin matemtica de la funcin, es demasiado caractersticos ms relevantes de la programacin
ineficiente, pues su tiempo de ejecucin t (n) se funcional.

2. Valga la pena aclarar que existe una solucin mucho


ms sencilla: emplear lafrmulaf(n)=n(n+l)/2. La frmtda
recursiva se presenta con fines puramente ilustrativos.

INGENIERA E INVESTIGACIN
A. Funciones de alto orden en CAML que nos permita obtener la versin
'currificada' de una funcin con dos argumentos:
El concepto "alto orden" se refiere a funciones
que reciben como argumento o retoman funciones, let curryf= (fun x -> ([uny-> f(x,y)));;
es decir, las funciones pueden manipulase como
datos; esta caracterstica tambin es referida como Utilicemos la funcin curry aplicada sobre
"funciones como objetos de primera clase." deriva para construir una funcin g' que
corresponda a la derivada de g (x )=x"2-1:
Por ejemplo, podramos utilizar la siguiente
definicin de la derivada de una funcin! letgx =x *. x-l.O;;
let g' = (curry deriva) g ;;
f'(x)= Lim f(x+h)-f(x)
h~oo h El proceso de evaluacin de g' 3. O sera:

g' 3.0= => ((curry deriva)g) 3.0


para construir una funcin deriva que nos ==> (tfun x -> (fun y ->deriva(x,y))) g) 3.0
aproxime la derivada de cualquier funcin ==> (fun y -> deriva (g,y)) 3. O
==> deriva (g, 3.0)
fjloat ~ float
let deriva (f,x) = ([(x +. 0.00 l) -. f(x) ) /. 0.00 It;'

En este caso, f sera una funcin que es B. Tipos algebraicos


recibida como argumento por deriva; por lo tanto,
deriva sera una funcin de alto orden. En el Los lenguajes funcionales con tipos como
siguiente ejemplo: ML y Haskell dan la posibilidad de declarar tipos
adicionales a los tipos primitivos (int, char, float,
let gx = x*. x -. 1 . O in deriva (g, 3. O);; etc.). Los tipos declarados por el usuaro se definen
mediante constructores como la enumeracin:
Est calculndose una aproximacin de la
derivada de g(x) =x2-l calculada en x= 3.
let direccin = norte I sur I oriente I occidente;;
Un concepto asociado a las funciones de alto
orden es el de currying, el cual tiene su origen en el ...el producto cartesiano de tipos ya definidos
estudio matemtico de funciones. En pocas palabras, o primitivos:
este concepto sugiere que es suficiente estudiar
funciones de un solo argumento. Por ejemplo, let racional = fraccion of int *int;;
considere la funcinf(x,y) =x+y, la cual puede ser
expresada como una funcin g tal que g (x) es una y definiciones recursivas:
funcin que al ser aplicada sobre y nos retoma x+y,
es decir (g(x))(y)= x+y; implementado en CAML let lista = vacia I cons ofint *lista ;;
quedara:
En el primer caso, se define un tipo que solo
let g x = fun y -> x+y ;; posee cuatro valores posibles; en el segundo
ejemplo, el tipo racional se construye como el
E 1 proceso de evaluacin para g 3 4 es: producto cartesiano del tipo primitivo int; valores
como fraccin (3, 4) r fraccin (-4, 2), etc.,
g 34 ==> (funy -> 3+y) 4 ==> 3+4 ==> 7
3. En CAML, los operadores aritmticos seguidos de un
En general, dada una funcinf(x,y), el proceso punto (+. -. *. 1. ) se refieren a operadores sobre reales; el
de currying consiste en construir una funcin g tal punto los distingue de los operadores respectivos sobre
que g (x)(y) =j{x, y). Podemos construir una funcin enteros[IOj.

1IIII~~fN~G~E_~_E_Rl_'~A~E~~
__E~S~T~IG~A~C_IO~'N ___
pertenecen a este tipo. Fraccin es un constructor funciones por casos; esto le da mayor capacidad
que no se ha declarado previamente. expresiva al lenguaje permitiendo escribir el cdigo
ms claro, sencillo y conciso.
En el ltimo ejemplo se emplea el tipo lista
dentro de su propia definicin; concretamente se Un ejemplo de definicin de una funcin
dice que una lista puede ser vacia o el 'cons' de un utilizando emparejamiento de patrones es la funcin
entero con una lista ya existente; en este caso 'cons' fib recursiva del numeral 1. Otro ejemplo es la
se puede entender como la operacin de adicionar siguiente definicin de la funcin Suma que calcula
un entero la cabeza de la lista. Ejemplos de elementos el tamao de una lista de enteros segn la
del tipo lista son: definicin del tipo lista dada en el apartado B. del
numeral 11.
vaca
cons (5, vaca) let rec Suma = fun vaca -> O
cons ( 3, cons (9, cons ( 1, vaca))) I cons (cabeza, resto) -> cabeza
+ Suma (resto);;
Como puede observarse, el nmero de
elementos pertenecientes al tipo lista es infinito; Aqu estn definindose dos patrones
esto es, efecto directo del carcter recursivo de su posibles C'vacia" y "cons (cabeza, resto)") que
definicin. Precisamente esta caracterstica, la pueden tomar el argumento enviado a suma; el
recursividad es la que le da el nombre de algebraico compilador trata de emparejarlo con cada uno. En
al sistema de tipos y le permite al programador definir caso de conseguirlo, ejecuta el cdigo a
y manejar estructuras bastante complejas, sin continuacin de la flecha (- .
necesidad de manipular apuntadores; esto elimina
Por ejemplo, en caso de evaluar Suma
la gestin directa de la memoria dinmica y, por tanto
cons(5, cons(2, cons(8, vacia))) , el compilador
obvia, una gran fuente de errores.
empareja el argumento con el segundo patrn
("cons (cabeza, resto)'') haciendo cabeza=5 y
Otro ejemplo de tipo recursivo es el de rbol
resto=cons(2, cons(8, vacia)); la evaluacin de la
expresin continuara as:
type arbolbi = vado I nodo ofint*arbo1bi*arbolbi;;
Suma cons (5, cons (2, cons (8, vacia) ) )
En este caso estn representndose el tipo
=> 5 + Suma cons (2, cons (8, vacia) )
de rboles binarios con etiquetas enteras en sus
=> 5 + 2 + Suma cons (8,vacia)
nodos. El siguiente rbol:
=> 5 + 2 + 8 + Suma vacia (en este caso se empareja el

primer patrn)
1O => 5 + 2 + 8 + O
/ \
2 5 D.Inferencia de tipos
\
Tradicionalmente, los sistemas de tipos de
Se representa mediante la siguiente expresin los lenguajes de programacin se han dividido en
de tipo arbolbi: dos: estrictos y no estrictos. En el primer caso, el
programador debe declarar el tipo de cada una de
nodo (10, nodo (2, vacio, nodo (1, vacio, vacioi), las variables y de los argumentos de las funciones
nodo (5, vacio, vacio)) y procedimientos, y ceirse de manera estricta a
estas declaraciones; en el segundo caso, el
C. Emparejamiento de patrones programador no debe ceirse necesariamente a las
declaraciones' y eventualmente las puede obviar,
El emparejamiento de patrones (en ingls como cuando a una funcin declarada en C que
Pattern Matching), se refiere a la posibilidad que recibe un entero, se le enva como argumento un
brindan algunos lenguajes funcionales de definir nmero de punto flotante.

- ~:.:....:....=..~II
INGENIERA E INVESTIGACIN .
La experiencia ha demostrado que los sistemas intrprete para la funcin curry definida en el
de tipos estrictos son preferibles a los no estrictos, apartado A del numeral 11.es:
pues favorecen la depuracin sencilla del cdigo al
eliminar en tiempo de compilacin muchos errores curry :(a' *b' -> c') -> (a' -> (b' -> c'))
potenciales; sin embargo pueden resultar muy
engorrosos para el programador por su falta de el cual evidencia el alto orden de la funcin, pues
flexibilidad. sta recibe como parmetro una funcin de tipo (a'
*b' -> c') y retoma una funcin (tambin de alto
Los sistemas de inferencia de tipos orden) de tipo (a' -> (b' -> c')).
representan un punto intermedio entre los dos
esquemas mencionados anteriormente. Por un lado, PERSPECTIVAS Y CONCLUSIONES
conservan el carcter estricto del sistema de tipos y
por otro liberan al programador de declaraciones Las caractersticas que hemos ilustrado de
explcitas de los tipos de los argumentos de las hasta ahora evidencian el gran potencial de los
funciones y de sus valores de retomo. Esto puede lenguajes funcionales como herramientas que les
parecer contradictorio, pero la clave est en que el facilite a los programadores enfrentar la complejidad
compilador hace el trabajo de asignacin de tipos creciente del desarrollo de software; esto nos
por el programador y, lo que es mejor, lo hace de la permite afirmar que en los prximos aos los
manera ms general posible, es decir, evidenciando lenguajes funcionales tomarn un lugar en el rea
la genericidad y el polimorfismo cuando stos tienen de desarrollo de software a gran escala, aliado de
cabida dentro de una funcin. lenguajes tan tradicionaies como e, e++,ADA [3,4].
La afirmacin anterior se sustenta con los siguientes
Por ejemplo, al introducir la funcin Suma puntos:
definida en el apartado e del numeral Il.C, el intrprete
de eAML responde con el siguiente mensaje: Transparencia referencial. Este concepto
se refiere a la propiedad de los lenguajes
Suma: lista -> int = <fun> funcionales que hace que la misma expresin
siempre represente el mismo valor; esto
Lo cual est indicndonos que la funcin permite probar matemticamente la correccin
Suma recibe como argumento un dato del tipo lista de un programa. La posibilidad de escribir
y retoma como resultado un entero; esto es inferido programas cuya correccin es probable en
por el intrprete de manera automtica. vez de gastar el tiempo pescando errores
puede revolucionar el proceso de
En el caso de una funcin como la siguiente: produccin de software.

lel primero (x, y) = x;; Fundamentacin matemtica. Desde sus


inicios, la programacin funcional ha tenido
La cual de una pareja de datos nos retoma el un gran componente matemtico, el clculo
primero, puede ser aplicada a parejas de diferentes Lambda, la lgica combinatoria, las teoras
tipos de datos; por tanto, el sistema de tipos debe de tipos, los sistemas de reescritura, la teora
inferir el tipo ms general posible y ste es: de dominios y la teora de categoras son
algunas de las reas de la matemtica que la
primero: a' * b ' -> a' fundamentan. Esto le da pilares sufi-
cientemente slidos que le permiten ser la
Donde a' y b ' se refieren a cualquier tipo, es base del desarrollo de una verdadera ciencia
decir, son variables de tipo que nos indican el de la programacin.
carcter general de la funcin. El tipo inferido por el
Eficiencia de compiladores e intrpretes.
4. En lenguajes como LISP ni siquiera existe el concepto Uno de los inconvenientes que tradi-
de tipo, todos los datos son compatibles entre s; ste es el cionalmente se le ha achacado a los lenguajes
caso extremo. funcionales es la ineficiencia de sus

1I__
IN_G_EN_I_E_Rl_'A_E_IN_V_E_ST_I_G_A_C_IO_'N _
intrpretes y compiladores. Hoy da, esto no BIBLIOGRAFA
representa un problema pues los avances
investigativos han permitido la construccin
l. CURRY H., FEYS R. Combinatory Logic,- North-
de compiladores que generan cdigo nativo
Holland , 1958.
que iguala en eficiencia el cdigo generado
por compiladores convencionales (C, 2. DYBVIG K. The Scheme programming
Fortran, etctera.). language. Addisson- Wesley 1996.

3. HUGHES J.Why functional programming


Paralelismo Implcito. El hecho que los matters.The computer Journal, vol. 32 N 2. Abril
lenguajes funcionales (puros) no permitan 1989.
efectos laterales ni el uso de variables
4. POUNTAIN. D. "Functional programming
globales, hace que la evaluacin de
comesof age ": BYTE, Agosto de 1994
diferentes expresiones constituyan procesos
independientes y, por tanto, que pueden ser 5. SETHI R. Programming languages, Addisson-
ejecutados de manera simultnea. Esta Wesley 2 Ed ., 1996.

caracterstica puede ser explotada para


Pginas en internet
programar computadores paralelos de
manera natural algo que no se ha logrado de Preguntas frecuentes de comp. lang functional
manera satisfactoria a travs de la
6. http://www.cs.nott.ac.uk/Department/Staff/
programacin convencional.
gmb/faq. html

Programacin funcional

7. http://cm-bell-Iabs.com/cm/cs/who/wad ler/
guide.html

8. http://www.lpac.ac.uklSEL- HPC/Articles/
FuncArchive.html

9. http://carol.fwi.uva.nl/-:jon/func.html

Lenguajes

10. CAML: http://pauillac.inria.fr/camllindex-eng.


html

11. Haskell: http://www-i2 informatik.rwth-


aachen.de/Forschung/FP/Haskell/

12. Scheme: http://ai.mit.edu

________

INGENIERA E INVESTIGACIN 11
1

También podría gustarte