2012-02-29 19 views
5

me he dado cuenta de que hay ciertos conceptos básicos que una gran cantidad de fanáticos de programación funcional se aferran a:¿Por qué es buena la programación funcional?

  • Evitar estado

  • Evitar los datos mutables

  • se minimizan los efectos secundarios

  • etc ...

No me pregunto qué otras cosas hacen la programación funcional, pero ¿por qué estas ideas centrales son buenas? ¿Por qué es bueno evitar el estado y el resto?

Respuesta

11

La respuesta simple es que si no tiene un estado extra del que preocuparse, es más fácil razonar sobre su código. Un código más simple es más fácil de mantener. No necesita preocuparse por cosas que están fuera de un código en particular (como una función) para modificarlo. Esto tiene ramificaciones realmente útiles para cosas como las pruebas. Si su código no depende de algún estado, es mucho más fácil crear pruebas automatizadas para ese código, ya que no necesita preocuparse por la inicialización de algún estado.

Tener un código sin estado hace que sea más fácil crear programas con subprocesos también, ya que no tiene que preocuparse por dos subprocesos de ejecución que modifican/leen un fragmento compartido de datos al mismo tiempo. Sus hilos pueden ejecutar código independiente, y esto puede ahorrar mucho tiempo de desarrollo.

Esencialmente, evitar el estado crea programas más simples. En cierto modo, hay menos "partes móviles" (es decir, formas en que las líneas de código pueden interactuar), por lo que esto generalmente significará que el código es más confiable y contiene menos fallas. Básicamente, cuanto más simple es el código, menos puede salir mal. Para mí, esta es la esencia de escribir código sin estado.

Hay muchas otras razones para crear código "funcional" sin estado, pero todas se reducen a la simplicidad para mí.

+1

¿Debería mencionarse que la concurrencia es más fácil de hacer correctamente? – ebaxt

+0

Sí, agregó eso. Gracias. :) – Oleksi

+0

+1. Bien dicho, Oleksi. –

5

Además de lo que dice @Oleksi, hay otra cosa importante: transparencia referencial y estructuras de datos transaccionales. Por supuesto, no necesita un lenguaje de programación funcional para hacerlo, pero es un poco más fácil con ellos.

Purely functional data structures se garantiza que permanecerán iguales; si una función devuelve un árbol, siempre será el mismo árbol, y todas las transformaciones posteriores crearán nuevas copias de la misma. Es mucho más fácil retroceder a cualquier versión anterior de una estructura de datos de esta manera, lo cual es importante para muchos algoritmos esenciales.

5

muy general, la programación funcional significa:

  • fomentar el uso de las funciones (primera clase)
  • desalentar el uso de estado (mutable)

¿Por qué es la mutación de un problema? Piénselo: la mutación es para las estructuras de datos lo que es controlar el flujo. Es decir, le permite "saltar" arbitrariamente a algo completamente diferente de una manera no estructurada. En consecuencia, ocasionalmente es útil, pero la mayoría de las veces bastante perjudicial para la legibilidad, la capacidad de prueba y la composicionalidad.

+1

+1 para comparar el estado mutable con goto! – Ingo

2

Una característica característica típica es "sin subtipado".Aunque suena un poco extraño para llamar a esto una característica, que es, por dos razones (de alguna manera relacionadas):

  • relaciones de subtipificación conducen a un montón de problemas no tan obvias. Si no te limitas a la herencia individual o mixin, terminas con el problema del diamante. Más importante es que tiene que lidiar con la varianza (covarianza, contravarianza, invarianza), que rápidamente se convierte en una pesadilla, especialmente para los parámetros de tipo (por ejemplo, genéricos). Existen varias razones más, e incluso en los lenguajes OO, se oyen afirmaciones como "prefieren la composición sobre la herencia".
  • Por otro lado, si simplemente omite el subtipado, puede razonar mucho más detalladamente sobre su sistema de tipo, lo que permite la inferencia de tipo (casi) completo, generalmente implementado con extensiones de inferencia tipo Hindley Milner.

Por supuesto, a veces lo echará de subtipos, pero lenguajes como Haskell han encontrado una buena respuesta a ese problema: el tipo clases, que permiten definir una especie de "interfaz" común (o "conjunto de operaciones comunes") para varios tipos que de otro modo no estarían relacionados. La diferencia con los lenguajes OO es que las clases de tipos se pueden definir "después", sin tocar las definiciones de tipo originales. Resulta que puede hacer casi todo con clases de tipo que puede hacer con subtipado, pero de una manera mucho más flexible (y sin evitar la inferencia de tipo). Es por eso que otros lenguajes comienzan a emplear mecanismos similares (por ejemplo, conversiones implícitas en Scala o métodos de extensión en C# y Java 8)

Cuestiones relacionadas