Revelaciones
epifanía sobre la programación funcional
Revelación de Kleisli, para manifestar a sus siervos las cosas que deben entender pronto y la declaró enviándole su avatar a Eduardo su siervo.
El cual ha dado testimonio de la palabra de Turing y de Church y de todas las cosas que ha visto y aprendido.
Bienaventurado el que lee y los que oyen las palabras de esta revelación y guardan las cosas en ella escrita, porque el tiempo de ejecución está cerca.
Yo Eduardo, vuestro hermano en la tribulación, en el reino y en la paciencia, estaba en la red, buscando la palabra categórica que revelara el sentido último de la Teoría de Categorías.
Y fui en el espíritu de devoción que navegaba por los oscuros rincones de la internet profunda cuando oí una voz como de trompeta que decía:
Yo soy el Lambda y la Clausura, la Cabeza y la Cola. Escribe en el blog lo que ves y envía este mensaje a la Noosfera.
Porque hasta aquel momento yo pensaba que sabía lo que era una función, y vivía feliz en mi ignorancia.
Y fue que la voz como trompeta me dijo: “¡Estás profundamente equivocado!”
Porque para los matemáticos, me dijo la voz, una función es simplemente una asociación entre un valor de entrada y un valor de salida.
Pero ustedes, programadores, en vuestra arrogancia, habeis pervertido el sentido de lo que una función es.
A veces vuestras funciones retornan un valor aleatorio, y si las evaluais en distintos tiempos retornais valores distintos.
Y el día lunes vuestra función responde un valor distinto del que respondió el sábado o lo que responderá el próximo miércoles.
O vuestras funciones a veces provocan que aparezcan palabras y textos en una pantalla, o impriman en papel sus resultados.
Y aunque comparten con las funciones de los matemáticos la posibilidad de la composición, son bestias muy distintas.
Pero en realidad lo que vosotros llamais Funciones, para los matemáticos son Categorías.
Y fue entonces que llorando me arrodillé y le implore al Avatar que estaba ante mi que me revelara esta cuestión tan misteriosa.
Entonces con su voz de trueno me dijo, escucha, aprende y toma nota, pobre programador.
Una Categoría es una colección de Objetos y Flechas. En tu limitada mente puedes llamar a las colecciones de objetos conjuntos si quieres. Y puedes imaginar que las flechas son funciones entre los conjuntos.
Pero pon atención. Cada Flecha tiene un Dominio y un Rango. Cada Objeto tiene una Flecha “Identidad” y las Flechas pueden ser compuestas cuando los Dominios y los Rangos se corresponden.
Y estas cosas fueron creadas porque el mundo es complejo y no son suficientes las funciones que los matemáticos suelen usar.
Pero presta atención, porque estas Flechas te protegen contra los Cuatro Jinetes de las Catepocalipsis.
Y miré y vi cuatro bestias semejantes a caballos y sobre ellas iban montados cuatro espantosos Jinetes.
El primer jinete era de color blanco y se llamaba Fallo.
Escucha pobre programador, me dijo el Avatar, ustedes construyen muchas cosas que pueden fallar, desde intentar leer archivos que no existen o tratar de enviar mensajes por internet cuando no hay conexión, hasta hacer cálculos con grandes cantidades de datos sin tener memoria suficiente. Es ahí cuando se encuentran con el primer jinete llamado Fallo.
Tomé nota y observé al segundo jinete de color bermellón que se llamaba Dependencia.
Entonces el Avatar habló. Este es el segundo de los jinetes que afecta a tus abstracciones, desdichado programador. Por que las funciones de los matemáticos son autocontenidas, pero las que escribes en tu código no.
Tus programas están llenos de configuraciones. Mira tu teléfono, tiene páginas y páginas de configuraciones. ¿En qué lenguaje desplegará sus mensajes?, ¿con qué frecuencia se graba una copia de tu trabajo?, ¿deben encriptarse las comunicaciones sobre la red?
Rara es la aplicación que no tenga un menú de configuración y preferencias.
Durante años los programadores han usado áreas compartidas de memoria para guardar esta información. Y aunque podríais pasar estos ajustes en cada llamada a cada función, esto sería bastante inconveniente.
Tomé nota y medité sobre esto.
Fue cuando me espantó el estrepitoso ruido del tercer caballo, sobre este estaba un jinete de color amarillo, que se llamaba Incerteza.
Ese es Incerteza, me dijo el Avatar, también conocido como No Determinismo. Una función normal asocia una entrada con una salida. Una función no determinista asocia una entrada con un número de posibles salidas. Este es el jinete más misterioso de todos.
Este espectro aparece cuando consultas, buscas o consideras muchas posibles respuestas. Cabalga por el reino de los lenguajes de dominio específico, como SQL.
Pensé en aquellos lenguajes terminados en QL o en ese fascinante intento de defensa contra este jinete llamado LINQ. Porque gran parte de las estructuras más complejas de programación de estas aciagas eras no son más que débiles fortalezas que tratan de reducir la incerteza de los resultados.
Finalmente contemplé al último jinete de color negro, que llamaban Destrucción.
Contempla a Destrucción, exclamó con voz retumbante el Avatar, es el producto de tus funciones. Porque tus cálculos tienen efectos sobre el mundo, cada vez que despliegas una información, o esperas una respuesta desde otros computadores, o personas. ¡A veces vuestros programas hacen explotar cosas literalmente!
Tus programas tienen una naturaleza destructiva, porque producen efectos que muchas veces no pueden ser deshechos. Esto hace que tus programas tengan más errores. Dificultan la división de tareas, porque si ejecutas las partes en el orden inadecuado puedes obtener las respuestas incorrectas.
Pero no puedes vivir sin Destrucción, porque ¿de qué sirve un programa sin efectos observables?
Entonces lloré angustiado, y le pregunté al Avatar si había manera de derrotar a estos jinetes.
No temas, me respondió, porque puedes usar el poder de las Matemáticas para hacer que estos jinetes trabajen para tí. Anota pobre programador mis palabras y difúndelas como verdad revelada.
Porque para cada función que tu programas puede convertirse en una función matemática si cambias el Rango de cada una de ellas.
Esto es lo que harás con Fallo, dijo.
Toda seudo función que puede fallar es simplemente una función cuyo resultado incluye dos cosas: Éxitos, que son los posibles resultado esperados, y Fracasos que describen por qué el intento falló.
De este modo si tienes un conjunto A, definiremos un conjunto Err(A) que es A más las posibles razones de porque algo pudo fallar. Entonces cuando tengas una función que puede fallar, que va desde el conjunto A al conjunto B, la puedes redefinir como una función de A a Err(B).
Y en ese momento vi que en la pared se dibujaron estos símbolos:
Si F: A -> B puede fallar entonces define F': A -> Err(B).
Ahora escucha que debes hacer con Dependencia, me dijo el Avatar.
Toma todas tus seudo funciones que de dependen de información que obtienen del mundo alrededor de ellas. Para estas define el conjunto Pref(A) que es el conjunto de funciones con aplicaciones de los ajustes, o configuraciones, del conjunto A. Ahora observa bien, una función en contexto de A hacia B es una función ordinaria de A a Pref(B).
Entonces entendí que lo que me quería decir es que para un valor del conjunto A, la función retorna otra función que mapea configuraciones de la aplicación al conjunto B.
A esto se le llama Currying, me advirió el Avatar.
De este modo, al cambiar el rango de la seudo función se agrega un parámetro adicional que recibe las configuraciones de la aplicación.
Y en la pared aparecieron estos símbolos
Si F : A -> Pref(B) tiene dependencias => define F' : A -> Pref(A) -> Pref(B).
Mi mente estalló tratando de entender esto último cuando el Avatar exclamó.
¡Pon atención estúpido programador, porque esto es lo que harás con la Incerteza!
Simplemente si tienes un conjunto A, debes definir el conjunto potencia de A, como el conjunto de todos los conjuntos posibles con valores de A. A esto lo llamarás P(A).
Si tienes una seudo función no determinista de A hacia B conviertela en una función de A a P(B).
Y una tercera fila de símbolos se grabaron en la pared:
Si F : A -> B es no determinista => define F': A -> P(B).
Por último, dijo el Avatar, escucha como manejarás la Destrucción.
Definirás un nuevo rango, que llamarás IO(A). Un elemento del conjunto IO(A) es una lista de instrucciones para obtener un miembro de A. No es un miembro de A, sólo una manera de obtener uno y este procedimiento puede tener cualquier número de efectos observables.
Entonces si tienes una seudo función destructiva de A a B conviértela en una función matemática de A a IO(B).
Y yo entendí que si le doy a la función un valor de A ésta no ejecutará los pasos para obtener B, pero ciertamente me dirá cuales son estos pasos.
Fue cuando la cuarta fila de símbolos apareció en el muro.
Si F : A -> B es destructuva => define F' : A -> IO(A).
Entonces temblé de pavor, porque sentí que una gran verdad me estaba siendo revelada, pero era incapaz de entenderla. Fue cuando escuché las últimas palabras del Avatar que me advirtió.
Escucha bien, pobre programador, porque veo que estás cansado. He de abandonarte por ahora, pero quiero que sepas que mi nombre es Kleisli y esto que acabo de revelarte es fundamental.
!He aquí, vengo pronto! Bienaventurado el que guarda las palabras de la revelación de este blog.
Yo Eduardo soy el que oyó y vio estas cosas. Y después que las hube oído y visto, me postré para adorar a los pies del Avatar que me mostraba estas cosas.
Y me dijo: No selles las palabras de la revelación de este blog, porque el tiempo está cerca.
Yo vengo pronto, y mi galardón conmigo, para recompensar a cada uno con el significado de qué son las Monadas.
Así la visión se desvaneció y desperté pensando que diablos habré comido o bebido esa noche...