Esta cita del artículo de paquetes de un buen número de malentendidos en fragmento de una frase:
[...] que permitirá crear unidades de trabajo, que cada uno tiene su propia copia de la pila , y no pise el cada dedos del pie como resultado.
Esto generalmente no es cierto para los idiomas con cierres.
En primer lugar, más a menudo tienen referencias a la pila, no copias, en aras de la eficiencia. Y en la mayoría de los idiomas, puede modificar cosas a través de una referencia. Entonces, en esos idiomas, esta característica no proporciona una forma de aislar unidades de trabajo. En todo caso, puede hacerlo más confuso.
En segundo lugar, en la mayoría de los idiomas (cuerdos) puede consultar todo lo que encierra léxicamente una función local. No puedes referirte a cualquier cosa en cualquier lugar de la pila. Por ejemplo, no puede profundizar en las variables locales de la función que llamó a la función que llamó a la función ... etc. Solo puede acceder a las variables/parámetros de funciones declaradas localmente, cuyo texto incluye el texto en el que se produce el uso. Además, las variables locales y los parámetros ("en la pila") no son las únicas cosas que pueden estar encubriendo léxicamente una función. Entonces, "la pila" es el concepto incorrecto para invocar aquí.
Java es un ejemplo de un lenguaje que solo puede tomar copias de variables locales y parámetros en sus cierres de "clase interna anónima". Sin embargo, aún tomará una referencia en el caso de la referencia this
de la clase externa.
Y en el caso de cerrar sobre this
, la clase interna ahora almacenará una referencia implícita a la clase externa - nada que ver con la pila, realmente.
La situación es similar en C#, excepto que las variables locales y los parámetros se capturan por referencia en lugar de copiarse.
var counter = 0;
Repeat(10,() => counter++);
Supongamos Repeat
es una función de biblioteca que comienza otro hilo y ahora va a llamar a la Action
lambda le pasa cada 10 milisegundos. ¡Con suerte puede ver cómo esta es una forma muy concisa de crear condiciones de carrera!
El único tipo de lenguaje que evitaría este problema sería un lenguaje funcional puro tal como Haskell, pero eso no sería debido a los cierres - claramente - pero en su lugar debido al hecho de que nunca se puede modificar cualquier compartida estado. (Y Haskell todavía no evitaría el problema por completo, la mayoría del software real tiene que interactuar con un estado compartido externo al programa en algún momento, y la biblioteca estándar de Haskell tiene una forma de hacerlo).
Parece que el artículo está cambiando la definición de cierres para que signifique algo más allá de lo que estoy acostumbrado a que signifique. –