¿Se puede utilizar la programación funcional para desarrollar una aplicación empresarial completa?

19

Estoy empezando a aprender la programación funcional (FP). Vengo de un mundo OOP, donde todo son objetos, y la mayoría de ellos son mutables. Me cuesta mucho entender el concepto de que las funciones no tienen efectos secundarios.

Si algo no es mutable, ¿cómo se representan objetos comunes como Empleado o Persona en FP?

¿Se puede utilizar FP para crear una aplicación empresarial completa?

usuario2434
fuente
55
¿Por qué una representación de un empleado tiene que ser mutable? Probablemente tiene estado, pero esa es otra pregunta por completo.
1
Se utilizan datos mutables que representan cosas. Por el contrario, los datos inmutables tienen el valor de algo en un momento específico (aunque este no es su único caso de uso). Si ha tenido un error en el que tiene dos objetos mutables que representan la misma cosa, entonces sabe de un caso en el que el uso de objetos para representar cosas puede descomponerse.
dan_waterworth
2
La programación funcional tiene efectos secundarios, de lo contrario, nunca podría imprimir nada.
1
@ Thorbjørn Ravn Andersen: En la programación imperativa (procesal, orientada a objetos), se usan efectos secundarios tanto para comunicarse con el mundo externo (IO) como para calcular las transformaciones de datos dentro de su programa. En FP, separa los dos mundos claramente: usa efectos secundarios solo para IO (un programa sin IO normalmente no sirve), pero usa funciones puras para calcular las transformaciones internas de datos. Los efectos secundarios no se pueden evitar por completo, pero como no son locales , es más difícil razonar sobre ellos, por lo que es bueno restringir su uso tanto como sea posible.
Giorgio
Algo así como un objeto "persona" no necesita ser mutable. En su lugar, crea un objeto "persona" completamente nuevo que es casi igual (pero ligeramente diferente). Tendrías una referencia al objeto "persona" en algún lugar y lo cambiarías para hacer referencia a la nueva copia en lugar de la copia anterior. Por supuesto, esa referencia podría estar en algún tipo de colección, así que cree una copia de la colección que sea casi la misma. ¡Tendría que haber una referencia a la colección en algún lugar para que pueda cambiar la colección anterior por la nueva colección!
Brendan

Respuestas:

17

La pregunta no es ¿Se puede utilizar FP en la empresa? pero ¿deberíamos usar FP en la Enteprise?

Por supuesto que puede. Puede desarrollar cualquier tipo de aplicación con cualquier tipo de lenguaje de programación, por eso se llaman "Turing complete".

Ahora, a la pregunta "¿Debería usarse en la empresa?" Depende de usted o de sus empleadores, FP puede ser realmente útil en algún tipo de aplicaciones, y de hecho, se usa bastante: Haskell en la industria

Ahora, usted podría estar preguntando "Entonces, ¿por qué no se usa más?" principalmente porque otros lenguajes imperativos / OO son más comunes, y las compañías se niegan a cambiar a un lenguaje más "exótico" porque están acostumbrados a Java o C ++.

dysoco
fuente
77
You can develop any kind of application with any kind of programming languageEse es un argumento muy débil, ten cuidado con las lonas de Turing ...
Yannis
55
@YannisRizos Creo que estaba generalizando por el bien de una respuesta directa en lugar de explorar cada tangente del problema.
Johnny Rotten
2
@YannisRizos puede !=querer
1
A veces se siente como a mí que incluso el lenguaje no debe ser Turing completo para cierto tipo de soluciones para empresas ...
shabunc
2
Diría que eso no depende de sus empleadores, cuando se trata de idiomas, depende de los propios ingenieros impulsar lo que vemos que es mejor desde nuestro punto de vista técnico.
shmish111
11

Empecé a aprender sobre lenguajes FP hace un par de años (Haskell, Scala, Scheme) y, aunque estoy lejos de ser un experto, descubrí que pueden hacerme extremadamente productivo, para ciertas tareas más que C ++ o Java .

En mi opinión, algunas de las fortalezas de los lenguajes FP son:

  • Tienden a ser muy concisos, pero conservan una semántica clara.
  • Puede usar un estilo declarativo y no necesita pensar demasiado en los detalles de implementación.
  • Un sistema de tipo rico como el de Haskell puede detectar muchos errores lógicos muy temprano (en tiempo de compilación). Hasta donde yo sé (no mucho, en realidad), SML y Ocaml ofrecen ventajas similares.

Hasta ahora, el cambio al paradigma FP me ha parecido bastante emocionante y no demasiado difícil una vez que pasas suficiente tiempo en él. (¿Pero cuánto tiempo pasé aprendiendo C o C ++? ¡Bastante!)

Así que creo que desde un punto de vista técnico tiene mucho sentido desarrollar una aplicación empresarial completa utilizando un lenguaje de programación funcional.

Desafortunadamente, este paradigma no es convencional: la mayoría de las empresas tienden a adoptar tecnologías bien probadas, por lo que se mantendrán alejados de FP hasta que tengan suficiente evidencia de que realmente funciona, de que hay suficientes desarrolladores, herramientas, bibliotecas, marcos. Por lo tanto, es (mucho) más difícil encontrar un trabajo en el que pueda hacer la programación de FP a tiempo completo en este momento.

Tal vez la situación actual cambie si el uso cada vez mayor de procesadores de múltiples núcleos aliente a invertir más en lenguajes FP, que parecen ser bastante fuertes para escribir software concurrente.

Además, existe una tendencia a introducir algunas características de FP en lenguajes no funcionales convencionales como C #, C ++ para que los programadores puedan usar algunos FP sin la necesidad de un cambio de paradigma completo. Tal vez en diez años a partir de ahora, estos lenguajes cubrirán suficientes características de FP para que el cambio a un lenguaje puramente funcional sea mucho más fácil.

Giorgio
fuente
10

No creo que sea necesariamente la mejor idea. Pero depende de la naturaleza de la aplicación específica.

Creo mucho en la filosofía de Eric Evans como se describe en su libro, Diseño impulsado por dominio , que debe hacer un modelo de dominio que sea una representación del problema en cuestión que pueda ayudarlo a resolver su problema. Evans sugiere encontrar un lenguaje de programación que se ajuste a la voluntad con el problema particular en cuestión, por ejemplo, menciona Fortran como una forma de resolver problemas de naturaleza matemática. O incluso crear lenguajes especializados de dominio específico para el problema en cuestión.

Cuando haya logrado crear un buen modelo de dominio, encontrará que el código de presentación termina siendo un caparazón delgado en la parte superior de la capa de dominio.

Ahora, la aplicación empresarial es que este tipo de aplicación (si puede generalizar sobre aplicaciones empresariales) a menudo implica modificar el estado de las entidades cuya identidad es importante y persistir las entidades modificadas en una base de datos. En mi humilde opinión, este tipo de problema muy generalizado se resuelve mucho mejor utilizando un modelo orientado a objetos que un modelo funcional.

Esto no significa que haya áreas de una aplicación empresarial que no podrían resolverse mejor con un paradigma funcional. Por ejemplo, un módulo de análisis de riesgos de una aplicación bancaria o un módulo de planificación de rutas en una aplicación de envío. Y quizás algunas aplicaciones empresariales podrían implementarse completamente usando un paradigma funcional.

Pero en general, creo que el paradigma orientado a objetos permite crear modelos de dominio más útiles para la mayoría de las aplicaciones empresariales.

Editar

Debido a algunos votos positivos, me llamó la atención esta respuesta, y desde que la escribí, he aprendido mucho más sobre FP, y ya no estoy completamente seguro de estar de acuerdo con mi propia respuesta. Algunos lenguajes funcionales pueden describir muy bien los casos de uso. Pero necesitas aprender una mentalidad completamente diferente.

Pete
fuente
2
+1: Muy buena y estimulante respuesta. Debido a mi conocimiento limitado sobre FP, no estoy seguro de si esto es correcto, pero creo que los objetos persistentes podrían modelarse usando mónadas o tipos únicos (en Clean): de esta manera, un valor puede obtener una identidad, pasar a su programa y transformado por diferentes funciones. Pero realmente necesitaría la opinión de un experto en FP para respaldar esto.
Giorgio
3

Sí puede. Google un poco y encontrarás software real codificado en lenguajes funcionales puros.

En cuanto a su pregunta sobre los objetos comerciales, supongo que su problema real es la inmutabilidad. En ese caso, considere que está devolviendo una nueva "Persona" cada vez que la mutaría si estuviera usando un lenguaje imperativo.

¡Tenga en cuenta que esta técnica también se puede implementar utilizando lenguajes imperativos!

Andres F.
fuente
3

La programación de funciones (FP) como la programación orientada a objetos (OOP) son paradigmas. Representan diferentes patrones o enfoques para problemas de programación. Estos enfoques diferentes no obvian la capacidad de producir software escalable, mantenible y extensible. Eso no quiere decir que los enfoques son equivalentes para todos los tipos de problemas; no lo son Ciertos problemas se alinean mejor (o peor) a paradigmas particulares, por ejemplo, FP no sería mi primera opción para un programa que tiene una secuencia dependiente de operaciones con efectos secundarios. Sin embargo, tales programas pueden y han sido escritos, y bien escritos.

dietbuddha
fuente
3

Sí, FP se puede usar en aplicaciones empresariales. Clojure es un ejemplo de lenguaje FP con éxito en empresas: http://cognitect.com/clojure#successstories

Representar al estado puede ser un desafío en la PF y cambiar los paradigmas para adaptarse a la PF puede ser un poco retorcido. Algunos lenguajes FP no permiten por completo los efectos secundarios y el estado mutable. Clojure permite ambos, pero desalienta o aísla esos paradigmas.

En resumen, la representación estatal puede ser muy similar a OO. La modificación del estado es muy diferente. Así, por ejemplo, en el estado FP puede estar representado por listas y mapas. Una lista de empleados puede verse así:

[[name: "James Brown" address: "Barnwell, SC"]
 [name: "Elvis Presley" address: "Tupelo, MS"]]

Hay dos maneras que conozco para manejar la modificación de estado en FP. Uno es algo así como la programación funcional reactiva. En este paradigma, todo el estado se maneja en el nivel más alto solo ... por ejemplo, una vista HTML de su aplicación tiene estado en la vista (como el nombre de la persona, la dirección, etc.). Ahora, cuando hace clic en "actualizar nombre", se llama a una función que maneja todo lo relacionado con una actualización de nombre, excepto cambiar el nombre. Esto puede sonar extraño ... pero ten paciencia conmigo. La función devolverá el nombre cambiado y la vista (o almacén de datos persistente, etc.) mostrará el nuevo nombre. O, alternativamente, se devolverá una estructura completamente nueva con el nombre actualizado. Entonces, ¿qué hace la función? Valida el nombre y devuelve el nuevo nombre si es válido, un error si no lo es, y posiblemente una nueva vista o enlace de navegación para seguir. Para algo más complejo que un cambio de nombre, puede hacer mucho más.

Entonces, para FRP, el objeto devuelto por la función es el nuevo estado y se puede dar directamente a la vista o lo que sea que esté en el nivel superior. En algunos casos, FRP toma todo el estado, lo pasa a la función y recupera todo el estado.

Con este paradigma, el contenedor o el marco deben manejar la actualización de la pantalla, la base de datos o cualquier otra cosa que necesite actualizarse desde el nuevo estado. Entonces puede imaginar un marco que dibuje la aplicación en la pantalla. Cuando un usuario hace clic en algo, se invocan funciones y se devuelve el nuevo estado. Luego, el marco actualiza la pantalla al volver a dibujar todo o al volver a dibujar de manera inteligente partes de la pantalla. Ver http://blog.getprismatic.com/om-sweet-om-high-functional-frontend-engineering-with-clojurescript-and-react/

Clojure usa el segundo paradigma que he encontrado y es aislar los cambios de estado, pero no necesariamente restringirlos al nivel más alto. Con Clojure, un átomo, agente o referencia debe "retener" todo el estado mutable (a menos que esté utilizando objetos Java para el estado). La forma en que esto funciona es el objeto sostenido o señalado o referenciado (como quiera llamarlo) por el átomo / agente / ref es inmutable, pero el átomo / agente / ref puede cambiar para apuntar a un nuevo objeto. En este caso, utiliza métodos especiales en el átomo / agente / referencia que dicen "actualice el objeto aquí haciendo tal y tal y reasignando el átomo / agente / referencia a un nuevo objeto".

¿Por qué es tan beneficioso que puedas preguntar? Debido a que el objeto inmutable al que hacen referencia estas construcciones de Clojure puede pasarse a una función que hace algo y mientras esa función se está ejecutando, se garantiza que su referencia al objeto no cambia. Es decir, el átomo / agente / ref no se pasa a la función pero se pasa el objeto inmutable al que apuntan. Los átomos, los agentes y los árbitros tienen propiedades especiales que manejan las actualizaciones y la concurrencia de manera segura y parte del lenguaje. Ver http://clojure.org/state

Espero que esto ayude. Sugiero leer más sobre el estado de Clojure y FRP para comprender mejor cómo los empleados y las personas pueden ser representados en FP. Sin embargo, la representación real sería similar a la programación orientada a objetos ... es la mutabilidad lo que es realmente diferente.

Jason
fuente