Siempre he pensado que la programación funcional se puede hacer en Python. Por lo tanto, me sorprendió que Python no recibiera mucha mención en esta pregunta, y cuando se mencionó, normalmente no fue muy positivo. Sin embargo, no se dieron muchas razones para esto (se mencionó la falta de coincidencia de patrones y los tipos de datos algebraicos). Entonces mi pregunta es: ¿por qué Python no es muy bueno para la programación funcional? ¿Hay más razones que su falta de coincidencia de patrones y tipos de datos algebraicos? ¿O son estos conceptos tan importantes para la programación funcional que un lenguaje que no los admite solo puede clasificarse como un lenguaje de programación funcional de segunda categoría? (Tenga en cuenta que mi experiencia con la programación funcional es bastante limitada).
fuente
Respuestas:
La pregunta a la que hace referencia pregunta qué lenguajes promueven tanto la OO como la programación funcional. Python no promueve la programación funcional a pesar de que funciona bastante bien.
El mejor argumento en contra de la programación funcional en Python es que Guido considera cuidadosamente los casos de uso imperativo / OO, mientras que los casos de uso de programación funcional no lo son. Cuando escribo Python imperativo, es uno de los lenguajes más bonitos que conozco. Cuando escribo Python funcional, se vuelve tan feo y desagradable como su lenguaje promedio que no tiene un BDFL .
Lo que no quiere decir que sea malo, solo que tiene que trabajar más duro de lo que lo haría si cambiara a un lenguaje que promueva la programación funcional o cambie a escribir OO Python.
Estas son las cosas funcionales que extraño en Python:
list
si desea persistencia. (Los iteradores son de uso único)fuente
Guido tiene una buena explicación de esto aquí . Aquí está la parte más relevante:
Saco dos cosas de esto:
fuente
El esquema no tiene tipos de datos algebraicos o coincidencia de patrones, pero sin duda es un lenguaje funcional. Cosas molestas sobre Python desde una perspectiva de programación funcional:
Lambdas lisiadas. Dado que Lambdas solo puede contener una expresión, y no puede hacer todo tan fácilmente en un contexto de expresión, esto significa que las funciones que puede definir "sobre la marcha" son limitadas.
Ifs son declaraciones, no expresiones. Esto significa, entre otras cosas, que no puedes tener una lambda con un If dentro. (Esto se soluciona mediante ternaries en Python 2.5, pero se ve feo).
Guido amenaza con eliminar el mapa, filtrar y reducir de vez en cuando
Por otro lado, Python tiene cierres léxicos, Lambdas y listas de comprensión (que son realmente un concepto "funcional", lo admita o no Guido). Hago mucha programación de "estilo funcional" en Python, pero difícilmente diría que es ideal.
fuente
Nunca llamaría a Python "funcional", pero cada vez que programo en Python, el código termina siendo casi puramente funcional.
Es cierto que eso se debe principalmente a la comprensión de la lista extremadamente agradable. Por lo tanto, no necesariamente sugeriría Python como un lenguaje de programación funcional, pero sugeriría una programación funcional para cualquier persona que use Python.
fuente
Permítanme demostrar con un fragmento de código tomado de una respuesta a una pregunta de Python "funcional" sobre SO
Pitón:
Haskell
La diferencia principal aquí es que la biblioteca estándar de Haskell tiene funciones útiles para la programación funcional: en este caso
iterate
,concat
y(!!)
fuente
grandKids()
el cuerpo con el generador de expresiones:return reduce(lambda a, v: concat((x for x in kidsFunc(v)) for v in a), xrange(generation), [val])
.concat
:return reduce(lambda a, v: (x for v in a for x in kidsFunc(v)), xrange(generation), [val])
itertools.chain.from_iterable
Una cosa que es realmente importante para esta pregunta (y las respuestas) es la siguiente: qué demonios es la programación funcional y cuáles son sus propiedades más importantes. Trataré de dar mi punto de vista:
La programación funcional es muy parecida a escribir matemáticas en una pizarra. Cuando escribe ecuaciones en una pizarra, no piensa en una orden de ejecución. No hay (típicamente) ninguna mutación. No regresas al día siguiente y lo miras, y cuando haces los cálculos nuevamente, obtienes un resultado diferente (o puedes, si tomaste un café recién hecho :)). Básicamente, lo que está en la pizarra está ahí, y la respuesta ya estaba allí cuando comenzaste a escribir las cosas, simplemente no te has dado cuenta de lo que es todavía.
La programación funcional se parece mucho a eso; no cambia las cosas, simplemente evalúa la ecuación (o en este caso, "programa") y descubre cuál es la respuesta. El programa sigue ahí, sin modificaciones. Lo mismo con los datos.
Clasificaría lo siguiente como las características más importantes de la programación funcional: a) transparencia referencial: si evalúa la misma declaración en otro momento y lugar, pero con los mismos valores variables, seguirá significando lo mismo. b) sin efectos secundarios: no importa cuánto tiempo mires la pizarra, la ecuación que otro chico está mirando a otra pizarra no cambiará accidentalmente. c) las funciones también son valores. que se puede pasar y aplicar con, o a, otras variables. d) composición de funciones, puede hacer h = g · f y así definir una nueva función h (..) que es equivalente a llamar a g (f (..)).
Esta lista está en mi orden de prioridad, por lo que la transparencia referencial es la más importante, seguida de ningún efecto secundario.
Ahora, si revisa Python y verifica qué tan bien el lenguaje y las bibliotecas soportan y garantizan estos aspectos, entonces está en camino de responder su propia pregunta.
fuente
Python es casi un lenguaje funcional. Es "funcional lite".
Tiene características adicionales, por lo que no es lo suficientemente puro para algunos.
También carece de algunas características, por lo que no es lo suficientemente completo para algunos.
Las características que faltan son relativamente fáciles de escribir. Echa un vistazo a publicaciones como esta en FP en Python.
fuente
Otra razón no mencionada anteriormente es que muchas funciones y métodos integrados de tipos incorporados modifican un objeto pero no devuelven el objeto modificado. Si se devolvieran esos objetos modificados, eso haría que el código funcional fuera más limpio y conciso. Por ejemplo, si some_list.append (some_object) devuelve some_list con some_object adjunto.
fuente
Además de otras respuestas, una de las razones por las que Python y la mayoría de los otros lenguajes de paradigmas múltiples no son adecuados para una verdadera programación funcional es porque sus compiladores / máquinas virtuales / tiempos de ejecución no admiten la optimización funcional. El compilador logra este tipo de optimización entendiendo las reglas matemáticas. Por ejemplo, muchos lenguajes de programación admiten una
map
función o método. Esta es una función bastante estándar que toma una función como un argumento y un iterable como el segundo argumento y luego aplica esa función a cada elemento en el iterable.De todos modos resulta que
map( foo() , x ) * map( foo(), y )
es lo mismo quemap( foo(), x * y )
. El último caso es en realidad más rápido que el primero porque el primero realiza dos copias donde el último realiza una.Los mejores lenguajes funcionales reconocen estas relaciones basadas en matemáticas y realizan automáticamente la optimización. Los lenguajes que no están dedicados al paradigma funcional probablemente no se optimizarán.
fuente
map( foo() , x ) * map( foo(), y ) == map( foo(), x * y )
No es cierto para todas las funciones. Por ejemplo, considere el caso cuandofoo
calcule una derivada.+
lugar de*
.