Caso : estoy trabajando en una empresa, escribiendo una aplicación en Python que maneja una gran cantidad de datos en matrices. Soy el único desarrollador de este programa en este momento, pero probablemente será utilizado / modificado / extendido en el futuro (1-3 años) por algún otro programador, en este momento desconocido para mí. Probablemente no estaré allí directamente para ayudarlo, pero tal vez brinde algún soporte por correo electrónico si tengo tiempo para hacerlo.
Entonces, como desarrollador que ha aprendido programación funcional (Haskell), tiendo a resolver, por ejemplo, filtrar así:
filtered = filter(lambda item: included(item.time, dur), measures)
El resto del código es OO, solo son algunos casos pequeños donde quiero resolverlo así, porque es mucho más simple y más hermoso según yo.
Pregunta : ¿Está bien hoy escribir código como este?
- ¿Cómo reacciona un desarrollador que no ha escrito / aprendido FP al código como este?
- ¿Es legible?
- Modificable?
¿Debo escribir documentación como explicarle a un niño lo que hace la línea?
# Filter out the items from measures for which included(item.time, dur) != True
Le pregunté a mi jefe, y él simplemente dice "FP es magia negra, pero si funciona y es la solución más eficiente, entonces está bien usarla".
¿Qué opinas de esto? Como programador que no es FP, ¿cómo reaccionas al código? ¿Es el código "googable" para que pueda entender lo que hace? Me encantaría recibir comentarios sobre esto.
# Select the item's from measures for which included(item.time, dur) == True
evitar un doble negativo siempre mejora la comprensión.Respuestas:
Para mí: Sí, pero he llegado a comprender que la comunidad de Python a menudo parece considerar que las comprensiones de listas son una solución más limpia que usar
map()
/filter()
.De hecho, GvR incluso consideró abandonar esas funciones por completo.
Considera esto:
Además, esto tiene el beneficio de que una comprensión de la lista siempre devolverá una lista.
map()
yfilter()
por otro lado devolverá un iterador en Python 3.Nota: Si quieres tener un iterador, es tan simple como reemplazarlo
[]
por()
:Para ser honesto, veo poca o ninguna razón para usar
map()
ofilter()
en Python.Sí, ciertamente, sin embargo, hay una cosa que lo hace más fácil: que sea una función, no una lambda.
Si su condición se vuelve más compleja, esto se escalará mucho más fácilmente, además, le permite reutilizar su cheque. (Tenga en cuenta que puede crear funciones dentro de otras funciones, esto puede mantenerlo más cerca del lugar donde se usa).
Busca en Google la documentación de Python y sabe cómo funciona cinco minutos después. De lo contrario, no debería estar programando en Python.
map()
yfilter()
son extremadamente simples No es como si les estuvieras pidiendo que entiendan las mónadas. Es por eso que no creo que necesites escribir tales comentarios. Use buenos nombres de variables y funciones, entonces el código se explica por sí mismo. No puede anticipar qué características de idioma no conoce un desarrollador. Por lo que sabes, el próximo desarrollador podría no saber qué es un diccionario.Lo que no entendemos generalmente no es legible para nosotros. Por lo tanto, podría argumentar que no es menos legible que una lista de comprensión si nunca antes ha visto ninguno de ellos. Pero como Joshua mencionó en su comentario, también creo que es importante ser coherente con lo que usan otros desarrolladores, al menos si la alternativa no ofrece una ventaja sustancial.
fuente
map
yfilter
hacen en python 3.reduce
como un contraejemplo, siempre se puede usar un argumento de comprensión de la lista , ya que es relativamente difícil reemplazarloreduce
con un generador en línea o una comprensión de la lista.Dado que la comunidad de desarrolladores está recuperando interés en la programación funcional, no es inusual ver algo de programación funcional en lenguajes que originalmente estaban completamente orientados a objetos. Un buen ejemplo es C #, donde los tipos anónimos y las expresiones lambda permiten ser mucho más cortos y expresivos a través de la programación funcional.
Dicho esto, la programación funcional es extraña para los principiantes. Por ejemplo, cuando durante un curso de capacitación, les expliqué a los principiantes cómo pueden mejorar su código a través de la programación funcional en C #, algunos de ellos no estaban convencidos, y algunos dijeron que el código original era más fácil de entender para ellos. El ejemplo que les di fue el siguiente:
Código antes de refactorizar:
Mismo código después de refactorizar usando FP:
Esto me hace pensar que:
No debe preocuparse si sabe que el próximo desarrollador que mantendrá su código tendrá suficiente experiencia general y algunos conocimientos de programación funcional, pero:
de lo contrario, evite la programación funcional o escriba un comentario detallado que explique al mismo tiempo la sintaxis, las ventajas y las posibles advertencias de su enfoque frente a una programación no funcional.
fuente
Soy un programador que no es FP y recientemente tuve que modificar el código de mi colega en JavaScript. Hubo una solicitud Http con una devolución de llamada que se parecía mucho a la declaración incluida por usted. Debo decir que me tomó algo de tiempo (como media hora) resolverlo (el código en general no era muy grande).
No hubo comentarios, y creo que no hubo necesidad de ninguno. Ni siquiera le pedí a mi colega que me ayudara a entender su código.
Teniendo en cuenta que estoy trabajando durante aproximadamente 1,5 años, creo que la mayoría de los programadores podrán entender y modificar dicho código, como lo hice.
Además, como dijo Joachim Sauer en su comentario, a menudo hay piezas de FP en muchos idiomas, como C # (indexOf, por ejemplo). Muchos programadores que no son FP se ocupan de esto con bastante frecuencia, y el fragmento de código que incluyó no es algo terrible o incomprensible.
fuente
Definitivamente diría que sí!
Hay muchos aspectos de la programación funcional, y el uso de funciones de orden superior, como en su ejemplo, es solo uno de ellos.
Por ejemplo, considero que escribir funciones puras es extremadamente importante para cualquier software escrito en cualquier idioma (donde "puro" no significa efectos secundarios), porque:
También evito a menudo mutar valores y variables, otro concepto tomado de FP.
Ambas técnicas funcionan bien en Python y otros lenguajes que no se clasifican comúnmente como funcionales. A menudo, incluso son compatibles con el lenguaje en sí (es decir,
final
variables en Java). Por lo tanto, los futuros programadores de mantenimiento no enfrentarán una enorme barrera para comprender el código.fuente
Tuvimos esta misma discusión sobre una compañía para la que trabajé el año pasado.
La discusión se refería al "código mágico" y si debía alentarse o no. Al analizarlo un poco más, parecía que las personas tenían puntos de vista muy diferentes sobre lo que en realidad era "código mágico". Los que mencionaron la discusión parecían significar principalmente que las expresiones (en PHP) que usaban el estilo funcional eran "código mágico", mientras que los desarrolladores que se originaron en otros lenguajes que usaban más estilo FP en su código parecen pensar que el código mágico era más bien cuando hiciste una inclusión dinámica de archivos a través de nombres de archivos, etc.
Nunca llegamos a una buena conclusión sobre esto, más allá de que la mayoría de la gente piense que el código que parece desconocido es "mágico" o difícil de leer. Entonces, ¿es una buena idea evitar el código que parece desconocido para otros usuarios? Creo que depende de dónde se use. Me abstendría de usar expresiones de estilo fp (inclusión dinámica de archivos, etc.) en un método principal (o partes centrales importantes de las aplicaciones) donde los datos deben ser tunelizados de una manera clara, fácil de leer e intuitiva. Por otro lado, no creo que uno deba temer empujar el sobre, los otros desarrolladores probablemente aprenderán FP rápidamente si se enfrentan con un código FP y tal vez tengan algún buen recurso interno para consultar sobre los problemas.
TL; DR: Evite en la parte central de alto nivel de las aplicaciones (que deben leerse para obtener una descripción general de la funcionalidad de la aplicación). De lo contrario, úsalo.
fuente
La comunidad C ++ también obtuvo lambda recientemente, y creo que tienen aproximadamente la misma pregunta. Sin embargo, la respuesta puede no ser la misma. El equivalente de C ++ sería:
Ahora
std::copy
no es nuevo, y las_if
variantes tampoco lo son, pero la lambda sí. Sin embargo, se define con bastante claridad en el contexto:dur
se captura y, por lo tanto,Item i
es constante, varía en el ciclo y la únicareturn
declaración hace todo el trabajo.Esto parece aceptable para muchos desarrolladores de C ++. Sin embargo, no he muestreado opiniones sobre lambda de orden superior, y esperaría mucha menos aceptación.
fuente
Publique un fragmento de código en un desarrollador que no sea tan fluido en Python y pregúntele si puede pasar 5 minutos revisando el código para ver si él / ella lo entiende.
En caso afirmativo, probablemente estés listo para ir. Si no es así, debe considerar aclararlo.
¿Podría su colega ser tonto y no entender algo que debería ser obvio? Sí, pero siempre debe programar de acuerdo con KISS.
¿Tal vez su código es más eficiente / atractivo / elegante que un enfoque más directo y a prueba de idiotas? Entonces debes preguntarte: ¿tengo que hacer esto? Nuevamente, si la respuesta es no, ¡no lo hagas!
Si después de todo esto, todavía cree que necesita y quiere hacerlo de la manera FP, entonces hágalo por todos los medios. Confíe en sus instintos, son más adecuados para sus necesidades que la mayoría de las personas en cualquier foro :)
fuente