Programación funcional vs programación orientada a objetos [cerrado]

784

Hasta ahora he estado expuesto principalmente a la programación OO y espero aprender un lenguaje funcional. Mis preguntas son:

  • ¿Cuándo elige la programación funcional en lugar de orientada a objetos?
  • ¿Cuáles son las definiciones típicas de problemas donde la programación funcional es una mejor opción?
Olivier Lalonde
fuente
esto es relevante programmers.stackexchange.com/questions/9730/…
kirill_igum
1
pregunta similar cs.se también cerró cuál es el ejemplo donde la programación funcional da mejores resultados que el estilo imperativo . La sabiduría convencional parece ser que uno no es superior al otro, o que no son comparables en criterios simples, o que se usan para diferentes propósitos ... la programación funcional tiene más orígenes y usos científicos / académicos y es menos común en la industria , por lo que la pregunta también establece un punto de vista / conflicto irresoluble "industria vs academia". un clásico que muestra el estilo de OOP en la programación funcional, libro SICP / MIT
vzn
" OO hace que el código sea comprensible encapsulando las partes móviles. FP hace que el código sea comprensible al minimizar las partes móviles " .Micheal Feathers, 2010
jaco0646

Respuestas:

1193

¿Cuándo elige la programación funcional en lugar de orientada a objetos?

Cuando anticipa un tipo diferente de evolución del software:

  • Los lenguajes orientados a objetos son buenos cuando tiene un conjunto fijo de operaciones sobre cosas y, a medida que su código evoluciona, agrega principalmente cosas nuevas. Esto se puede lograr agregando nuevas clases que implementen métodos existentes, y las clases existentes se dejan solas.

  • Los lenguajes funcionales son buenos cuando tiene un conjunto fijo de cosas y, a medida que su código evoluciona, agrega principalmente nuevas operaciones en cosas existentes. Esto se puede lograr agregando nuevas funciones que computan con los tipos de datos existentes, y las funciones existentes se dejan solas.

Cuando la evolución va por el camino equivocado, tienes problemas:

  • Agregar una nueva operación a un programa orientado a objetos puede requerir editar muchas definiciones de clase para agregar un nuevo método.

  • Agregar un nuevo tipo de cosas a un programa funcional puede requerir editar muchas definiciones de funciones para agregar un nuevo caso.

Este problema se conoce desde hace muchos años; en 1998, Phil Wadler lo denominó el "problema de expresión" . Aunque algunos investigadores piensan que el problema de la expresión puede abordarse con características del lenguaje como los mixins, una solución ampliamente aceptada aún no ha llegado a la corriente principal.

¿Cuáles son las definiciones típicas de problemas donde la programación funcional es una mejor opción?

Los lenguajes funcionales sobresalen en la manipulación de datos simbólicos en forma de árbol. Un ejemplo favorito son los compiladores, donde los lenguajes de origen e intermedios cambian raramente (principalmente las mismas cosas ), pero los escritores de compiladores siempre agregan nuevas traducciones y mejoras u optimizaciones de código (nuevas operaciones en las cosas). La compilación y la traducción en general son "aplicaciones geniales" para lenguajes funcionales.

Norman Ramsey
fuente
119
Hay un zen serio detrás de esta respuesta. Creo que ilumina el hecho de que ciertos patrones de diseño de OOP (Visitor) son en realidad hacks que intentan superar el problema de agregar nuevas operaciones.
Soluciones de datos Jacobs
54
En JavaScript, puedes tener todas las cosas.
Erik Reppen
61
@ErikReppen en qué momento surge la pregunta, ¿cuándo elige usar las funciones funcionales y cuándo elige usar las funciones orientadas a objetos?
Norman Ramsey el
77
@NormanRamsey No es raro mezclarlo en JS y las funciones de primera clase están vinculadas a muchas características relacionadas con JS OOP. La ordenación de matrices de JS toma funciones como un argumento que puede producir algunas estructuras de datos poderosas. Closures + una función aprobada se utiliza para mantener los objetos jquery con una memoria muy ligera, ya que la mayoría de los métodos son solo referencias. Etc ...
Erik Reppen
99
@ NormanRamsey: Muy buena respuesta, en la línea de SICP. Según esta clasificación, la programación funcional y de procedimiento se agrupa en el lado opuesto de la programación orientada a objetos. Esto podría explicar el auge de OOP a fines de la década de 1980 y principios de la década de 1990: cuando las GUI se convirtieron en la OOP convencional, resultó ser un buen enfoque para modelarlas porque normalmente tiene un conjunto fijo de operaciones (pintar, abrir, cerrar, cambiar el tamaño) y un número creciente de widgets. Por supuesto, esto no significa que OOP sea mejor que el procedimiento para cualquier aplicación, como lo ilustraste.
Giorgio
177

No necesariamente tiene que elegir entre los dos paradigmas. Puede escribir software con una arquitectura OO utilizando muchos conceptos funcionales. FP y OOP son de naturaleza ortogonal .

Tomemos por ejemplo C #. Se podría decir que es principalmente OOP, pero hay muchos conceptos y construcciones de FP. Si considera Linq , las construcciones más importantes que permiten que Linq exista son de naturaleza funcional: expresiones lambda .

Otro ejemplo, F #. Se podría decir que es principalmente FP, pero hay muchos conceptos y construcciones de OOP disponibles. Puede definir clases, clases abstractas, interfaces, lidiar con la herencia. Incluso puede usar la mutabilidad cuando aclara su código o cuando aumenta drásticamente el rendimiento.

Muchos lenguajes modernos son multi-paradigmáticos.

Lecturas recomendadas

Como estoy en el mismo barco (antecedentes de OOP, aprendiendo FP), te sugiero algunas lecturas que realmente aprecio:

Bruno Reis
fuente
8
@duffymo: tu comentario, la forma en que lo expresas, no tiene sentido. Nadie quiere una comparación de idiomas, máquinas virtuales o plataformas, gracias.
Bruno Reis
66
@Bruno: una respuesta al "poder de .NET". Relajarse.
duffymo
66
Es curioso, no te veo reprendiendo a Dykam por su inútil comentario. ¿Fuiste nominado como moderador mientras yo no estaba buscando? Aquí nadie está en llamas excepto tú. Lo diré de nuevo, relájate.
duffymo
44
Je, perdón si empecé a flamear. No quise decir que otras plataformas son menos potentes, solo que .NET no solo admite OOP. Por ejemplo, tiene optimización de llamada de cola.
Dykam
55
@nawfal, hasta que pueda señalar algunas características intrínsecas en los dos paradigmas y decir que son incompatibles, son ortogonales: ese es el corazón de la discusión. FP es incompatible con la programación imperativa por definición, pero OOP no se limita a la programación imperativa. La razón por la que tenemos diferentes palabras para estos conceptos es para que podamos hablar sobre ellos: cuando los agrupas, simplemente nos obligas a encontrar nuevas palabras innecesariamente.
DavidS
31

La programación orientada a objetos ofrece:

  1. Encapsulación, a
    • controlar la mutación del estado interno
    • limitar el acoplamiento a la representación interna
  2. Subtipado, permitiendo:
    • sustitución de tipos compatibles (polimorfismo)
    • Un medio crudo de compartir la implementación entre clases (herencia de implementación)

La programación funcional, en Haskell o incluso en Scala, puede permitir la sustitución a través de un mecanismo más general de clases de tipos. El estado interno mutable está desalentado o prohibido. La encapsulación de la representación interna también se puede lograr. Ver Haskell vs OOP para una buena comparación.

La afirmación de Norman de que "agregar un nuevo tipo de cosas a un programa funcional puede requerir editar muchas definiciones de funciones para agregar un nuevo caso". depende de qué tan bien el código funcional ha empleado clases de tipos. Si la coincidencia de patrones en un tipo de datos abstractos en particular se extiende a través de una base de código, de hecho sufrirá este problema, pero quizás sea un mal diseño para comenzar.

EDITADO Se eliminó la referencia a las conversiones implícitas al analizar las clases de tipos. En Scala, las clases de tipos están codificadas con parámetros implícitos, no conversiones, aunque las conversiones implícitas son otro medio para lograr la sustitución de tipos compatibles.

retronym
fuente
3
Las clases de tipos no son un mecanismo para la conversión implícita a otros tipos. Son una descripción de un conjunto de funciones definidas para un tipo a fin de proporcionar una forma de polimorfismo. Lo más parecido al OOP de estilo Java serían las interfaces, aunque las clases de tipos de Haskell tienen algunas diferencias importantes.
Zak
25
  1. Si se encuentra en un entorno muy concurrente, entonces la programación funcional pura es útil. La falta de estado mutable hace que la concurrencia sea casi trivial. Ver Erlang

  2. En un lenguaje multiparadigm, es posible que desee modelar algunas cosas funcionalmente si la existencia de un estado mutable es un detalle de implementación y, por lo tanto, FP es un buen modelo para el dominio del problema. Por ejemplo, vea la lista de comprensiones en Python o std.range en el lenguaje de programación D. Estos están inspirados en la programación funcional.

dsimcha
fuente