Durante todo el año pasado he escrito código Scala (proveniente de un fondo Java). Realmente me gustó cómo podría crear un código más simple y limpio, con vals, clases de casos, funciones de mapa / filtro / lambda, implicidades y la inferencia de tipos. Lo he usado principalmente para una aplicación basada en Akka .
Este año estoy en un proyecto Scala con un nuevo equipo, a quien realmente le gusta la programación funcional. Usan mucho Scalaz , y el código está lleno en todas partes con solicitantes, límites de contexto, mónada de lector / escritor / estado, incluso el método principal está "envuelto" en una mónada de E / S. Su razonamiento es que esto hace que el compilador "trabaje para nosotros" al afirmar que el código es correcto y que cada función está libre de efectos secundarios.
Aun así, desde mi punto de vista, toda esta sintaxis realmente se interpone en el camino de la lógica empresarial. Por ejemplo, un tipo de "MyBusinessObject" está bien, al igual que tipos como "List [MyBusinessObject]", "Option [MyBusinessObject]" o incluso "Future [MyBusinessObject]". Todos tienen un significado y un propósito claros. Por otro lado, código como:
def method[M[_]: Applicative] = {
case (a, b) => (ca[M](a) |@| cb[M](b)) {
case t @ (ra, rb) =>
if (ra.result && rb.result) t.right
else t.left
}
}
¿Le agrega complejidad al programa o soy yo el único que no estoy acostumbrado a esta forma de programación?
fuente
>>=
y<$>
, que no significan nada hasta que saber lo que hacen Sin embargo, después de aprender lo que significan, ahora me leen muy natural y rápidamente. Realmente no es una respuesta, solo mi experiencia objetiva con cosas como esta. También uso Scala, pero no tengo experiencia con la biblioteca Scalaz.for(i=0; i<7; ++i) { trivialOperation(i); }
con algunatrivialOperationCount
variable incómoda , ¿verdad?) Ahora, los lenguajes de programación funcionales con coincidencia de patrones a veces introducirán algunas variables más donde simplemente escribiría llamadas al método de acceso en OO. El resultado es generalmente más conciso; quizás un poco menos autoexplicativo, pero buscar la declaración de datos normalmente lo deja claro rápidamente. La escritura estática ayuda mucho, no es como en APL.Respuestas:
Esto no tiene nada que ver con la programación funcional: puede encontrar este tipo de situación en el contexto de cualquier otro lenguaje de programación: los desarrolladores que aman tanto las construcciones avanzadas de "su" lenguaje que ignoran cualquier sentido común sobre la legibilidad y mantener las cosas simples. Me he encontrado con tal situación en C, C ++, Perl, Java, C #, Basic y otros lenguajes no funcionales. No es la programación funcional lo que agrega complejidad al código, como hacen los programadores.
No me malinterpreten, no recomiendo evitar las funciones avanzadas de lenguaje, pero es importante encontrar el equilibrio adecuado en el contexto dado. Al escribir una biblioteca genérica para el uso de> 100,000 desarrolladores en todo el mundo, existen diferentes medidas para aplicar, como cuando se escribe un generador de informes individual solo para su oficina local.
fuente
Yo diría que no estás acostumbrado a la forma en que codifican es al menos parte de la imagen. Estoy en una situación similar a la tuya (viniendo de C # a F # y trabajando con personas con antecedentes de Haskell), y aunque me parece una experiencia interesante, tengo momentos en los que me golpeo la cabeza contra la pared, desenredando un composición de funciones sin puntos particularmente enrevesada solo para familiarizarse con lo que está sucediendo allí. Es una cosa cultural.
En cuanto a si este código en particular agrega complejidad al programa, no lo sé. Convino en que un código genérico puede ser complejo en sí mismo. Pero es una utilidad, no una parte de la lógica empresarial. Si desea saber si hace que la base de código sea más compleja o más simple, tendrá que imaginar cómo debería verse sin ese fragmento de código. A menudo es el caso con construcciones tan genéricas que son complejas en sí mismas, pero es una complejidad que puede caber en una sola pantalla. Al mismo tiempo, hacen que toda la base de código sea un poco más simple. Este es particularmente el caso de las mónadas.
Por otra parte, también puede ser un caso de 'arte por el arte', como sugiere @Doc Brown. No puedo descartarlo tampoco.
fuente
Yo diría que, en general, la programación funcional reduce la complejidad al eliminar el estado mutable, reduciendo así el número de casos que deben considerarse al tratar de comprender cómo funciona una sección de código.
Sin embargo, la programación funcional hace posible mayores grados de abstracción, y aunque el código altamente abstracto puede ser extremadamente útil, también puede ser difícil de entender porque, por definición, está separado del contexto que normalmente usaría para guiar su comprensión. Su comentario "Todos tienen un significado y un propósito claros" sobre los objetos comerciales es indudablemente cierto, pero en realidad es un reflejo del hecho de que esa lógica es muy específica para una necesidad y un contexto que ya comprende. La existencia de una construcción como Monad le permite hacer algo muy útil con poco esfuerzo, pero la web está llena de páginas que intentan explicar qué es una Monad. Eso es abstracción para ti.
Además, Scalaz fue escrito por personas que habían estado comiendo y respirando FP durante mucho tiempo; querían llevar la funcionalidad disponible en Haskell a Scala. Al hacerlo, no intentaron ser pedagógicos. Scalaz utiliza un vocabulario y un estilo que parecen claros y directos para los autores pero ajenos a los no iniciados. Los métodos que son desconcertantes para el resto de nosotros parecían tan obvios para los autores, dados sus antecedentes de Haskell, que ni siquiera justificaron un comentario.
Además, como lenguaje de programación funcional, Scala tiene algunas deficiencias (en parte porque la JVM tiene deficiencias) que obligaron a los autores de Scalaz a escribir código más feo en algunos casos. Por ejemplo, la falta de eliminación general de llamadas de cola obliga al uso de trampolines en algún código, y la falta de un "sistema amable" puede complicar las firmas de tipo.
Y finalmente, Scalaz hace un gran uso de sí mismo. Eso podría considerarse como un signo de su poder, pero para los no iniciados puede hacer que la fuente sea un rompecabezas: cualquier pieza aleatoria de código que mires probablemente haga uso de otra cosa que te parezca ajena.
Cuelga ahí. Y esto podría ayudar.
fuente
¿Agrega complejidad al programa, o es solo que no estás acostumbrado a esta forma de programación?
¿Por qué crees que estas posibilidades no son lo mismo?
El código bien escrito puede ser leído por personas que no están familiarizadas con el lenguaje de programación específico. Algunos idiomas (BÁSICO, Pascal, etc.) pueden ser leídos y entendidos por escolares que nunca antes han visto ningún lenguaje de programación.
Si alguien que tiene experiencia con otros idiomas y experiencia con Scala (y que supongo que ha trabajado con Scalaz durante al menos una semana y tiene colegas para explicar las cosas más difíciles) todavía está confundido; entonces eso es prueba de que ha agregado complejidad.
fuente
"Well written code can be read by people who aren't familiar with the specific programming language."
x[⍋x←6?40]
. ¿Qué crees que hace? Seguro que no lo habría sabido ...