Closures
Closures
¿Cuáles lenguajes tienen ML, Lisp, Perl, Ruby, Python, Javascript, PHP, C++14,
closures? Java8+, C#, Rust, Go, etc.
Closures
Función usada en un ámbito diferente al cual fue definida
Las variables que necesita pueden no estar presentes en el ámbito de uso
El lenguaje debe proveer un mecanismo para que la función acceda a las
variables que necesita
fn function f1() {
¿Cómo hace la función f2
int x;
para acceder a la variable
fn function f2(){ Es necesario “capturar” x
x cuando se ejecute sin
print x; para que f2 pueda
que esté en memoria la
} funcionar correctamente
variable x?
return f2; fuera de f1
};
int main() {
z=f1(); Se está invocando a f2 fuera
z(); de f1
}
Ejemplos de Closures
Rust
fn main() { Se construye un closure que utiliza la
let mut num = 5; variable num
{
let mut add_num = move
|x: i32| num+= x; Ejecución de closure add_num
fn function f1() {
int x=1;
fn function f2(){ f1 f2 / z
x 1
print x;
}
return f2;
}; main La variable x ya no está disponible
z 1
int main() {
z=f1();
…
¿Cómo se captura “x” para que el closure pueda utilizarla?
z();
} ● Por copia ¿Dónde se ubica la copia?
fn main() c1 1000
{ main
let mut c1=f(); y 0
let mut y = 0;
c1(); ● Las variables se capturan por copia.
println!("&c1:{:p}",&c1); ● Las copias se almacenan en el heap y la
println!("c1:{:p}",c1);
println!("&y:{:p}",&y);
variable receptora (en el registro de
} activación de la unidad receptora) es un
puntero
Captura en Lenguajes tipo Algol
Go
package main
import "fmt"
var w int = 1
c1 z 2
func f1() func() { ● Las variables se capturan por
var x int = 2
fmt.Printf("\n &x en f1:",&x);
referencia.
return func() { ● Con este modelo de pila no es
f1
var z int = x x 2 necesario realizar una copia
fmt.Printf("\n &w:",&w);
fmt.Printf("\n &x:",&x); porque el registro de
fmt.Printf("\n &z:",&z); activación donde está la
} c1 $350
} main variable capturada, permanece
y 0 en memoria
func main() {
var c1 = f1();
var y = 0;
c1();
Puntero al código del
fmt.Printf("\n &c1: \n",&c1); closure
fmt.Printf("\n &y: \n",&y);
}
Efectos laterales y sensibilidad a la historia
Go
package main
import "fmt" ¿Qué imprime este programa?
var k int = 1