Esta es una pregunta teórica, pero después de muchos años de programación en lo que ahora me doy cuenta es una técnica imperativa "normal", usando C ++ principalmente, descubrí este otro mundo de programación funcional, que me topé accidentalmente mientras aprendía JavaScript de manera casual.
Esto me ha llevado a preguntarme si técnicamente podría reemplazar cualquier programa completo orientado al estado con una implementación diferente que sea puramente funcional y sin estado.
Es una idea intrigante y debo admitir que hay una claridad y elegancia en la programación funcional que realmente me ha sorprendido.
Respuestas:
Respuesta corta: sí. Según Wikipedia, Alan Turing demostró la equivalencia del cálculo lambda con las máquinas de Turing como modelo universal de cálculo en 1937. El modelo computacional de una máquina de Turing es lo que normalmente tiene en mente cuando habla de programación imperativa o con estado, y el cálculo lambda es una formalización matemática de la "programación funcional pura".
Se calcula que todo modelo efectivo de computación puede realizar los mismos cálculos que una máquina de Turing, y viceversa. Esto se llama tesis de Church-Turing . Sin embargo, esta conjetura no se puede probar debido al término más o menos intuitivo "modelo efectivo de cómputo" (¿tal vez alguien inventará un nuevo modelo en el futuro?)
fuente
En cualquier sistema dinámico, el "estado" es lo que hace que su presente sea influenciado por su pasado o futuro (la flecha del tiempo no es un problema matemático, solo una restricción física).
Si tiene algo que "recordar" o que depende de lo que hizo, tiene un estado.
Un sistema sin estado no es "dinámico": es solo una función combinatoria. Es posible que eso no tenga un estado, pero, para producir resultados diferentes, necesita un estado que se suministre de alguna manera.
Ahora, dependiendo del modelo computacional al que se refiera, un estado puede representarse explícitamente (en forma de variable) o implícitamente (en forma de "direcciones de retorno").
cuando lo haces,
fna(fnb(x))
estás dando un estado a fnb que a su vez producirá un estado para fna. Esto se debe al hecho de quex
existe antes de que se llame fnb (por lo tanto, proviene de su propio "pasado").No es una cuestión de "estado existente" o "estado no existe". Es una cuestión de "me importa" o "no me importa".
fuente
Estado significa la capacidad de responder a un estímulo presente de una manera que depende de estímulos pasados, no solo en función del estímulo presente.
Los programas puramente funcionales son solo funciones. Por lo tanto, para aplicaciones prácticas, el programa puramente funcional ingresa un par (old_state * present_stimulus) y genera un par (new_state * present_response). Se necesita un "bucle" externo con estado para esperar el próximo estímulo y propagar el estado.
Un programa puramente funcional no tiene un estado intrínseco y no puede usarse directamente para aplicaciones prácticas.
Por lo tanto, ningún programa orientado al estado puede ser reemplazado por una implementación diferente que sea puramente funcional y sin estado.
fuente
Puede evitar el estado mutable explícito siempre que no tenga que interactuar con el mundo exterior.
En JavaScript para que su programa realmente tenga un efecto más allá de tomar ciclos de procesador, debe modificar el objeto Dom o Window, y estas API tienen estado. Pero supongo que podría crear un contenedor que pasara los objetos Dom y Window como parámetros al código JavaScript, y luego recibiera un nuevo Dom / Window como salida. Esto aislaría el código JavaScript del estado mutable.
Por supuesto, todavía depende del estado, ya que la ventana del navegador y el DOM tienen estado por naturaleza. Cualquier aplicación interactiva es inherentemente con estado, pero aún puede estructurar su código de manera tal que minimice el estado explícito.
Una pregunta diferente es si es una buena idea. Incluso Haskell, que es un lenguaje funcional puro por diseño, incluye la mónada 'estado', que le permite simular un estado mutable. Esto muestra que el estado mutable explícito a veces es realmente un patrón deseable.
fuente
Piense en cómo implementaría una "máquina de estado" en un lenguaje de programación sin estado.
Probablemente podría hacerlo, pero terminaría usando nombres de funciones como almacenamiento. Terminando con gobblyday gook como:
fuente