Lenguajes de Programación

 

Estructurada Modular O. Obejtos Concurrente Funcional Logica Volver

Programación Funcional

 

En ciencias de la computación, la programación funcional es un paradigma de programación declarativa basado en la utilización de funciones aritméticas que no maneja datos mutables o de estado. Enfatiza la aplicación de funciones, en contraste con el estilo de programación imperativa, que enfatiza los cambios de estado.

 

La programación funcional tiene sus raíces en el cálculo lambda, un sistema formal desarrollado en los años 1930 para investigar la definición de función, la aplicación de las funciones y la recursión.

 

Los lenguajes de programación funcional, especialmente los que son puramente funcionales, han sido enfatizados en el ambiente académico principalmente y no tanto en el desarrollo de software comercial. Sin embargo, lenguajes de programación importantes tales como Scheme, Erlang, Rust, Objective Caml y Haskell, han sido utilizados en aplicaciones comerciales e industriales por muchas organizaciones.

 

La programación funcional también es utilizada en la industria a través de lenguajes de dominio específico como R (estadística), Mathematica (matemáticas simbólicas), J y K (análisis financiero), F# en Microsoft.NET y XSLT (XML). Lenguajes de uso específico usados comúnmente como SQL y Lex/Yacc, utilizan algunos elementos de programación funcional, especialmente al procesar valores mutables. Las hojas de cálculo también pueden ser consideradas lenguajes de programación funcional.

 

La programación funcional también puede ser desarrollada en lenguajes que no están diseñados específicamente para la programación funcional. En el caso de Perl, por ejemplo, que es un lenguaje de programación imperativo, existe un libro que describe como aplicar conceptos de programación funcional. JavaScript, uno de los lenguajes más ampliamente utilizados en la actualidad, también incorpora capacidades de programación funcional. Python también incorpora particularidades de los lenguajes funcionales como listas de comprensión y funciones de tratamiento de listas como matemática de conjuntos. Java en su versión 8, esta incorporando la programación funcional, así como el uso de las expresiones lambda.

 

Resumiendo, la programación funcional, o mejor dicho, los lenguajes de programación funcionales, son aquellos lenguajes donde las variables no tienen estado — no hay cambios en éstas a lo largo del tiempo — y son inmutables — no pueden cambiarse los valores a lo largo de la ejecución. Además los programas se estructuran componiendo expresiones que se evalúan como funciones. Dentro de los lenguajes funcionales tenemos Lisp, Scheme, Clojure, Haskell, OCaml y Standard ML, entre otros. Estos lenguajes están diversidad de tipificación, donde se encuentran lenguajes dinámicos, estáticos y estáticos fuertes

 

Para citar un ejemplo de mostrar un mensaje  “Debo poner atención en clases”. La respuesta expresada en PHP esta escrita a continuación. Donde PHP es un lenguaje dinámico, no necesita declarar variables y es un lenguaje orientado a objetos con raíces imperativas. Sus instrucciones son paso a paso, y no constituyen una única expresión reducible.

 

<?php
    /* codigo PHP */
    for ($i = 0; $i < 500; $i++) {
        echo "Debo poner atencion en clases";
    }
 ?>

Si usamos Haskell como ejemplo, que es un lenguaje funcional con tipificación estática fuerte, requiere que las variables sean declaradas con un tipo — la mayoría de las veces — y es muy expresivo, donde el siguiente ejemplo dice repetir la cadena, tomar 500 elementos y con esa lista ejecutar la función monádica putStrLn, que esta hecha para el Monad IO e imprime la el mensaje las 500 veces solicitada

.module Main (main) where
-- codigo Haskell
main :: IO ()
main = mapM_ putStrLn $ take 500 $ repeat "Debo poner atención en clases"

 

En Lisp sería similar, pero Lisp es de tipificación dinámica y no necesita declarar variables, dando lugar a un programa muy simple de una sola línea. Donde también tenemos lenguajes como Clojure, que es un dialecto de Lisp y soporta construcciones muy similares a las del ejemplo en Lisp, dando lugar a programas expresivos y simples, pero que corren sobre la máquina virtual de Java o JVM

 

;;; codigo Lisp
(loop repeat 500 do (format t "Debo poner atencion en clases~%"))

 

Un ejemplo clásico para la conversión η en Haskell, es reducir las llamadas a funciones en su combinador de identidad. Por ejemplo se tiene la función f(g(x)), que en Cálculo Lambda se expresa como λx.(λy.y)x, se puede reducir a g(x), que se expresa como λy.y en Cálculo Lambda. Esto expresado en Haskell, se vería como el siguiente ejemplo, donde absN y absN’ son funciones equivalentes y absN’ es la reducción η de absN.

absN :: Num a => a -> a
absN n = abs n
 

absN' :: Num a => a -> a
absN' = abs

Actualmente los lenguajes orientados a objetos más comunes están integrando características funcionales, como Java, que acaba de incluir funciones anónimas. Pero también están los lenguajes que a lo largo de su historia han sido multi-paradigma, como Python, e implementa características funcionales, procedurales y orientadas a objetos. El bien conocido algoritmo para verificar si un RUT es válido o no, se puede expresar funcionalmente en Python como esta escrito en el siguiente ejemplo.

def val_rut(rut):
    """
    Valida un string con un RUT con el guión incluido, retornando cero si es valido.

    Ejemplo: print(val_rut("22222222-2"))
    """
    return cmp(rut[-1],
               str((range(10) + ['K'])[
                   (11 - sum(map(lambda x: (int(x[0]) * x[1]),
                                 zip(reversed(rut[:-2]),
                                     (2 * range(2, 8))))) % 11)]))

 

Como se aprecia en el ejemplo, la validación se realiza utilizando expresiones o llamadas a funciones, sin uso de variables con estado y mutabilidad, donde cada llamada a una función se puede reducir a un valor determinado, y como resultado final se tiene un valor cero o distinto de cero que indica si el RUT es válido. Este mismo algoritmo funcional, se puede expresar en Haskell con llamadas muy similares, debido a que los nombres de las funciones y funciones de alto orden son bastante comunes entre los lenguajes funcionales.

valRut :: String -> Bool
valRut s = (((['0'..'9'] ++ ['K'])
             !! (11 - sum(zipWith (*)
                          (fmap digitToInt $ drop 2 $ reverse s)
                          (take 10 $ cycle [2..7])) `mod` 11)) == (last s))

 

 

 

 Volver