Reflexiones funcionales con Julia Language — Parte I
Explorando la programación funcional con Julia

Julia se considera un lenguaje de propósito general, tipificado dinámicamente que admite múltiples paradigmas de programación. Estrictamente hablando, aunque Julia no es un lenguaje de programación funcional (FP), lo admite.
Entonces, ¿qué es un lenguaje de programación funcional "puro"? Son lenguajes que están diseñados para tener funciones matemáticas que usan expresiones condicionales y recursividad para realizar cálculos. Utilizan datos inmutables, evaluación perezosa y otras construcciones para "hacer cumplir" la forma de programación de FP. Estos lenguajes pueden ser bastante concisos y obstinados. Un buen ejemplo de esta clase de idioma es Haskell.
Julia, sin embargo, está más que feliz de darle el poder al programador, en lugar de colocar limitaciones y barreras en el camino para forzar la adhesión a tal o cual paradigma.
¿Es Julia un buen lenguaje para programar de forma Funcional? creo que lo es Entonces, ¿por qué Julia es buena en programación funcional? Por muchas razones, incluida la metaprogramación, los objetos de primera clase, el potente sistema de tipos, el envío múltiple y muchas otras razones.
FP está ganando popularidad últimamente. Los estados de objetos mutables son el nuevo código espagueti y la concurrencia solo aumenta la complejidad. FP admite programación paralela y concurrencia, lo que genera menos errores y código limpio. FP tiene en sus raíces sólidos conceptos matemáticos e ideas de un campo matemático emergente conocido como teoría de categorías.
Profundicemos y comencemos a construir algunos conceptos.
Programación funcional en acción
Digamos que estoy interesado en encontrar el cubo de algunos números, podría escribir:
3 * 3 * 3
2 * 2 * 2
cube(x) = *(x,x,x)
cube(x) = x * x * x
Ahora estoy interesado en calcular algunas series. Comenzaremos diseñando una función para calcular la suma de los números enteros de a a b:
Ahora, no sería exagerado suponer que, en algún momento, estaría interesado en calcular también la suma de los cubos de los números enteros en un rango dado. En este caso, mi función podría verse así:
No es difícil detectar el patrón de código presente en las dos definiciones de funciones anteriores. Otra pista es el tipo de suma implícito en el nombre de la función misma. Lo que necesitamos es otro nivel de abstracción, para que podamos calcular la suma de cualquier serie. Necesitamos hacer explícito el tipo de sum y pasarlo como argumento a la función en lugar de codificarlo en el cuerpo de la función.
Con la definición de función anterior, hacemos explícito el tipo de función para sumar en el argumento. He anotado el parámetro "f" para dejar claro que esta es una función y no otro valor.
Ahora, si quiero la suma de cubos del 1 al 10, puedo llamar como tal:
O si quiero la suma de enteros del 1 al 10, puedo escribir:
Explorando las funciones de Julia
En Julia, las funciones son objetos de primera clase y se pueden pasar como argumentos a otras funciones. Esto abre la puerta a soluciones aún más elegantes con niveles más profundos de abstracción.
Podemos seguir construyendo abstracciones sobre abstracciones. También podemos canalizar funciones juntas en cadenas. Se dice que Julia es un lenguaje altamente componible. Aquí es cuando un poco de conocimiento de la teoría de categorías puede ayudarte a convertirte en un mejor programador. La Programación Funcional tiene profundas raíces en los fundamentos matemáticos.
El ejemplo anterior muestra formas equivalentes de combinar y componer funciones juntas.
Los ejemplos anteriores muestran cómo pasar funciones como argumentos puede ayudarnos a lograr niveles más profundos de abstracción en nuestro código. Pero uno no necesita detenerse ahí. Podemos crear funciones cuyos valores devueltos sean en sí mismos funciones. Tome el siguiente código como ejemplo. Considere una función f que devuelve el valor promedio entre x y f(x) . Llamaremos a esta función promedio_humedad .
julia> average_damp(square)
#7 (generic function with 1 method)
Para obtener nuestro valor húmedo promedio de una función cuadrada en x=10 , llamamos con:
julia> average_damp(square)(10)
55.0

julia> dx = 0.00001;
julia> deriv(cube)(5)
75.00014999664018
El siguiente es un ejemplo de tal función:
julia> withdraw(20)
80
julia>
julia> withdraw(20)
60
julia> withdraw(20)
40
julia> withdraw(20)
20
julia> withdraw(20)
0.0
julia>
De todos modos, más por venir la próxima vez...
Referencias: “Estructura e Interpretación de Programas de Computadora”, Abelson y Sussman