¿Podemos decir que el cierre de una función es guardar un estado en una función, y cada vez que asignamos un nuevo estado a la función, resultará en una nueva función?
En la siguiente función llamada inc en Scala se realiza una operación de incremento.
def inc(more:Int) = {
def helper(x:Int) = x+more
helper _
}
Cuando se llama a la función inc, devuelve otra función que enlaza el argumento que se le pasa. Por ejemplo, inc(1) devolverá otra función de tipo Int => Int donde la variable more está enlazada con 1.
inc(1) // Esto es de tipo Int => Int
¿Podemos decir que more es una variable de estado para la función devuelta y cuando llamamos a inc(1), entonces se asigna 1 a more?
Aquí hay algunas explicaciones más.
Como vengo del paradigma de programación OO, cuando digo estado, lo relacioné con la instancia de una clase, que en un momento dado tiene un estado particular. Consideremos primero una clase en Java llamada IncHelper como sigue:
class IncHelper{
private int more;
public IncHelper(int more){
this.more = more;
}
public int inc(int x){
return x+this.more;
}
}
Si creo diferentes instancias de la clase anterior como sigue:
IncHelper inc1 = new IncHelper(1);
// Esta instancia siempre aumentará un valor en 1
inc1.inc(10); // la salida será 11
Si creo diferentes instancias de la clase anterior como sigue:
IncHelper inc2 = new IncHelper(2);
// Esta instancia siempre aumentará un valor en 2
inc2.inc(10); // la salida será 12
Entonces, en los dos escenarios anteriores, las dos instancias inc1 e inc2 contienen diferentes valores para las variables de estado. Y lo mismo es cierto para el ejemplo que he dado para la programación funcional de Scala:
val inc1 = inc(1)
inc1(10) // Devolverá 11
Si creo otro valor como sigue:
val inc2 = inc(2)
inc2(10) // Devolverá 12
Entonces, en ambos casos, es decir, en la programación OO cuando he creado 2 instancias de IncHelper, recuerda la variable que se pasa mientras se construye. De la misma manera, es cierto para los dos literales de función que hemos creado, donde las dos variables pasadas al crear los literales de función inc1 e inc2 han almacenado los valores.
davy.ai
Sí, se puede decir que
more
es una variable de estado para la función devuelta y cuando llamamos ainc(1)
se le asigna 1 amore
. Esto se debe a quemore
está siendo capturado por la función internahelper
y devuelto como un cierre. El cierre devuelto tiene acceso al valor demore
desde su alcance circundante.En la programación orientada a objetos, típicamente asociamos el estado con el estado interno de un objeto. En el ejemplo dado, tenemos una clase
IncHelper
que tiene una variable de instanciamore
, que representa su estado interno. Cada instancia de la claseIncHelper
tiene su propia copia demore
, que puede ser diferente de otras instancias.De manera similar, en la programación funcional, los cierres pueden capturar variables desde su alcance circundante, que pueden considerarse su estado interno. Cada cierre puede tener su propia copia de las variables capturadas, que puede ser diferente de otros cierres creados con la misma definición de función.
Por lo tanto, podemos pensar en
more
como el estado interno del cierre devuelto por la funcióninc
, que se pasa como argumento y se utiliza en la operación de incremento.