Últimamente he notado que los lenguajes de programación funcionales están ganando popularidad . Recientemente vi cómo el Índice Tiobe muestra un aumento en su popularidad en comparación con el año pasado, aunque la mayoría de ellos ni siquiera llegan a los 50 idiomas más populares según este índice.
Y este ha sido el caso durante bastante tiempo. La programación funcional simplemente no se ha vuelto tan popular como otros modelos (es decir, programación orientada a objetos).
Sin embargo, he visto un interés renacido en el poder de la programación funcional, y ahora que los multinúcleos son cada vez más populares, los desarrolladores han comenzado a mostrar interés en otros modelos de concurrencia ya explorados en el pasado por lenguajes como Haskell y Erlang.
Veo con gran interés el hecho de que, a pesar de su falta de aceptación significativa por parte de la comunidad, siguen surgiendo más y más idiomas de este tipo. Clojure (2007), Scala (2003), F # (2002) son solo tres ejemplos de la última década.
Yo mismo he invertido algo de tiempo aprendiendo Haskell y Scala. Y encuentro un gran potencial en el paradigma que para mí era nuevo a pesar de estar ahí por tanto tiempo.
Y, por supuesto, mi mayor pregunta es si alguno de estos se volverá lo suficientemente popular como para considerar poner algún esfuerzo en ellos, pero esta es una pregunta que ni siquiera Mandrake podría responder, a pesar de todo el alboroto que la gente está haciendo sobre ellos.
Lo que sí quiero preguntar es:
- ¿En qué escenarios debería considerar un lenguaje de programación funcional más adecuado para realizar una tarea determinada? Además del problema multinúcleo tan popular de la programación paralela.
- Si decidiera cambiar a un lenguaje de programación funcional, ¿cuál consideraría que son los mayores escollos que enfrentaría? (Además del cambio de paradigma y la dificultad de evaluar el rendimiento debido a la evaluación perezosa).
- Con tantos lenguajes de programación funcionales, ¿cómo elegiría el que mejor se adapte a sus necesidades?
Cualquier recomendación para futuras investigaciones será más que bienvenida.
He buscado opiniones en la web, y parece que toda esta popularidad renovada proviene de la idea de que ahora estamos a punto de llegar al muro de la Ley de Moore y que vendrán lenguajes de programación funcionales y nos salvarán heroicamente. Pero si este es el caso, diría que hay más probabilidades de que los lenguajes populares existentes se adapten al paradigma.
Algunos de ustedes, con más experiencia trabajando todos los días con estos idiomas tal vez, pueden ofrecer más información sobre el tema. Todas sus opiniones serán mejor apreciadas y consideradas cuidadosamente.
¡Gracias por adelantado!
Respuestas:
Cualquier cosa que implique crear una secuencia de elementos de datos derivados utilizando una serie de pasos de transformación.
Básicamente, el "problema de la hoja de cálculo". Tiene algunos datos iniciales y un conjunto de cálculos fila por fila para aplicar a esos datos.
Nuestras aplicaciones de producción realizan una serie de resúmenes estadísticos de datos; Todo esto se aborda mejor funcionalmente.
Una cosa común que hacemos es una combinación de combinaciones entre tres conjuntos de datos monstruosos. Similar a una unión SQL, pero no tan generalizada. Esto es seguido por una serie de cálculos de datos derivados. Todo esto son solo transformaciones funcionales.
La aplicación está escrita en Python, pero está escrita en un estilo funcional usando funciones generadoras y tuplas inmutables con nombre. Es una composición de funciones de nivel inferior.
Aquí hay un ejemplo concreto de una composición funcional.
Esta es una forma en que la programación funcional influye en lenguajes como Python.
A veces, este tipo de cosas se escribe como:
Los objetos inmutables son el obstáculo más difícil.
A menudo terminará calculando valores que crean nuevos objetos en lugar de actualizar objetos existentes. La idea de que es un atributo mutable de un objeto es un hábito mental difícil de romper.
Una propiedad derivada o función de método es un mejor enfoque. Los objetos con estado son un hábito difícil de romper.
No importa al principio. Elige cualquier idioma para aprender. Una vez que sepa algo, puede elegir otro para que se ajuste mejor a sus necesidades.
He leído sobre Haskell solo para entender las cosas que le faltan a Python.
fuente
"Funcional" es un conjunto de características diferentes, cada una de las cuales es útil de forma independiente, y me resulta más útil observarlas individualmente.
Inmutabilidad
Ahora que estoy familiarizado con él, cada vez que puedo evitar devolver un resultado inmutable, siempre trato de hacerlo, incluso en un programa orientado a objetos. Es más fácil razonar sobre el programa si tiene datos de tipo de valor. Por lo general, necesita mutabilidad para cosas como GUI y cuellos de botella de rendimiento. Mis entidades (que usan NHibernate) también son mutables (lo cual tiene sentido porque están modelando datos almacenados en una base de datos).
Funciones como tipos de primera clase
Como quiera llamarlo, pasar delegados, acciones o funciones, es una forma realmente útil de resolver una clase completa de problemas del mundo real, como el "agujero en el patrón intermedio". También descubrí que pasar un delegado, acción o función a un objeto es más limpio que hacer que esa clase declare un evento y enganche ese evento (suponiendo que normalmente haya un solo "oyente"). Cuando sepa que hay un oyente, la acción de devolución de llamada puede pasarse como un parámetro de constructor (¡y almacenarse en un miembro inmutable!)
Ser capaz de componer funciones (por ejemplo, convertirse
Action<T>
en solo unaAction
también es bastante útil en algunos escenarios).También debemos tener en cuenta la sintaxis de Lambda aquí, porque solo obtienes la sintaxis de Lambda cuando promocionas funciones a tipos de primera clase. La sintaxis de Lambda puede ser muy expresiva y concisa.
Mónadas
Es cierto que este es mi punto débil, pero entiendo que los flujos de trabajo computacionales en F #, como el
async
flujo de trabajo, son una mónada. Esta es una construcción sutil pero muy poderosa. Es tan poderoso como layield
palabra clave utilizada para crearIEnumerable
clases en C #. Esencialmente está construyendo una máquina de estado para ti bajo las sábanas, pero tu lógica parece lineal.Evaluación perezosa y recursión
Los puse juntos porque, si bien siempre están agrupados como características de la programación funcional, se han abierto camino tan rápidamente a lenguajes imperativos que ya es difícil llamarlos funcionales.
Expresiones S
Creo que no estoy seguro de dónde poner esto, pero la capacidad de tratar el código no compilado como un objeto (e inspeccionarlo / modificarlo), como Lisp S-Expressions o LINQ Expressions, es, de alguna manera, La herramienta más poderosa de programación funcional. La mayoría de las nuevas interfaces "fluidas" de .NET y DSL utilizan una combinación de sintaxis lambda y expresiones LINQ para crear algunas API muy concisas. Sin mencionar Linq2Sql / Linq2Nhibernate donde su código C # se ejecuta "mágicamente" como SQL en lugar de como código C #.
Esa fue la respuesta larga a la primera parte de su pregunta ... ahora ...
El mayor obstáculo que enfrenté fue tratar de encontrar la línea entre el uso de soluciones funcionales y las soluciones imperativas. Sin embargo, después de probar ambos enfoques varias veces, comienza a tener una idea de cuál funcionará mejor.
Si está familiarizado con .NET, le recomiendo F #. Por otro lado, si está más familiarizado con la JVM, siempre hay Clojure . Si eres más académico que práctico, entonces iría con Common Lisp o Scheme. Si ya conoces Python, creo que hay muchas construcciones funcionales ya disponibles allí.
fuente
Esto es cierto si cuenta los programas desarrollados por programadores profesionales (o al menos las personas que se ven a sí mismas como tales). Si extiende su red más ampliamente para incluir programas desarrollados por personas que no se consideran como tales, FP (o al menos programar en un estilo funcional) está bastante cerca de OO (Excel, Mathematica, Matlab, R ... incluso JavaScript 'moderno' )
Mi opinión personal es que el multinúcleo no es la característica principal de FP (al menos hasta que los compiladores Haskell, Scala, Clojure, F # resuelvan el problema de la localidad de caché). La función única es
map
,filter
,fold
y amigos que permiten una expresión más sucinta de un gran grupo de algoritmos. Esto se ve agravado por los lenguajes FP que tienen una sintaxis más concisa que las contrapartes OO más populares.Además, el hecho de que FP esté más cerca del modelo relacional reduce la falta de coincidencia de impedancia con RDBMS ... que es, de nuevo al menos para los no programadores, muy agradable.
Además, cuando tiene requisitos de "corrección" particularmente difíciles de satisfacer, en una forma que es difícil de probar (común en computación científica / análisis de datos grandes donde el objetivo es obtener resultados previamente desconocidos y, como tales, no especificables) FP puede ofrecer ventajas
¿Cuántos de sus problemas se pueden resolver al salir de bibliotecas / marcos en qué plataforma (por ejemplo, JVM o .Net) cuántos son nuevos? ¿Existen construcciones de lenguaje capaces de expresar estos problemas directamente?
¿Cuánto control de bajo nivel necesita sobre el rendimiento de espacio y tiempo de su aplicación?
¿Cuán estrictos son sus requisitos de "corrección"?
¿Puede permitirse capacitar a los desarrolladores y / o competir con los beneficios que ofrecen algunos nichos altamente rentables en el desarrollo de software?
fuente
Asumiendo que eres un desarrollador de C ++ / C # / Java en la industria ...
Prepárate para compañeros gruñones que no quieren aprender nada. Prepárate para los jefes de pelo puntiagudo que imponen malas elecciones de idioma "porque alguna vez fueron codificadores". Prepárese para académicos concisos en foros que lo patrocinan sobre monoides. Prepárese para guerras interminables de idiomas porque Scala ni siquiera tiene eliminación de llamadas de cola y Clojure realmente requiere pedales para todos los soportes y no me ayude a comenzar con Erlang.
Si eres un programador web, entonces la mayor dificultad probablemente será tu cabello.
Comenzaría con la plataforma:
fuente
Para una perspectiva (ciertamente sesgada) sobre esta pregunta, puede consultar el blog de Bob Harper, Tipo existencial . Carnegie Mellon ha reelaborado recientemente su plan de estudios de CS para enseñar primero la programación funcional, con otros paradigmas enseñados solo una vez que se ha establecido una base sólida en la programación funcional, y Harper está dando un golpe a golpe a medida que el nuevo plan de estudios se implementa en la práctica .
Harper es uno de los principales desarrolladores del lenguaje de programación Standard ML, por lo que es justo decir que su propia opinión sobre el asunto se puede adivinar de antemano, y ciertamente no se asusta de las declaraciones controvertidas al argumentar por esta posición, pero hace Su caso bien.
fuente
var
ni ninguna colección mutable una sola vez. Entonces, el pensamiento imperativo es IMO algún tipo de optimización prematura que, como todos sabemos, es la raíz de todo mal.No existe una fórmula mágica que le indique cuándo utilizar la programación funcional. No es que la programación orientada a objetos se adapte mejor a nuestras situaciones de programación actuales. Es solo otra forma de estructurar programas en términos de otro conjunto de abstracciones.
La programación funcional no tiene nada que ver con la pereza. ML y OCaml son lenguajes funcionales y estrictos. El mayor obstáculo que enfrentará es estructurar las cosas en términos de valores inmutables y comprender la abstracción que se use en el sistema de tipos para los efectos secundarios. Los lenguajes funcionales son más adecuados para la optimización debido al hecho de que hacen que los efectos secundarios sean muy explícitos en el sistema de tipos. Haskell usa mónadas, pero hay otros enfoques para usar efectos en lenguajes funcionales puros. Clean tiene tipos únicos y algunos otros lenguajes en desarrollo tienen otras cosas.
Entre los lenguajes de programación que conozco, diría que solo Haskell y Clean pueden llamarse lenguajes funcionales. Todos los demás permiten efectos secundarios sin hacer que esos efectos sean explícitos en el sistema de tipos. Entonces, si va a dedicar tiempo a aprender programación funcional, entonces Haskell es probablemente el único que se ajusta a la ley. Todos los otros que conozco, Erlang, Scala, Clojure, etc., solo proporcionan abstracciones funcionales además de un lenguaje imperativo. Entonces, si desea abordar el paradigma funcional en bits, le recomendaría Scala o Erlang y si desea abordar todo de una vez y posiblemente renunciar a la frustración, entonces debería ir con Haskell.
fuente
Atribuiría el aumento actual de interés en lenguajes funcionales al hecho de que son ideales para la computación paralela. Por ejemplo, toda la idea de map-reduce se basa en el paradigma funcional. Y no hay duda de que la computación paralela irá en aumento, ya que está claro que el escalamiento actual es mucho más fácil y económico que el escalamiento. Incluso en el mercado de consumo, las CPU obtienen más núcleos, no más GHz.
EDITAR: ya que no es obvio para todos.
En la programación funcional pura, una función toma entrada, produce salida y no tiene efectos secundarios. Al no tener efectos secundarios, significa que no tiene un estado compartido, por lo tanto, no necesita mecanismos de sincronización, que de lo contrario serían necesarios mientras se ejecuta simultáneamente. La sincronización es la parte más difícil de cualquier software concurrente / paralelo, por lo que es puramente funcional, básicamente no tiene que lidiar con la parte más difícil.
En cuanto a map-reduce, incluso el nombre proviene de la programación funcional (tanto el mapeo como la reducción son operaciones típicas en el paradigma funcional). Ambos pasos de map-reduce son funciones, que se ejecutan en paralelo, toman entrada, producen salida y no tienen efectos secundarios. Así que esta es exactamente la idea de programación funcional pura.
Pocos ejemplos de FP utilizados para el paralelismo:
fuente