programming languages functional example course books oop scala programming-languages functional-programming paradigms

languages - functional programming vs oop



¿FP y OO son ortogonales? (10)

He escuchado esto una y otra vez, y estoy tratando de comprender y validar la idea de que FP y OO son ortogonales.

En primer lugar, ¿qué significa que 2 conceptos sean ortogonales?

FP fomenta la inmutabilidad y la pureza tanto como sea posible, mientras que OO parece construido para el estado y la mutación: ¿una versión ligeramente organizada de la programación imperativa? Me doy cuenta de que los objetos pueden ser inmutables, pero OO parece implicar estado / cambio para mí.

Parecen opuestos. ¿Cómo afecta eso su ortogonalidad?

Un lenguaje como Scala hace que sea fácil hacer OO y FP, ¿esto afecta la ortogonalidad de los dos métodos?


En primer lugar, ¿qué significa que 2 conceptos sean ortogonales?

Significa que los dos conceptos no tienen ideas contrastantes o no son incompatibles entre sí.

FP fomenta la inmutabilidad y la pureza tanto como sea posible. y OO parece algo construido para el estado y la mutación (¿una versión ligeramente organizada de la programación imperativa?). Y me doy cuenta de que los objetos pueden ser inmutables. Pero OO parece implicar estado / cambio para mí.

Parecen opuestos. ¿Cómo afecta su ortogonalidad?

Un lenguaje como Scala hace que sea fácil hacer OO y FP, ¿afecta esto la ortogonalidad de los 2 métodos?

OO trata sobre la encapsulación, la composición de objetos, la abstracción de datos, el polimorfismo mediante subtipado y la mutación controlada cuando sea necesario (también se fomenta la inmutabilidad en OO). FP se trata de composición de funciones, abstracción de control y polimorfismo restringido (también conocido como polimorfismo paramétrico). Por lo tanto, las dos ideas no son contradictorias. Ambos te proporcionan diferentes tipos de poderes y mecanismos de abstracción, que sin duda es posible tener en un idioma. ¡De hecho, esta es la tesis sobre la cual se construyó Scala !

En su charla de Scala Experiment en Google, Martin Odersky explica muy bien cómo cree que los dos conceptos, OO y FP, son ortogonales entre sí y cómo Scala unifica los dos paradigmas de manera elegante y sin problemas en un nuevo paradigma popularmente conocido en la comunidad Scala como paradigma objeto-funcional. Debes verte hablar por ti. :-)

Otros ejemplos de lenguajes objeto-funcionales: OCaml , Source , Nemerle .


En primer lugar, ¿qué significa que 2 conceptos sean ortogonales?

Significa que no se afectan entre sí. Es decir, un lenguaje funcional no es menos funcional porque también está orientado a objetos.

Parecen opuestos. ¿Cómo afecta su ortogonalidad?

Si fueran opuestos (es decir, un lenguaje puramente funcional no podría estar orientado a objetos), por definición, no serían ortogonales. Sin embargo, no creo que este sea el caso.

y OO parece algo construido para el estado y la mutación (¿una versión ligeramente organizada de la programación imperativa?). Y me doy cuenta de que los objetos pueden ser inmutables. Pero OO parece implicar estado / cambio para mí.

Si bien esto es cierto para la mayoría de los lenguajes OO convencionales, no hay ninguna razón para que un idioma OO necesite tener un estado mutable.

Si un lenguaje tiene objetos, métodos, herencia virtual y polimorfismo ad-hoc, es un lenguaje orientado a objetos, ya sea que también tenga un estado mutable o no.


Acabo de encontrar una explanation maravillosa de la ortogonalidad de OOP y FP.

La idea básica es la siguiente. Imagina que estamos trabajando con AST de expresiones matemáticas. Entonces tenemos diferentes tipos de sustantivos (constante, suma, multiplicación) y diferentes verbos (eval, toString).

Digamos que la expresión es (1 + 2) * 3 . Entonces el AST sería:

multiplication / / addition 3 / / 1 2

Para implementar un verbo, debemos proporcionar su implementación para cada tipo de sustantivo. Podemos representarlo como una tabla:

+---------------------+-------------------------------------+ | eval | toString | +---------------+---------------------+-------------------------------------+ | constant | value | value.toString | +---------------+---------------------+-------------------------------------+ | addition | lhs.eval + rhs.eval | lhs.toString + " + " + rhs.toString | +---------------+---------------------+-------------------------------------+ | mutiplication | lhs.eval * rhs.eval | lhs.toString + " * " + rhs.toString | +---------------+---------------------+-------------------------------------+

La "ortogonalidad" proviene del hecho de que, en OOP , implementaremos esta tabla por filas : representaremos cada sustantivo como una clase, que deberá implementar cada método.

En FP , por otro lado, implementaremos esta tabla por columnas - escribiremos una función para cada verbo, y esta función reaccionará de manera diferente a los argumentos de diferentes tipos (probablemente usando la coincidencia de patrones).


Como todas las clasificaciones, la división de lenguajes de programación en funcional, orientada a objetos, procedural, etc. es ficticia. Pero sí necesitamos clasificaciones, y en los lenguajes de programación clasificamos por un conjunto de características del lenguaje y el enfoque filosófico de aquellos que usan el lenguaje (donde el último es influenciado por el primero).

Por lo tanto, a veces los lenguajes "orientados a objetos" pueden tener éxito al adoptar las características y filosofías de los lenguajes de programación "funcionales" y viceversa. Pero ciertamente no todas las características y filosofías del lenguaje de programación son compatibles.

Por ejemplo, un lenguaje funcional como OCaml logra la encapsulación a través del alcance léxico y cierres, mientras que los lenguajes orientados a objetos usan modificadores de acceso público / privado. Estos no son mecanismos incompatibles per-se, pero son redundantes, y un lenguaje como F # (un lenguaje principalmente funcional que busca vivir en armonía con la biblioteca .NET decididamente orientada a objetos y la pila de idiomas) tiene que llegar a ser un puente. el hueco.

Como otro ejemplo, OCaml usa un sistema de tipo estructural para la orientación a objetos, mientras que la mayoría de los lenguajes orientados a objetos usan un sistema de tipo nominal. Estos son bastante-muy incompatibles, y curiosamente representan incompatibilidad dentro del ámbito de los lenguajes orientados a objetos.


La idea de los objetos se puede implementar de manera inmutable. Un ejemplo es el libro " A Theory of Objects ", de Abadi y Cardelli, que pretende formalizar estas ideas, y donde a los objetos se les da semántica inmutable por primera vez, porque eso hace que el razonamiento sobre los programas orientados a objetos sea más simple.

En este caso, un método que tradicionalmente habría modificado el objeto en su lugar, en su lugar devuelve un nuevo objeto, mientras que el objeto anterior persiste.


Ortogonal. Suena bien. Si tienes una educación, puedes dividirla un poco y pretender. Es un poco como un paradigma.

Todo depende de en qué círculos viajes y qué tipo de técnica de programación te brinde. He leído algunas publicaciones en SS y la mayoría de las que provienen de un lenguaje de programación funcional persisten en el hecho de que solo puede funcionar y cualquier otra cosa va en contra del pensamiento y la mentalidad.

La programación orientada a objetos se trata principalmente de capturar el estado y mantener este estado tan localizado como sea posible para que no se vea afectado por nada que no sea parte del objeto con el que administra el estado. Por otro lado, la programación funcional analiza el problema del estado desde una perspectiva diferente e intenta separar el estado del sistema y reducirlo a funciones. Sí, puede usar ambas técnicas en su código, pero ambas miran el diseño del software desde diferentes ángulos.

Ha habido un gran interés en las técnicas de Programación Funcional, principalmente debido a la administración requerida del estado cuando se trata de chips multi-core y programación paralela. Parece que en este punto en el tiempo la programación funcional tiene la ventaja al lidiar con esto, sin embargo puede lograr el mismo efecto usando Objetos. Simplemente piensas en el problema de manera diferente. En lugar de rascarse la cabeza, tratando de deshacerse del estado tanto como sea posible, observa los objetos en el diseño y ve cómo puede emparejarlos con el núcleo de lo que se espera que hagan, utilizando patrones de diseño, CRC y Análisis de Objetos. Sin embargo, donde los Objetos vienen a ser propios, y donde la programación funcional es mucho más difícil, es analizando el mundo real y asignándolo a un sistema computarizado comprensible. En OO, por ejemplo, un objeto de persona sería una encapsulación de estado con métodos que actúan según el estado de las personas. En la programación funcional, una persona se descompone en partes de datos y funciones que actúan sobre los datos de la persona, con la condición adicional de que los datos deben crearse una sola vez y ser inmutables.

Debo admitir, aunque proveniente de un fondo de OO, que en la mayoría de los lenguajes de OO cuando se trata de chips de múltiples núcleos, he seguido la ruta funcional, principalmente por estructuras de diseño de programación central (como subprocesos y delegados) y paso los objetos de pseudodatos. Esto me ha llevado a cuestionar las técnicas de programación de OO, ya que no parece ajustarse bien a este diseño enhebrado.


Para dos conceptos ser ortogonales significa que pueden realizarse independientemente en cualquier grado en cualquier manifestación dada. Teniendo en cuenta la música, por ejemplo, puede clasificar una pieza musical en cuanto a qué tan armónica es y qué tan rítmica es. Los dos conceptos "armónico" y "rítmico" son ortogonales en el sentido de que hay piezas armónicas y rítmicas, piezas desarmónicas y arrítmicas, pero también piezas discordantes y rítmicas, así como piezas armónicas y arrítmicas.

Aplicado a la pregunta original, esto significa que hay lenguajes de programación puramente funcionales, no orientados a objetos, como Haskell, lenguajes "no funcionales" orientados a objetos, como Eiffel, pero también lenguajes que no son ni C, ni idiomas que son ambos como Scala.

Simplemente hablando, Scala al estar orientado a objetos significa que puede definir estructuras de datos ("clases" y "rasgos") que encapsulan datos con los métodos que manipulan estos datos, garantizando que las instancias de estas estructuras ("objetos") estén siempre en una estado definido (el contrato del objeto presentado en su clase).

Por otro lado, el hecho de que Scala sea un lenguaje funcional significa que favorece el estado inmutable sobre el mutable y que las funciones son objetos de primera clase, que se pueden usar como cualquier otro objeto como variables locales, campos o parámetros para otras funciones. Además de esto, casi cada declaración en Scala tiene un valor, que lo alienta a usar un estilo de programación funcional.

La ortogonalidad de la programación orientada a objetos y la programación funcional en Scala también significa que usted, como programador, puede elegir libremente cualquier combinación de estos dos conceptos que considere adecuados para su propósito. Puede escribir sus programas en un estilo puramente imperativo, utilizando solo objetos mutables y sin usar funciones como objetos en absoluto, por otro lado también puede escribir programas puramente funcionales en Scala sin utilizar ninguna de sus características orientadas a objetos.

Scala realmente no requiere que uses un estilo u otro. Te permite elegir lo mejor de ambos mundos para resolver tu problema.


Puede implementar funciones como objetos y objetos como colecciones de funciones, por lo que es evidente que existe alguna relación entre los dos conceptos.

FP fomenta la inmutabilidad y la pureza tanto como sea posible

Estás hablando de programación puramente funcional.

mientras que OO parece construido para estado y mutación

No hay ningún requisito para que los objetos sean mutables. Yo diría que los objetos y la mutación son conceptos ortogonales. Por ejemplo, el lenguaje de programación OCaml proporciona una sintaxis para la actualización de objetos puramente funcionales.

Un lenguaje como Scala hace que sea fácil hacer OO y FP ambos

Realmente no. La falta de optimización de la cola de llamadas significa que la mayoría del código idiomático puramente funcional acumulará desbordamiento en Scala porque pierde fotogramas de la pila. Por ejemplo, estilo de paso de continuación (CPS) y todas las técnicas descritas en el documento That about wraps up by Bruce McAdam. No hay una manera fácil de solucionar eso porque la propia JVM no es capaz de optimizar la cola de llamada.

Con respecto a la ortogonalidad de la programación puramente funcional y la programación orientada a objetos, diría que están al menos cerca de ser ortogonales simplemente porque la programación puramente funcional trata solo con programas pequeños (por ejemplo, funciones de orden superior) mientras que la programación orientada a objetos trata con los grandes -Estructura de escalas de programas. Esta es la razón por la que los lenguajes de programación funcionales suelen proporcionar algún otro mecanismo para la estructuración a gran escala, por ejemplo, los sistemas de módulos de orden superior de Standard ML y OCaml, o CLOS para Common Lisp o clases de tipos para Haskell.


Una cosa que me ayudó a entender la relación entre FP y OO fue el libro de SICP, particularmente la sección "Modularidad de programas funcionales y modularidad de objetos". Si está pensando en estos temas y tiene un fin de semana libre, podría valer la pena leerlo los primeros tres capítulos, su bonita apertura de ojos.


Orthogonality implica que dos cosas no están relacionadas. Viene de las matemáticas, donde significa perpendicular . En el uso común, puede significar que dos decisiones no están relacionadas o que un tema es irrelevante cuando se considera otro tema. Como se usa aquí, ortogonal significa que un concepto no implica ni excluye al otro.

Los dos conceptos de programación orientada a objetos y programación funcional no son incompatibles entre sí. Orientación a objetos no implica mutabilidad. Muchas personas que son introducidas a los programas orientados a objetos de la manera tradicional a menudo primero usan C ++, Java, C # o idiomas similares donde la mutabilidad es común e incluso fomentada (las bibliotecas estándar proporcionan una variedad de clases mutables para que las personas usen). Por lo tanto, es comprensible que muchas personas asocien la programación orientada a objetos con programación imperativa y mutabilidad, ya que así es como lo han aprendido.

Sin embargo, la programación orientada a objetos cubre temas como:

  • Encapsulación
  • Polimorfismo
  • Abstracción

Nada de esto implica mutabilidad, y ninguno de ellos excluye la programación funcional. Entonces sí, son ortogonales porque son conceptos diferentes. No son opuestos: puedes usar uno, o el otro, o ambos (o incluso ninguno). Idiomas como Scala y F # intentan combinar ambos paradigmas en un solo idioma:

Scala es un lenguaje de programación multi-paradigma diseñado para integrar características de programación orientada a objetos y programación funcional .

Source

F # es un lenguaje sucinto, expresivo y eficiente orientado a objetos y funcional para .NET que le ayuda a escribir código simple para resolver problemas complejos.

Source