Reputation: 100
This is sort of a follow up to an earlier question at Scala variable binding when used with Actors
Against others' advice, I decided to make a message containing a closure and mutate the variable that closure is closed under between messages.. and explicitly wait for them. The environment is akka 1.2 on scala 2.9
Consider the following
var minAge = 18
val isAdult = (age: Int) => age >= minAge
println((actor ? answer(19, isAdult)).get)
minAge = 20
println((actor ? answer(19, isAdult)).get)
The message handler for answer essentially applies isAdult to the first parameter (19). When actor is local, I get the answers I expect.
true
false
But when it is remote, I get
false
false
I am simply curious why this would be the behavior? I would have expected consistent behavior between the two..
Thanks in advance!
Upvotes: 3
Views: 176
Reputation: 15472
What you encounter here is what I would call “greediness” of Scala closures: they never close “by-value”, presumably because of the uniform access principle. This means that the closure contains an $outer
reference which it uses to obtain the value of minAge
. You did not give enough context to show what the $outer
looks like in your test, hence I cannot be more precise in how it is serialized, from which would follow why it prints what you show.
One word, though: don’t send closures around like that, please. It is not a recipe for happiness, as you acknowledge yourself.
Upvotes: 2
Reputation: 134340
Well, you have come across what may (or may not) be considered a problem for a system where the behaviour is specified by rules which are not enforced by the language. The same kind of thing happens in Java. Here:
Data d = rmiServer.getSomeData();
d.mutate()
Do you expect the mutation to happen on the server as well? A fundamental issue with any system which involves remote communication, especially when that communication is transparent to a client, is understanding where that communication is occurring and what, exactly, is going on.
Upvotes: 3