ventajas programacion paradigmas orientada objetos imperativa funcional ejemplos desventajas functional-programming

functional programming - programacion - ¿Por qué la programación funcional no se ha hecho cargo todavía?



programacion funcional vs orientada a objetos (11)

He leído algunos textos sobre programación declarativa / funcional (lenguajes), probé Haskell y escribí uno mismo. Por lo que he visto, la programación funcional tiene varias ventajas sobre el estilo imperativo clásico:

  • Programas sin estado; Sin efectos secundarios
  • Concurrencia Juega extremadamente bien con la creciente tecnología multi-core
  • Los programas suelen ser más cortos y, en algunos casos, más fáciles de leer.
  • La productividad sube (ejemplo: Erlang)

  • La programación imperativa es un paradigma muy antiguo (que yo sepa) y posiblemente no sea adecuada para el siglo XXI.

¿Por qué las empresas que usan o los programas escritos en lenguajes funcionales siguen siendo tan "raros"?

¿Por qué, al observar las ventajas de la programación funcional, seguimos utilizando lenguajes de programación imperativos?

Tal vez fue demasiado pronto para eso en 1990, pero hoy en día?


¿Por qué la programación funcional no se ha hecho cargo todavía?

Funcional es mejor para algunas cosas y peor para otras, por lo que nunca "se hará cargo". Aunque ya es ubicuo en el mundo real.

Programas sin estado; Sin efectos secundarios

Los programas sin estado son más fáciles de probar. Esto ahora es ampliamente apreciado y a menudo explotado en la industria.

Concurrencia Reproducciones extremadamente agradables con la creciente tecnología de múltiples núcleos Los programas son generalmente más cortos y, en algunos casos, más fáciles de leer La productividad aumenta (ejemplo: Erlang)

Estás combinando concurrencia y paralelismo.

La concurrencia se puede hacer de manera efectiva utilizando procesos secuenciales de comunicación (CSP). El código dentro de un CSP puede mutar su estado local, pero los mensajes enviados entre ellos siempre deben ser inmutables.

La programación puramente funcional juega extremadamente mal con el multinúcleo porque es muy poco amigable con el caché. Los núcleos compiten por la memoria compartida y los programas paralelos no se escalan.

¿Por qué las empresas que usan o los programas escritos en lenguajes funcionales siguen siendo tan "raros"?

Scala es a menudo considerado como un lenguaje funcional, pero no es más funcional que C #, que es uno de los idiomas más populares en el mundo hoy en día.

¿Por qué, al observar las ventajas de la programación funcional, seguimos utilizando lenguajes de programación imperativos?

La programación puramente funcional tiene muchas desventajas serias, por lo que usamos lenguajes funcionales impuros como Lisp, Scheme, SML, OCaml, Scala y C #.


¿No es así?

Smalltalk fue un gran sistema orientado a objetos en el pasado. ¿Por qué no se ha hecho cargo la programación orientada a objetos? Bueno, lo ha hecho. Simplemente no se parece a Smalltalk. Los lenguajes comunes siguen haciéndose más pequeños como Smalltalk con C ++, Java, C #, etc. La moda y el estilo cambian más lentamente que cualquier otro, por lo que cuando OO se convirtió en el mainstream, lo conseguimos pegando partes de OO a los lenguajes antiguos, por lo que se parecía bastante a C para tragar .

Funcional es de la misma manera. Haskell fue un gran lenguaje funcional. Pero tenemos aún más masa de programadores convencionales que utilizan la sintaxis tipo C hoy en día que hace 20 años. Así que tiene que parecerse a C. Hecho: mire cualquier expresión de LINQ y dígame que no es funcional.


A pesar de las ventajas de la programación funcional, la programación imperativa y orientada a objetos nunca desaparecerá por completo.

La programación imperativa y orientada a objetos es una descripción paso a paso del problema y su solución. Como tal, puede ser más fácil de comprender. La programación funcional puede ser un poco oscura.

En última instancia, un programa útil siempre tendrá efectos secundarios (como proporcionar una salida real al usuario para el consumo), por lo que los lenguajes funcionales más puros todavía necesitarán una forma de ingresar al mundo imperativo de vez en cuando.

El estado actual de la técnica es que los lenguajes imperativos (como C #) toman prestadas características del mundo funcional (como las declaraciones lambda) y viceversa.


Creo que los lenguajes imperativos son más frecuentes simplemente porque eso es a lo que más personas están acostumbradas. Ni la programación funcional ni el modelo de programación imperativo son más oscuros o académicos que el otro. De hecho, son complementos.

Un cartel decía que el código imperativo es más fácil de entender que el código de programación funcional. Esto solo es cierto si el lector ya ha visto un código imperativo, especialmente si los ejemplos anteriores son parte de la misma "familia" (por ejemplo, C / C ++, Perl, PHP y Java). No diría que es cierto para cualquier lenguaje imperativo; tome una comparación de Java y Forth, para hacer un ejemplo extremo.

Para un laico, todos los lenguajes de programación son incomprensibles, excepto tal vez los lenguajes verbales como Hypertalk y SQL. (Cabe destacar que SQL es un lenguaje declarativo y / o funcional y goza de una enorme popularidad).

Si nos hubiéramos entrenado inicialmente en un lenguaje Lisp-y o Haskell-y desde el principio, todos pensaríamos que los lenguajes de programación funcionales son perfectamente normales.


Cuando pienso en lo que la programación funcional podría aportar a mis proyectos en el trabajo, siempre me guío por el mismo camino del pensamiento:

  1. Para obtener todas las ventajas de la programación funcional, necesita la pereza. Sí, hay lenguajes funcionales estrictos, pero los beneficios reales de la programación funcional no brillan tan bien en un código estricto. Por ejemplo, en Haskell es fácil crear una secuencia de operaciones perezosas en una lista y concatenarlas y aplicarlas a una lista. P.ej. op1 $ op2 $ op3 $ op4 $ someList . Sé que no se va a construir la lista completa e internamente solo voy a obtener un buen ciclo que recorre los elementos uno a la vez. Esto te permite escribir código realmente modular. La interfaz entre dos módulos puede implicar la entrega de estructuras de datos potencialmente vastas y, sin embargo, no es necesario que tenga la estructura residente.

  2. Pero cuando tienes pereza, se vuelve difícil razonar sobre el uso de la memoria. Cambiar los indicadores del compilador de Haskell con frecuencia cambia la cantidad de memoria utilizada por un algoritmo de O (N) a O (1), excepto que algunas veces no lo hace. Esto no es realmente aceptable cuando tiene aplicaciones que necesitan aprovechar al máximo toda la memoria disponible, y no es ideal incluso para aplicaciones que no necesitan toda la memoria.


Dos cosas:

  1. Solo lleva tiempo, no importa lo buena que sea una tecnología. Las ideas detrás de FP tienen unos 70 años. Pero su uso principal en Ingeniería de Software (en las trincheras, en la industria) es probablemente de menos de 10 años. Pedirle a los desarrolladores que adopten una mentalidad racialmente nueva es posible pero solo toma tiempo (muchos, muchos años). Por ejemplo, la programación orientada a objetos realmente obtuvo un uso general a principios de los años ochenta. Sin embargo, no ganó la latencia hasta finales de los años noventa.
  2. Necesitas que las personas se vean obligadas a enfrentar la fuerza de una tecnología antes de que llegue a lo grande . Actualmente, las personas están utilizando herramientas que no hacen uso del paralelismo y las cosas funcionan bien. Cuando las aplicaciones que no usan el paralelismo se vuelven insoportablemente lentas; entonces muchas personas se verán obligadas a usar herramientas de paralelismo y la FP puede aumentar en popularidad. Esto también puede aplicarse a otras fortalezas de FP.

La respuesta de la acción es que ni reemplazará ni reemplazará a la otra, son herramientas diferentes que tienen diferentes ventajas y desventajas, y qué enfoque tiene la ventaja diferirá según el proyecto y otras cuestiones "blandas" como el grupo de talentos disponible.

Creo que tienes razón en que el crecimiento de la concurrencia debido a los núcleos múltiples aumentará el porcentaje (del conjunto global de proyectos de desarrollo) cuando la programación funcional se elija sobre otros estilos.

Creo que es raro hoy en día porque la mayoría del grupo de talentos profesionales de hoy en día se siente más cómodo con las tecnologías imperativas y orientadas a objetos. Por ejemplo, más de una vez elegí Java como el lenguaje para un proyecto comercial porque era lo suficientemente bueno, no controversial, y sé que nunca me quedaré sin gente que pueda programar (lo suficientemente bien) en él.


Porque todas esas ventajas también son desventajas.

Programas sin estado; Sin efectos secundarios

Los programas del mundo real son todos sobre los efectos secundarios y la mutación. Cuando el usuario presiona un botón es porque quiere que algo suceda. Cuando escriben algo, quieren que ese estado reemplace cualquier estado que haya estado allí. Cuando Jane Smith en contabilidad se casa y cambia su nombre a Jane Jones, la base de datos que respalda el proceso de negocios que imprime su cheque de pago debería ser todo sobre el manejo de ese tipo de mutación. Cuando disparas la ametralladora al alienígena, la mayoría de las personas no modelan mentalmente eso como la construcción de un nuevo alienígena con menos puntos de golpe; modelan eso como una mutación de las propiedades de un extraterrestre existente.

Cuando los conceptos del lenguaje de programación funcionan fundamentalmente contra el dominio que se está modelando, es difícil justificar el uso de ese lenguaje.

Concurrencia Juega extremadamente bien con la creciente tecnología multi-core

El problema es simplemente empujado alrededor. Con estructuras de datos inmutables, tiene una seguridad de subprocesos barata a costa de posiblemente trabajar con datos obsoletos. Con las estructuras de datos mutables, tiene la ventaja de trabajar siempre con datos nuevos al costo de tener que escribir una lógica complicada para mantener los datos consistentes. No es que uno de esos sea obviamente mejor que el otro.

Los programas suelen ser más cortos y, en algunos casos, más fáciles de leer.

Excepto en los casos en que son más largos y más difíciles de leer. Aprender a leer programas escritos en un estilo funcional es una habilidad difícil; Las personas parecen ser mucho mejores para concebir los programas como una serie de pasos a seguir, como una receta, en lugar de como una serie de cálculos a realizar.

La productividad sube (ejemplo: Erlang)

La productividad tiene que aumentar mucho para justificar el gasto masivo de contratar programadores que saben cómo programar en un estilo funcional.

Y recuerda, no quieres tirar un sistema de trabajo; la mayoría de los programadores no están creando nuevos sistemas desde cero, sino que mantienen los sistemas existentes, la mayoría de los cuales se construyeron en lenguajes no funcionales. Imagínese tratando de justificar eso a los accionistas. ¿Por qué desechó su sistema de nómina laboral actual para construir uno nuevo a un costo de millones de dólares? "Debido a que la programación funcional es impresionante" es poco probable que deleite a los accionistas.

La programación imperativa es un paradigma muy antiguo (que yo sepa) y posiblemente no sea adecuado para el siglo XXI.

La programación funcional es muy antigua también. No veo cómo la edad del concepto es relevante.

No me malinterpretes Me encanta la programación funcional, me uní a este equipo porque quería ayudar a llevar los conceptos de la programación funcional a C #, y creo que la programación en un estilo inmutable es el camino del futuro. Pero hay costos enormes para la programación en un estilo funcional que no puede ser simplemente descartado. El cambio hacia un estilo más funcional sucederá lenta y gradualmente a lo largo de décadas. Y eso es lo que será: un cambio hacia un estilo más funcional, no un enfoque global de la pureza y la belleza de Haskell y el abandono de C ++.

Construyo compiladores para la vida y definitivamente estamos adoptando un estilo funcional para la próxima generación de herramientas de compilación. Esto se debe a que la programación funcional es fundamentalmente una buena combinación para el tipo de problemas que enfrentamos. Nuestros problemas consisten en captar información sin procesar (cadenas y metadatos) y transformarlos en diferentes cadenas y metadatos. En situaciones en las que se producen mutaciones, al igual que alguien está escribiendo en el IDE, el espacio del problema se presta a técnicas funcionales como la reconstrucción incremental de solo las partes del árbol que cambiaron. Muchos dominios no tienen estas bonitas propiedades que los hacen evidentemente susceptibles de un estilo funcional .


Ya tienes suficientes respuestas que mencionaré solo un par de cosas que aún no veo mencionadas.

En primer lugar y (en mi opinión), los lenguajes de procedimiento se han beneficiado enormemente de su grado de compatibilidad. Por ejemplo, casi cualquier persona que conozca casi cualquiera de los lenguajes de procedimiento (OO) de la corriente principal puede leer casi todos los demás razonablemente bien. Evito activamente trabajar en Java, C #, Cobol, Fortran o Basic (solo por algunos ejemplos) pero puedo leer cualquiera de ellos razonablemente bien, casi tan bien como las personas que los usan todos los días.

En el lado funcional, eso es mucho menos cierto. Por ejemplo, también puedo escribir Scheme bastante razonablemente, pero eso es de poca utilidad en la lectura de Ocaml o Haskell (solo para un par de ejemplos). Incluso dentro de una sola familia (por ejemplo, Scheme vs., Common Lisp), la familiaridad con una no parece traducirse tan bien como la otra.

La afirmación de que el código funcional es más legible tiende a ser cierta solo en un rango limitado de condiciones. Para las personas que están muy familiarizadas con el idioma, la legibilidad es realmente excelente, pero para todos los demás, a menudo es casi inexistente. Peor aún, si bien las diferencias en los lenguajes de procedimiento son en gran parte de sintaxis y, por lo tanto, se aprenden con relativa facilidad, las diferencias en los lenguajes funcionales a menudo son mucho más fundamentales, por lo que requieren un estudio considerable para comprender realmente (por ejemplo, saber que Lisp es de poca ayuda para entender las Mónadas).

El otro punto importante es que la idea de que los programas funcionales son más cortos que los procesales a menudo se basa más en la sintaxis que en la semántica. Los programas escritos en Haskell (por ejemplo, a menudo son bastante cortos, pero su funcionalidad es una parte bastante pequeña de eso). Mucho si es simplemente que Haskell tiene una sintaxis relativamente concisa.

Pocos lenguajes puramente funcionales pueden competir bien con APL por el código fuente terso (aunque, para ser justos, APL también admite la creación de funciones de nivel superior, por lo que no es una diferencia tan grande como en otros casos). Por el contrario, Ada y C ++ (solo para un par de ejemplos) pueden ser bastante competitivos en cuanto al número de operaciones necesarias para realizar una tarea determinada, pero la sintaxis es (al menos generalmente) sustancialmente más detallada.


Masterminds of Programming: Conversaciones con los creadores de los principales lenguajes de programación

[Haskell]

¿Por qué crees que ningún lenguaje de programación funcional ha entrado en la corriente principal?

John Hughes: ¡ Pobre marketing! No me refiero a la propaganda; hemos tenido mucho de eso Me refiero a una elección cuidadosa de un nicho de mercado objetivo para dominar, seguido de un esfuerzo decidido para hacer que la programación funcional sea, con mucho, la forma más efectiva de abordar ese nicho. En los días felices de los 80, pensamos que la programación funcional era buena para todo, pero llamar a la nueva tecnología "bueno para todo" es lo mismo que llamarlo "particularmente bueno para nada". ¿Qué se supone que es la marca? Este es un problema que John Launchbury describió muy claramente en su charla invitada en ICFP. Galois Connections estuvo a punto de caer cuando su marca era "software en lenguajes funcionales", pero se han ido fortaleciendo desde que se enfocaron en "software de alta seguridad".

Mucha gente no tiene idea de cómo se produce la innovación tecnológica y espera que una mejor tecnología simplemente se vuelva dominante por sí misma (el efecto "mejor trampa para ratones" ), pero el mundo no es así.


Ninguna necesidad percibida

Recuerdo la respuesta de mi antiguo jefe Rick Cline cuando le mostré una copia de la conferencia del Premio Turing de John Backus titulada ¿Puede la programación liberarse del estilo de von Neumann?

Su respuesta: "¡Tal vez algunos de nosotros no queremos ser liberados del estilo de von Neumann!"