2011-12-09 16 views
5

Soy bastante nuevo en Scala. Estoy tratando de comprender cómo/if scala hace el enlace dinámico cuando se pasa un cierre como parte de un mensaje a un Actor.Enlace variable Scala cuando se usa con Actors

Estoy usando Akka 1.2 con Scala 2.9.

I tienen el siguiente segmento de código (modificado de http://gleichmann.wordpress.com/2010/11/15/functional-scala-closures/)

var minAge = 18 
val isAdult = (age: Int) => age >= minAge 

actor ! answer(19, isAdult) 
minAge = 20 
actor ! answer(19, isAdult) 

En el lado actor, simplemente se aplica isAdult al primer parámetro e imprime el resultado. Desde Scala utiliza enlace dinámico (así me dijeron), lo que habría esperado

true 
false 

pero de alguna manera el resultado es

false 
false 

Entonces, ¿es cierto que Scala es vinculante para la variable estática y teniendo 18 como el valor de minAge para ambos mensajes de respuesta? ¿Hay alguna manera de mantener el comportamiento de enlace dinámico al usar cierres en los mensajes?

Gracias!

Respuesta

9

Su comprensión de los cierres es correcta. Está haciendo enlace dinámico sin embargo, está presentando problemas de concurrencia. El cierre se une a datos variables que hacen que el cierre sea mutable. El modelo de actor solo resuelve problemas de concurrencia cuando pasa datos estrictamente inmutables entre los actores. Puede escribirlo en un orden aparentemente cronológico, pero el planificador del actor cambia el orden de los eventos. Y como isAdult es mutable, el reordenamiento cambia los resultados.

actor ! answer(19, isAdult) // message put in actor queue 
minAge = 20 
actor ! answer(19, isAdult) // message put in actor queue 
// later... 
// actor handles answer(19, isAdult) 
// actor handles answer(19, isAdult) 
+0

Gracias! Esto tiene sentido. Así que isAdult se evalúa perezosamente y las variables nunca se enlazan hasta que el actor realmente maneja el mensaje. Parece que si hubiera esperado una respuesta de mi primera consulta antes de ejecutar minAge = 20, obtengo el resultado que esperaba. – royalflush

+2

Eso es correcto, pero recuerde que nunca debe hacer eso ;-) En serio, no estaría utilizando actores si quisiera compartir el estado mutable entre ellos. Desafortunadamente, Scala no proporciona una forma de cerrar "por valor", por lo que lo único que puede hacer es asegurarse manualmente de que todo lo que cierra es un 'val'. –

+0

Creo que ese argumento es cierto en una sola carcasa de máquina. pero con actores remotos, ¿por qué no? ¿Puedo enviar un mensaje para sincronizar un estado distribuido entre dos actores, por ejemplo? – royalflush

Cuestiones relacionadas