Gracias @espencer, nuestro gran «early adopter» del development, llegué a un artículo del «Tío Bob» (te dejo la entrevista que le hice hace un tiempo) de esos que te deja pensando un buen rato.
El artículo expone por qué el futuro de tecnología puede pasar por los lenguajes de programación funcionales (como Haskell, F# o Clojure), frente a los imperativos (Java, C, etc.).
Lo que le contaría a Dijkstra. La columna de los jueves. |
Y voy a intentar explicados el porqué, de la manera más sencilla y divulgativa que me sea posible, a sabiendas de que, por lo arduo del tema, la tarea es compleja.
Vamos allá.
Los lenguajes de programación que usamos normalmente son imperativos, es decir, cuando programas vas diciendo lo que el programa debe hacer, le vas dando ordenes. Por ejemplo, «implementar un programa que calcule el cuadrado de los 25 primeros números enteros», en Java (imperativo) vendría a ser algo así como:
for (int i=1; i<=25; i++)
System.out.println(i*i);
Pero en Clojure (un lenguaje de programación funcional) sería algo como:
(take 25 (squares-of (integers)))
Hasta aquí bien. Ahora viene lo que nos interesa.
Observa que en el anterior no hay variables. ¿Qué sucede entonces en la memoria del ordenador? Las posiciones de memoria se inicializan sólo cuando el programa las utiliza, y luego conservan sus valores, sin cambios, durante el resto de la ejecución del programa. Ningún nuevo valor se asigna a esas posiciones de memoria. Ninguna variable, una vez inicializada, puede cambiar nunca de valor.
¿Por qué es todo esto tan importante para el futuro de la tecnología?
Si estás leyendo este post en tu portátil, y es medio decente, seguramente su procesador tenga 4 núcleos. Los de hace unos años tenían 2 núcleos. Y mucho tiempo atrás sólo un núcleo. Seguramente, los siguientes tendrán 8 núcleos, y después 16, 32, etc.
La frecuencia de reloj de los ordenadores (los ciclos de procesador) ya no pueden ir mucho más rápido. Han estado doblando velocidad durante años, pero están llegando a un punto en que la velocidad no puede incrementarse más. Así que los ingenieros de hardware, en un esfuerzo para darnos más y más ciclos por segundo, recurrieron a lo de añadir más procesadores a nuestros chips, y aquí no parece haber fin, no hay un límite de cuantos procesadores podrán añadir.
Y llegado este punto ¿cómo vamos a aprovechar cada ciclo de procesador cuando tengamos 4096 núcleos? ¿16384 procesadores compitiendo por el mismo bus de memoria? ¿Sitios web ágiles y flexibles con sus modelos, vistas y controladores compartiendo 65536 procesadores?
Como comenta el tío Bob, ya es difícil hacer cooperar a dos hilos (Threads) en Java. Y hilos son comida para niños en comparación con procesadores reales que luchan por el bus.
Esto es lo que se llama simultaneidad, y para tratar con ella hay que olvidar las asignaciones a variables. Si el valor de una posición de memoria, una vez inicializada, no cambia durante el curso de la ejecución de un programa, entonces los 131072 procesadores no tienen que competir.
No necesitas semáforos. Y no hay efectos secundarios… y ahí está la clave de los lenguajes funcionales, que resuelven muy fácilmente este problema.
El tren de la programación multi-core se acerca, y es mejor estar listos para cuando llegue. De ahí, todos los nuevos lenguajes funcionales que aparecen como Scala, F# y Clojure. Y de que se vuelva a hablar de los lenguajes antiguos, como Erlang, Haskell, ML y otros.
Algo más…
Si quieres empezar a jugar con lenguajes funcionales, yo he estado trasteando con Haskell en esta web, que tiene un IDE online.
Como siempre, difunde el conocimiento, tuitea, envía, comenta, etc.
- Diario: cómo Javier Garzás evita quedarse obsoleto estudiando a un X10 con IA-Esteroides - 7 noviembre, 2024
- Si creas Historias de Usuario con IA ¿A quién pertenecen? ¿A ti o la IA? El mono Naruto te lo explica - 31 octubre, 2024
- HistorIAs de usuario y como a Maximiliano lo ENGAÑABAN con la IA y como una viejuna historia del 1500 le salvó - 24 octubre, 2024
Hola,
Pues si esto se cumple vamos a tener un problema porque creo que no conozco a nadie que sepa hacer el hola mundo en funcional, y menos calcular por ejemplo los factoriales, o cosas sencillas de ese tipo.
Bueno, el problema igual es que no conocemos a esas personas, pero hay miles. Precisamente el factorial es algo que funcionalmente es mucho más natural que de manera imperativa; no es un problema de capacidad del lenguaje o de falta de expertos, yo creo que es una deformación por las tendencias de las últimas dos décadas, que nos hacen pensar en C, en Java, en VB, en Python… y poco más.
Me parece ultra elegante poder definir algo como:
factorial n = if n == 0 then 1 else n * factorial (n – 1)
Sobre todo, sabiendo que el hardware lo va a ejecutar de manera super eficiente. Otra cosa es que la sintaxis no nos sea familiar porque llevemos años programando en herederos de C y similares.
El caso es que si tenemos un problema porque los paradigmas cambian o porque hemos de adaptarnos a tecnologías desconocidas… ¡valientes expertos en software que somos!
La argumentación en la entrada en defensa de la p. funcional es muy sensata, pero hay que tener presente que es un razonamiento restringido a lo que conocemos actualmente. Parece una tautología, pero en software sabemos que las predicciones (salvo algunas genialidades) tienen las patas muy cortas porque a poco que te despistes, llega un listo y te vuelca el establishment.
Los debates en torno a qué lenguaje de programación (o qué tipo de lenguaje, según diversas clasificaciones) siempre me han resultado poco más que un divertimento. Considero que un verdadero profesional, antes de atacar cualquier desarrollo, debe analizar todos los aspectos del proyecto y elegir la tecnología más adecuada. Si todas las premisas que expones son ciertas en el tiempo y se convierten en la tendencia principal de manera sostenida, los desarrolladores tendrán que migrar a las herramientas que permitan implementar buenos proyectos. O derivar trabajo a los profesionales expertos en la tecnología más adecuada.
Las reflexiones como la de este post sirven para que los ya lúcidos tengan más argumentos, pero no iluminan a nadie que no quiera ver. Con la experiencia que tenemos en los últimos años, sabemos que aunque todas las evidencias tecnológicas dejen claro qué caminos tomar, la gente seguirá con la inercia de ‘lo que saben’ y ‘lo que es mejor siempre’.
Por concluir, dejo también dos cuestiones. ¿Y si acabamos todos programando en Prolog? ¿Qué pasa con el desarrollo para tecnologías como CUDA? Pese a estar basada en una potente paralelización, se programan en lenguajes nada funcionales como son C y C++.
Pingback: Bitacoras.com
Por si a alguien le interesa :
«Functional Programming Principles in Scala» https://www.coursera.org/course/progfun
Es gratis y me han dicho que necesitas unas 5-7 horas a la semana incluyendo videos. El tutor es Martin Odersky, creador de Scala y uno de los principales colaboradores. Empieza el 25 de marzo.
Yo ya me apunte hace unos dias 🙂
Cuando se acerque el dia te avisaran.
Saludos
Pues creo que es un argumento falso a mi entender. Cualquier compilador de C en la actualidad genera código muy óptimo que hace el menor número de accesos a memoria posible. De hecho, si bicheas en el código ensamblador te darás cuenta de que algunas variables jamás «tocan» la memoria. En el ejemplo que has puesto probablemente ocurra eso.
Pero es que además tenemos que tener en cuenta las cachés de los distintos núcleos. Una vez cargada una línea en caché, los accesos a memoria principal son mínimos en algoritmos que realicen cálculos repetitivos. Hay que hacer código a mala leche para provocar continuos fallos de caché.
Ocurre algo parecido cuando programas con GPGPU. Si programas como es debido, el mayor número de accesos a memoria se producen en memoria local del hilo o compartida del bloque. Además, haciendo intercambio constante de «warp» de hilos se enmascaran los accesos a la memoria global de GPU.
Todo esto dicho muy grosso modo.
Hace dos años que aprobé la asignatura de «programación funcional», nos enseñaron Haskell, y fue todo un reto, pues básicamente tuve que olvidar todo lo que sabía de programación hasta el momento para aprender a utilizar un lenguaje declarativo.
No se si será el futuro o no, pero a mi me abrió la mente de una manera bárbara, luego en asignaturas del año siguiente donde utilizábamos python (como en inteligencia artificial), me di cuenta que estaba utilizando herramientas típicas de lenguajes funcionales, como la correspondencia de patrones, recursividad…. que ayudan a escribir mucho en pocas lineas de código
Desde luego espero que en el futuro me encuentre con este lenguaje en mi trabajo, aunque nunca olvidare la frase de la profesora el primer día de clase «es posible que nunca más os encontréis con Haskell, a no ser que os dediquéis a la robótica»
Y otra razón que yo creo es más importante: es porque se pueden validar y verificar dichos programas, mientras que en un programa hecho en un lenguaje imperativo, la explosión de casos es tan alta que es inviable probarlos todos.
No sería esto un hueco eficiente para matemáticos? creo que el mundo de la informática perdió eso de la funcionalidad laboral, no todos tenemos que saber hacer de todo, quizás eso nos esté haciendo mas ineficaces aunque por otra parte más preparados.
Habrá que ponerse las pilas..
Sobre esto de programación funcional (que confieso no tengo ni idea) os dejo 2 enlaces interesantes:
un libro (que no he leido)
http://pragprog.com/book/btlang/seven-languages-in-seven-weeks
y una web de programación donde se pueden encontrar muchos ejercicios:
http://www.solveet.com/
Pingback: ¿Bases de datos NoSQL o Bases de datos SQL? ¿Tiene sentido en “nuestro mundo” usar bases de datos NoSQL? - Javier Garzás | Javier Garzás
La programación funcional, por ejemplo casos de Javascript o el potentísimo Perl, básicamente tiene los siguientes atributos que la distingue de los otros paradigmas de progamación (el procedural, declarativo y OOP):
1.- el uso de closures.
2.- call-backs.
3.- funciones como objeto-argumentos.
4.- variables contextuales
La closure permite el uso de variables privadas a nivel de función. Esto tiene un poder total que hace trivial la implementación de cache memory, memoization, curry etc. Es decir el retorno de una función es una referencia a una función interna que mantiene los valores de las variables de la función externa.
las variables contextuales, son en esto fundamental, la referencia a una función no necesita ser especificada como un ptr función en C++, por ejemplo, fuertemente tipado, sino que se adapta a cualquier tipo de función. Esto permite, junto con las closures, la creación de potentes patrones factories de objetos de una manera muy elegante y sucinta.
Sí, la prog. fncional es el futuro,ya es el presente.
OS ME ATREVO A DECIR QUE TODOS ESTAN HABLANDO GILIPOLLESES, JAVA ES EL FUTURO DE LA PROGRAMACION Y NADA MAS…
Los debates en torno a qué lenguaje de programación (o qué tipo de lenguaje, según diversas clasificaciones) siempre me han resultado poco más que un divertimento. Considero que un verdadero profesional, antes de atacar cualquier desarrollo, debe analizar todos los aspectos del proyecto y elegir la tecnología más adecuada. Si todas las premisas que expones son ciertas en el tiempo y se convierten en la tendencia principal de manera sostenida, los desarrolladores tendrán que migrar a las herramientas que permitan implementar buenos proyectos. O derivar trabajo a los profesionales expertos en la tecnología más adecuada.