¿Cuándo utilizar un lenguaje de programación funcional?

90

¿En qué situaciones debería elegir usar un lenguaje de programación funcional en lugar de un lenguaje orientado a objetos más detallado como C ++, C # o Java?

Entiendo qué es la programación funcional, lo que realmente no entiendo es para qué tipo de problemas ¿es una solución perfecta?

Alex Baranosky
fuente
Esta pregunta se responde aquí stackoverflow.com/questions/381685/…
krosenvold
2
Siempre. O al menos nunca nunca.
Shelby Moore III
1
Con lambdas, C # es funcional al límite.
JD

Respuestas:

50

Los lenguajes funcionales son, en mi opinión, buenos principalmente para dos cosas: IA de juegos y cálculos matemáticos. Es bueno en la IA de juegos debido a sus agradables manipulaciones de listas (al menos en Lisp y Scheme), y para cálculos matemáticos debido a su sintaxis. Scheme, Lisp y Haskell tienen una sintaxis que hace que los cálculos matemáticos sean fáciles de leer. Lo último que tengo que añadir es que los lenguajes funcionales son lenguajes realmente divertidos. Mi curso de Scheme fue uno de los cursos con los que más me divertí.

martiert
fuente
2
Después de superar el hecho de que mi cerebro quería explotar en mi primera semana de la clase de compilación que tomé en Scheme, también encontré que era muy divertido (y
mejoré
1
¿Qué lenguajes funcionales ha utilizado para cálculos matemáticos?
Jules
8
¡Además, compiladores! He oído a personas que han escrito compiladores en Haskell decir que "nunca volverán a escribir un compilador en un lenguaje imperativo".
ShreevatsaR
1
julesjacobs: He usado un poco de haskell y Scheme para resolver cálculos matemáticos simples. No soy nada bueno en esos idiomas, así que tengo mucho camino por recorrer para resolver problemas más complejos. No puedo hacerlos lo suficientemente rápido por ahora.
martiert
95

Yo mismo investigué un poco sobre esto y pensé que podría agregar CONCURRENCIA a la lista de razones para usar un lenguaje funcional. Verá que en algún momento en el futuro cercano la velocidad del procesador no podrá aumentar usando la misma tecnología de cpu. La física de la arquitectura no lo permitirá.

Ahí es donde entra el procesamiento concurrente.

Lamentablemente, la mayoría de los lenguajes de programación orientada a objetos no pueden aprovechar varios procesadores a la vez debido a las interdependencias entre los datos.

En los lenguajes de programación puramente funcionales, la computadora puede ejecutar dos (o muchas más) funciones a la vez porque esas funciones no alteran la información de estado externa.

Aquí hay un excelente artículo sobre programación funcional que puede disfrutar.

Alex Baranosky
fuente
38
No diría que la mayoría de los lenguajes OO no pueden aprovechar una cantidad arbitrariamente grande de procesadores. Yo diría que para que un programa aproveche muchos procesadores al mismo tiempo de una manera eficiente y confiable, ese programa debe estar organizado de tal manera que la mayoría de las unidades de código intensivas en computación se comporten como funciones puras. Es posible organizar un programa de esa manera en la mayoría de los idiomas. Es más fácil de hacer en lenguajes funcionales que en lenguajes imperativos (incluidos los orientados a objetos).
Zak
2
Gracias por vincular ese artículo. Realmente me ayudó a explicar las cosas.
guptron
13

Un amigo mío citó a uno de sus profesores universitarios diciendo algo como lo siguiente:

Dibuje una cuadrícula con tipos de datos en la parte superior y operaciones en esos tipos de datos en el lado izquierdo. Si corta la cuadrícula verticalmente, está haciendo OO; si corta la cuadrícula horizontalmente, está haciendo FP.

Mi respuesta es que FP es un enfoque completamente viable para la programación con una gama de aplicaciones tan amplia como OO. Al igual que con cualquier discusión sobre la elección del lenguaje de programación, creo que las preguntas más importantes son:

  1. ¿Tiene tiempo para invertir en aprender una nueva notación y una nueva forma de pensar?
  2. ¿Cuál de los lenguajes que está considerando tiene bibliotecas lo suficientemente ricas como para no quedarse atascado reinventando alguna rueda?

En cuanto a la primera pregunta, si está haciendo esto principalmente por el valor de aprendizaje, le sugiero que consulte a Haskell , debido a la amplia gama de materiales de apoyo (libros, artículos, comunidad activa, etc.)

En cuanto a la segunda pregunta, Haskell tiene una buena gama de bibliotecas (aunque algunas son más maduras que otras), pero Scala (un lenguaje funcional híbrido OO que se ejecuta en la JVM) tiene las ventajas de que puede realizar una transición más gradual al estilo funcional. y dispone de la gama completa de bibliotecas accesibles a Java.

joel.neely
fuente
Aprendí Scheme en la universidad, así que no quiero aprender programación funcional solo por la experiencia. Prefiero aprender un lenguaje funcional por razones prácticas.
Alex Baranosky
9

Prácticamente todo lo que puedes hacer en PP se puede hacer en FP, y lo mismo a la inversa. Es simplemente otra forma de codificar algo: otra perspectiva del problema y una forma diferente de resolverlo.

Sin embargo, debido a que no mucha gente usa FP, el problema es más sobre la falta de buenas bibliotecas, portabilidad / mantenibilidad (ya que el mantenedor tiene más posibilidades de entender algo escrito en C ++ que Scheme) y la falta de documentación y comunidad. Sé que HAY algunos documentos, sin embargo, compárelo con C ++, C # o Java y comprenderá lo que quiero decir.

Sin embargo, si realmente desea hacer FP, puede usar este estilo incluso en C ++ y C #. Por supuesto, no será un 100% FP si usa la biblioteca estándar. Desafortunadamente, no creo que C # esté optimizado para usarse con programación funcional y probablemente creará muchos problemas de rendimiento.

Esta es una publicación más subjetiva, lo que pienso sobre FP. No es una declaración rigurosa.

user35978
fuente
8
"Prácticamente todo lo que se puede hacer en PP se puede hacer en FP" - En realidad, es exactamente todo.
BlueRaja - Danny Pflughoeft
2
@BlueRaja: ¿te refieres a Turing Completeness? Si es así, lo que dices no sigue. Por ejemplo, Game of Life de Conway es Turing Complete, pero no puede usarlo para escribir un controlador de tarjeta de video como puede hacerlo en C. Del mismo modo, no veo ninguno de los últimos juegos escritos en Haskell. ¡Puede hacerlo en FP! = Teóricamente podría hacerlo en un FP teórico.
Luigi Plinge
@Luigi Plinge Tendría que estar de acuerdo con BlueRaja. Haskellers discutiendo algunos controladores de Linux escritos en Haskell. No tengo un enlace, pero también escuché que se ha escrito un sistema operativo en Haskell (posiblemente también en otros lenguajes funcionales). En cuanto a los juegos, no veo que los últimos juegos se escriban en C # o Java, ¿estás insinuando que no se pueden usar para eso? De todos modos, un ejemplo de un juego que se escribe en FP. Además, tenga en cuenta que la mayoría de mis enlaces son Haskell, un lenguaje PURAMENTE funcional.
austinprete
@PardonMyRhetoric Obviamente, puedes escribir juegos en Haskell y hacer cualquier cálculo, pero la velocidad será varias veces más lenta y el uso de memoria mayor. Entonces, un contraejemplo de la declaración de BlueRaja sería que no puedes escribir "un juego que sea tan rápido y use tanta memoria en C" en FP. Este es un problema práctico real, no un truco pedante (y no quiero golpear FP en absoluto, ¡estoy codificando Scala ahora mismo!).
Luigi Plinge
1
@PardonMyRhetoric También debe ser FP idiomático. Los puntos de referencia que ve que dan a Haskell un rendimiento cercano al de C están escritos en un estilo unidiomático de "bajo nivel" que la mayoría de los programadores de Haskell no podrían escribir. Por ejemplo, podría lograr un rendimiento similar simplemente haciendo que su código Haskell genere la salida y compilando el código C. Aunque es inútil. Una cuestión práctica relacionada es qué "se puede hacer" frente a qué "se puede / se podría hacer". Si algo es demasiado difícil, no importa mucho si es posible en teoría (¿y "posible" para quién?).
Luigi Plinge
4

Los lenguajes funcionales son buenos en muchas situaciones. Depende de las bibliotecas de un lenguaje funcional particular.

¿Cómo respondería a la pregunta "Cuándo utilizar un lenguaje de programación orientado a objetos"?

Jules
fuente
1
"¿Cuándo utilizar un lenguaje de programación orientado a objetos?" Cuando quieres modelar computacionalmente cualquier cosa, por otro lado he estado buscando un problema de que fp sería la respuesta intuitiva, sigo buscando, así es como encontré esta publicación.
jimjim
@Arjang supongo que la programación funcional encontraría un gran uso en aplicaciones de cálculo que solo necesitan entrada para generar salida. Sin mutabilidad y sin iteración
EdgeDev
3

Aunque esta es una pregunta bastante subjetiva, me gustaría agregar que los lenguajes funcionales se usan mucho para analizar lenguajes específicos de dominio ; la naturaleza funcional se presta bien para analizar gramáticas.

csl
fuente
2
¿Analizando DSL? Pensé que con las macros Lisp y similares, los DSL se implementan como macros, no algo que los programas Lisp puedan analizar. YMMV con lenguajes que no son Lisp. :-P
Chris Jester-Young
1

Por lo que he visto, es más una cuestión de gusto que de funcionalidad (sin juego de palabras). Realmente no hay nada en ninguno de los estilos de lenguaje que lo haga inherentemente mejor o peor en tareas específicas.

TED
fuente
2
@JonHarrop - ¿Te importaría profundizar en eso? No lo encuentro tan obvio, y sería una pena si dejaras la impresión de que estás votando a la gente por mero refuerzo.
TED
1
La familia de lenguajes ML se creó específicamente para la metaprogramación con la adición de características de lenguaje sofisticadas como la coincidencia de patrones para manipular árboles (por ejemplo, árboles de expresión). En consecuencia, esta familia de idiomas es inherentemente mucho mejor en esa tarea específica.
JD
1
@JonHarrop - Lo aceptaré. Sin embargo, estás hablando de ML, no de lenguajes funcionales en general. Soy un gran creyente en DSL, por lo que ciertamente no discutiré en contra del uso de un lenguaje en particular para la tarea exacta para la que fue diseñado.
TED
Hoy en día, la coincidencia de patrones se encuentra en casi todos los lenguajes funcionales, incluidos OCaml, F #, Scala, Haskell, Clojure y Erlang. Por ejemplo, recientemente construí un motor de reglas de negocios a medida para un cliente con un enfoque en matemáticas. Eso es 1,000 líneas de F # y es predominantemente un intérprete. La lectura, el análisis, la verificación de tipos y la interpretación de entradas son mucho más fáciles gracias a la coincidencia de patrones.
JD
@JonHarrop ... pero no todos. No es una característica inherente de los lenguajes funcionales, que es sobre lo que se estaba preguntando.
TED
1

En general, use el lenguaje en el que sea más fácil expresar la solución a un problema. Para la programación funcional, esto es cuando la solución a un problema se expresa fácilmente en términos de funciones , de ahí el nombre. Generalmente es bueno para operaciones matemáticas, IA, coincidencia de patrones; en general, cualquier cosa que se pueda dividir en un conjunto de reglas que se deben aplicar para obtener una respuesta. Solo puede determinar realmente el "mejor" lenguaje a utilizar después de haber analizado suficientemente su problema. Aquí es donde el pseudocódigo resulta útil. Si se encuentra escribiendo un pseudocódigo que se parece a FP, utilice FP.

Por supuesto, todos los lenguajes de programación completos son funcionalmente equivalentes, por lo que realmente no importa cuál elija en términos de los problemas que pueda resolver. Los principales efectos serán en términos de eficiencia y precisión de codificación y facilidad de mantenimiento.

Tenga en cuenta también que es posible imitar FP dentro de los lenguajes OO a través de API inteligentemente diseñadas. Por ejemplo, he visto numerosas bibliotecas de Java (JMock es un ejemplo) que usan el encadenamiento de métodos para simular un FP DSL. Luego verá construcciones como:

logger.expects(once()).method("error") .with( and(stringContains(action),stringContains(cause)) );

Básicamente, esto crea una función que se evalúa para determinar si alguna secuencia de llamada en un objeto simulado es correcta. (ejemplo robado de http://www.jmock.org/yoga.html )

Otra sintaxis similar a FP en lenguajes OO es el uso de cierres, como en Ruby.

Phil
fuente
2
"... realmente no importa cuál elijas en términos de qué problemas puedes resolver". Solo si tiene tiempo y dinero infinitos para resolver su problema.
JD