haskell - programacion - ¿Son los cierres una violación del paradigma de la programación funcional?
programacion funcional ventajas y desventajas (4)
Programación funcional "evita datos de estado y mutables".
Los cierres ocultan el estado al vincular su entorno léxico y, por lo tanto, se cierran sobre sus variables libres.
¿Cómo es Haskell puramente funcional si soporta cierres? ¿No rompen la transparencia referencial?
La definición de "programación funcional" de mi hombre de trabajo es que si metes lo mismo (s), siempre sacas lo mismo (s).
Los cierres no violan esta definición en Haskell (trate de encontrar un cierre que sí lo haga :)), por lo tanto, los cierres no violan el paradigma de PF.
Los cierres no son una violación porque todos los enlaces en Haskell son inmutables. Lo que realmente significan los cierres es que un lambda con variables libres no denota una función única; Denotará diferentes funciones dependiendo de los enlaces que estén vigentes para sus variables libres cada vez que se evalúe. P.ej:
makeClosure :: Num a => a -> a -> a
makeClosure x = /y -> x+y
La expresión makeClosure 5
evalúa como una función diferente a makeClosure 6
; y mucho más importante, dos apariciones de makeClosure 5
en diferentes partes del programa evalúan la misma función , al igual que makeClosure (2+3)
o similar; es decir, tenemos transparencia referencial (al sustituir expresiones con sus iguales se conserva el significado de un programa).
Parece que estás confundido sobre el significado de "estado" en la cita que mencionas. Estado en este contexto significa datos mutables; los cierres definitivamente pueden "ocultar" datos, pero en Haskell estos datos no son mutables, por lo que no ocultan el estado. En contraste con esto, en mi experiencia, los programadores de Java a menudo dicen que una instancia de clase "oculta el estado" en los casos en que los datos en cuestión no son mutables, por ejemplo, asignados a un campo de instancia private final
del constructor; lo que realmente quieren decir es que las clases (y los cierres) encapsulan datos.
No, los cierres están bien y no causan problemas en Haskell porque un cierre se cierra sobre los valores de las variables libres. La razón por la que puede ocultar el estado detrás de los cierres en otros idiomas es que cierra sobre la referencia . Como ustedes saben, en Javascript:
var x = 1;
var f = function(y) { return y + x; }
f(2) // => 3
x = 2;
f(2) // => 4
Puedes modelar esto usando IORef
s en Haskell:
main = do
x <- newIORef 1
let f y = do x'' <- readIORef x
return (y + x'')
r1 <- f 2
writeIORef x 2
r2 <- f 2
Esto está bien porque la función f
tiene el tipo Int -> IO Int
lugar de Int -> Int
. En otras palabras, f
está vinculado a la misma acción, pero cuando se ejecuta esa misma acción puede devolver resultados diferentes cada vez.
En Haskell, los cierres tienen variables libres de la misma manera que en matemáticas puedes escribir fx = x^2
, no muta el estado.
Yo diría que Haskell evita el estado mutable .