What would Squeak be like without non-local returns
Andreas Raab
andreas.raab at gmx.de
Wed Nov 7 08:31:58 UTC 2007
Igor Stasenko wrote:
> On 07/11/2007, Andreas Raab <andreas.raab at gmx.de> wrote:
>> Same answer (though strictly speaking you may get an error that you
>> can't *wait* in an eventual system).
> This doesn't change anything, you may put:
> (1 to: 1000000 atRandom) do: [1+1]
> instead of delay.
Sure. But it makes no difference. I was only pointing this out for
completeness.
> Hmm. An example above was to show that when running in parallel there
> is equal chance to get to ^3 or ^4 first.
No, there isn't. It's simply not how it works. This code cannot run in
parallel because it's on the same island (necessarily so for non-shared
state concurrency since blocks have access to receiver variables) and
can therefore *not* be executed in parallel. The order is completely
deterministic - scheduling the message in the future *guarantees* that
it will be executed only after the ^4 has completed. It can't be any
other way for it to work; if you'd want to run it in parallel you'd need
to copy it to a different island first in which case the return value
from the method would *still* be 4! It's completely deterministic, the
result is 4.
> And in previous message you described behavior, when running code gets
> to ^4 first. But what if it gets to ^3 first?
It cannot. It simply cannot. If you don't understand why, then you don't
fully understand how E and Croquet works. The block is created in the
same island as the receiver. When it is passed to another island (as
argument to the future ifTrue: message) it will be converted into a
remote reference. This reference only understands future messages (all
the immediate messages relate entirely to its role as a reference not
the underlying object) which is the reason why I distinguished these
cases in the True>>ifTrue: code (simply because #value on a remote
reference has no bearing on executing the block that this reference
points to but scheduling a future value message does).
This in turn means that the second island (the one containing the
boolean) *must schedule* the future #value with the first island which
means that the first island will only execute it after the ^4 has been
executed. It is the *only* way in which this can work in an event-loop
environment.
What happens is something like here:
Island A: Island B:
->message starts running
-> aBool future ifTrue:[] ..... -> ..... <schedules True>>ifTrue:>
-> Delay wait
... time passes ...
<at this point Island A is running the message>
<and Island B has the #ifTrue: message scheduled>
-> executes True>>ifTrue:
<schedules aBlock value> ..... <- ..... <- aBlock future value
-> True>>ifTrue: finishes
.... time passes ....
<Island A is still not finished with the delay>
<Island B has posted the eventual #value to Island A>
-> Delay wait ends.
-> message returns 4
-> message completes
<Now, and *only* now the pending #value call will be executed>
-> aBlock value starts
-> Attempts to [^3]
-> Raises BlockCannotReturn
The result is 4. Each and every time.
Cheers,
- Andreas
More information about the Squeak-dev
mailing list
|