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