¿Aprender un lenguaje funcional hace un mejor programador de OOP? [cerrado]

28

Como programador de Java / C # / C ++, escucho mucho hablar sobre lenguajes funcionales, pero nunca he encontrado la necesidad de aprender uno. También he oído que el mayor nivel de pensamiento introducido en los lenguajes funcionales lo convierte en un mejor programador de lenguaje de procedimiento / OOP.

¿Alguien puede confirmar esto? ¿De qué manera mejora tus habilidades de programación?

¿Cuál es una buena opción de idioma para aprender con el objetivo de mejorar las habilidades en un idioma menos sofisticado?

GavinH
fuente
3
Si está codificando en C #, ya conoce uno. LINQ es algo bastante funcional.
SK-logic
Creo que OOP es mejor para modelar objetos de la vida real.
Tulains Córdova
1
@ user61852 La mayoría de los patrones de diseño de OO no modelan nada sobre objetos de la "vida real", sino conceptos muy abstractos.
Andres F.
Sé más que un programador Java / C # (+ C ++). Hay una diferencia entre una gigantesca navaja suiza con un panfleto no tan pequeño que describe por qué elegirías la cuchilla X de 40 y una cuchilla que puedes tallar muy cerca de cualquier cosa que desees porque es malditamente afilada y curvada. correcto para que pueda aplicar su poder de corte a una amplia variedad de circunstancias sin pensarlo mucho. (con un abrebotellas en el mango, por supuesto)
Erik Reppen

Respuestas:

32

Yo , básicamente, de acuerdo con la respuesta de FrustratedWithFormsDesign , pero también se preguntan cómo el aprendizaje del nuevo paradigma ayuda a desarrollar habilidades de uno. Puedo dar un par de ejemplos de mi propia experiencia.

Desde que aprendí la programación funcional, soy mucho más consciente de qué conceptos con los que trabajo se consideran más naturalmente como "objetos" (en general, cuando la mutación tiene sentido) y cuáles se consideran más naturalmente como "valores" inmutables (creo que hay una distinción importante , tocando dónde OO tiene sentido frente a cuándo FP tiene sentido, pero esa es solo mi opinión).

Noto que mi código incluye efectos secundarios, y soy más cuidadoso de aislar esos lugares, haciendo que mis funciones sean más "puras". Esto mejora enormemente la capacidad de prueba de mi código OO.

Soy más consciente de los ciclos en mi representación de datos. (Por ejemplo, no creo que pueda escribir una función para convertir una lista enlazada en una lista doblemente enlazada en Haskell, por lo que nota los ciclos un poco más en ese idioma). Evitar los ciclos reduce la cantidad de sincronización debe realizar para que sus estructuras de datos sean coherentes internamente, lo que facilita la carga de compartir estas estructuras entre subprocesos.

Es más probable que confíe en la recursividad (las construcciones de bucle recursivo del esquema son cosas hermosas). Dijkstra mencionó la importancia de esto en las Notas sobre programación estructurada : los algoritmos recursivos se correlacionan muy directamente con la inducción matemática, lo que sugiere que es el único medio para demostrar intelectualmente que nuestros bucles son correctos. (No sugiero que debamos probar que nuestro código es correcto, pero que cuanto más fácil lo hagamos para nosotros, lo más probable es que nuestro código sea correcto).

Es más probable que use funciones de orden superior. El artículo de John Hughes, Por qué es importante la programación funcional . Enfatiza la componibilidad que se obtiene al emplear técnicas de programación funcional, las funciones de orden superior juegan un papel importante.

Además, como se menciona en la respuesta de Jetti , encontrará que se están incorporando muchas ideas de FP en los nuevos lenguajes OO. Ruby y Python proporcionan muchas funciones de orden superior, he oído que LINQ se describe como un intento de brindar soporte para las comprensiones monádicas en C #, incluso C ++ ahora tiene expresiones lambda.

Aidan Cully
fuente
@Aidan: wrt lambdas en C ++ 0x, en cualquier caso, los nuevos compiladores de C ++ ya los han incorporado.
Matthieu M.
1
"Objeto" como "cosa que tiene estado mutable" es muy común, pero el patrón de Objeto de Valor ha existido durante muchos años.
Frank Shearar
@ Matthieu, gracias, he actualizado el texto para reflejar eso.
Aidan Cully
@ Frank: gracias por el puntero. No incluí esto en la respuesta, pero la principal objeción que tengo para convertir los valores en objetos tiene que ver con la distinción entre interfaces de objetos en blanco y negro (que son propiedad de objetos) y operaciones (en las que las relaciones entre objetos son más primario que los objetos mismos). 1 + 2es matemáticamente equivalente a 2 + 1, pero 1.+(2)se implementa de manera diferente a 2.+(1). Existen varios problemas de SW que pueden entenderse más naturalmente usando operaciones que usando interfaces de objetos.
Aidan Cully
1
@Aidan ¿Has leído William Cook "Sobre entender la abstracción de datos, revisitado"? Se profundiza en las diferencias entre objetos y ADT, que es lo que estás insinuando.
Frank Shearar
32

No diría que está garantizado para hacerte un mejor programador de OOP, pero te presentará una nueva forma de pensar, y eso podría hacerte mejor en la resolución de problemas en general, no solo en términos de OOP.

FrustratedWithFormsDesigner
fuente
3
Dado que los objetos son en realidad funciones de orden superior, descubrí que aprender cosas de FP me ayudó directamente con mi OOP. Es, como usted dice, más generalmente aplicable / útil sin embargo.
Frank Shearar
12

Aprender un lenguaje funcional, Lisp para mí, realmente ayuda a la hora de crear aplicaciones paralelas. Los métodos funcionales (basados ​​en estado, sin efectos secundarios) son mucho más fáciles de sincronizar y son más seguros para el subproceso, ya que solo dependen de su entrada. Eso significa que los únicos datos que necesita observar para un área de código dada son los parámetros que ingresa. Esto también facilita la depuración.

Michael K
fuente
Encontrará que también ayuda con las bibliotecas de subprocesos, que tienden a esperar funciones puras como sus tareas. También puede ayudar indirectamente, hay lugares donde escribiré código OO en una especie de "estilo funcional" donde hay un "parámetro propietario" que tiene un bloqueo implícito en un grupo de objetos a los que hace referencia y son utilizados por la función . Siempre que documente sus expectativas (y las pruebe unitariamente), esto puede proporcionarle un mejor código multiproceso con pocos problemas de bloqueo. Y pocas cerraduras explícitas.
Nunca he oído que Prolog sea llamado un lenguaje funcional. Si entrecierro los ojos lo suficiente, puedo ver vagamente cómo (partes de) Prolog podría ayudar con FP.
Frank Shearar
1
Prolog no es un lenguaje funcional. Es un lenguaje lógico. Si quiere un lenguaje lógico similar a Prolog que también sea programación funcional integrada, tenga en cuenta que puede echar un vistazo a Mercury . Advertencia: Te dolerá un poco el cerebro incluso si ya conoces a Prolog.
SOLO MI OPINIÓN correcta
@ SOLO MI OPINIÓN correcta: Sí, creo que tienes razón. ¡Supongo que necesito aprender más sobre lenguajes funcionales!
Michael K
1
@moz: Sí, desearía que Java tuviera lambdas. Los Threadobjetos anónimos son ... torpes.
Michael K
9

Aprender cualquier otro paradigma de programación mejorará tus habilidades de programación en general. La programación, cuando no es material académico de grado de investigación (e incluso entonces, a menudo), es básicamente la resolución de problemas. Pensando, en una palabra. Los diversos paradigmas son diferentes formas de pensar sobre los problemas y sus soluciones. Por lo tanto, no piense que es "aprender un lenguaje funcional". Piense en ello como "aprender una forma diferente de pensar sobre los problemas y sus soluciones". Entonces verá los beneficios de aprender un idioma, incluso si nunca lo usa.

Para abordar su pregunta específica, yo era un programador de C ++ en los días de antaño (antes de que hubiera un estándar para C ++). Seguí todas las cosas habituales con objetos que mantenían el estado manipulado por métodos, etc., etc., etc. Luego me topé con Haskell y aprendí (gran parte). (No creo que nadie aprenda realmente a Haskell). El ejercicio parecía un poco perdido en ese momento hasta que uno de mis colegas, el evaluador asignado a mi grupo, hizo un comentario informal de que mi código se estaba volviendo más fácil de probar.

Lo que sucedió fue que había comenzado a hacer mis objetos más y más inmutables. Las clases con un estado mutable complejo comenzaron a ser reemplazadas por clases que se clonaron a sí mismas con cambios, devolviendo los nuevos objetos. Los objetos compartidos comenzaron a ser reemplazados por objetos que tenían una semántica de copia en escritura (dando así la ilusión de muchos clones de objetos sin la sobrecarga de memoria). Las funciones no tienen efectos secundarios a menos que sea absolutamente necesario; la definición pura y matemática de "función" era cada vez más la norma. Todo esto comenzó a suceder en mi código de forma natural, sin pensar conscientemente, mientras exploraba más y más el espacio de programación funcional.

Ahora me propongo aprender al menos un nuevo paradigma de programación cada dos años (incluso si es solo un paradigma de extensión menor como AOP) y al menos dos nuevos lenguajes dentro de cada paradigma (uno tan puro como sea posible, uno más híbrido / práctico ) Cada uno me ha dado nuevas herramientas intelectuales para aplicar a toda mi programación en cualquier idioma, por lo que, en mi opinión, el tiempo dedicado a aprenderlas no se ha desperdiciado ni un poco.

SOLO MI OPINIÓN correcta
fuente
3

Lo dije antes y lo diré nuevamente, aprender lenguajes funcionales definitivamente mejoró mi C #. Me ayudó a entender las lambdas (y me ayudó a amarlas). ¡También me hizo darme cuenta de cuánto prefiero la programación funcional (F #) cuando trabajo con operaciones asincrónicas!

Jetti
fuente
3

El código de máquina no es más que una lista de efectos secundarios: comandos que ejecuta directamente el procesador. Los efectos secundarios en C son diferentes, en lugar de manejar los registros y el hardware físico, lidias con un conjunto de abstracciones y dejas que el compilador haga todo el trabajo sucio. C también le permite estructurar sus efectos secundarios en bucles y, si es así, declaraciones. C ++ mejora a C al agregar OOP y algunas características muy necesarias al lenguaje. Java y C # agregan recolección de basura, y Python agrega escritura dinámica.

Incluso con todas estas características: los programas de mecanografía dinámica, recolección de basura, etc. en estos idiomas todavía se basan completamente en los efectos secundarios. Los lenguajes de programación funcionales, como Scheme, Clojure, Haskell y ML son algo completamente diferente, estos lenguajes están más cerca de las matemáticas que del código de máquina. En lugar de usar efectos secundarios, pasa valores alrededor de las funciones.

¿Cuál es una buena opción de idioma para aprender con el objetivo de mejorar las habilidades en un idioma menos sofisticado?

Recomiendo Scheme , es mínimo y se usó en las antiguas clases de programación introductoria del MIT. Los otros lenguajes de programación funcionales son mucho más difíciles de aprender. Clojure trae consigo todas las complejidades de Java, ML trae un complicado sistema de tipo estático, a veces se conoce a Haskell como un lenguaje académico; no es ideal para principiantes, etc. El esquema, por otro lado, es fácil de aprender y comprender.

¿De qué manera mejora tus habilidades de programación?

Casi todos los lenguajes de programación de alto nivel tienen funciones y recursividad, los conceptos en los que se basa la programación funcional. Como tal, su conocimiento de FP debería ser útil en casi todas partes, sin embargo, si realmente desea programar funcionalmente, debe usar un lenguaje donde sea natural y eficiente en lugar de tratar de doblar el diseño del lenguaje de otra persona a su gusto, es decir debe usar un lenguaje de programación funcional para hacer la programación funcional.

jhuni
fuente