Hi all
I'm designing a simple environment with a bot evolving in a maze. The user can control the bots from a kind of workspace. In an old implementation, I did not use step and put some delay and World doOneCycle. Not so good. I decided to clean that and to use the step method to execute commands sent to this morph.
The morph has a queue of actions (which are reified message sends with a future to hold their result).
For example the method go is implemented as NewBot>>go self addAction: #goPrimitive
this means that when the action is executed the method goPrimitive will be executed which is in fact implemented.
goPrimitive
self position: (self position + (10@10))
addAction: and similar methods are implemented that way: a command object is created and put in the queue and returned.
addAction: aSelector arguments: anArray | anAction | anAction := (BotCommand selector: aSelector arguments: anArray). actionQueue addLast: anAction. ^ anAction
A command object is a message reification that holds a future so that I can get result back to the sender when necessary (for exmaple getter method, as in the following example. result in that case get the future and ask its value.
diamNumber ^ (self addAction: #diamNumberPrimitive) result
The step method goes over the queue and execute the actions one after the other. It then puts the future value
step | action res | ^ actionQueue isEmpty ifFalse: [action := self removeAction. res := self perform: action selector withArguments: action arguments. action setFutureValue: res]
Now I have the following problem that you can try just by loading the cs. If I create a morph NewBot new openInWorld, inspect it and execute self diamNumber in an inspector, the complete environment is blocked.
I simplified the problem to its essence in the attached file. If you open an inspect and evaluate self diamNumber the system freezes. Apparently there is not enough thread in morphic. So I started to see where I could put another thread. The problem is that - in an inspector doing [self diamNumber] fork does not help because I would need another future to get the value form the thread - opening an inspector in another block (self inspect fork) and in this new inspector doing self diamNumber still freezes the system My impression is that the UI scheduler does not let me doing that.
does anybody has an idea of how I could solve that problem?
stef
From: ducasse ducasse@iam.unibe.ch wrote:
<snip>
Now I have the following problem that you can try just by loading the cs. If I create a morph NewBot new openInWorld, inspect it and execute self diamNumber in an inspector, the complete environment is blocked.
I simplified the problem to its essence in the attached file. If you open an inspect and evaluate self diamNumber the system freezes. Apparently there is not enough thread in morphic. So I started to see where I could put another thread. The problem is that
- in an inspector doing [self diamNumber] fork does not help because I
would need another future to get the value form the thread
- opening an inspector in another block (self inspect fork) and in this
new inspector doing self diamNumber still freezes the system My impression is that the UI scheduler does not let me doing that.
I am not convinced that this is the fault of the UI scheduler.
You can try this:
1. In NewBot, add this instance method:
diamNumberPromise ^ (self addAction: #diamNumberPrimitive)
2. Open a Transcript. 3. Evaluate [NewBot new inspect]. An inspector appears. 4. in the evaluation pane of the inspector evaluate this:
| p s | s := Semaphore new. [ p := self diamNumberPromise. s signal. " p has now a value " Transcript show: p result printString; cr] fork. s wait. " wait until p has a value " p inspect
In the Transcript you see that your future is waiting. You get a second inspector, this time for an instance of BotCommand.
5. In the evaluation pane of the inspector for the BotCommand, evaluate:
self setFutureValue: 7
In the transcript, you see the second part of the story: Reception of the value.
I think the problem is simply that, as soon as processes come into play, one has to construct expressions for inspection very carefully.
Greetings, Boris
Hi Stef,
Your problem is that the UI process (which is responsible for invoking #step) waits for the promise to compute its value. However, that promise will only be evaluated upon the next step, which would have to be run via the UI process which blocks on the promise. In short, you have a classic deadlock.
Cheers, - Andreas
----- Original Message ----- From: "ducasse" ducasse@iam.unibe.ch To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Sunday, February 01, 2004 1:52 AM Subject: Multi-thread Question in Morph?
Hi all
I'm designing a simple environment with a bot evolving in a maze. The user can control the bots from a kind of workspace. In an old implementation, I did not use step and put some delay and World doOneCycle. Not so good. I decided to clean that and to use the step method to execute commands sent to this morph.
The morph has a queue of actions (which are reified message sends with a future to hold their result).
For example the method go is implemented as NewBot>>go
self addAction: #goPrimitive
this means that when the action is executed the method goPrimitive will be executed which is in fact implemented.
goPrimitive
self position: (self position + (10@10))
addAction: and similar methods are implemented that way: a command object is created and put in the queue and returned.
addAction: aSelector arguments: anArray
| anAction | anAction := (BotCommand selector: aSelector arguments: anArray). actionQueue addLast: anAction. ^ anAction
A command object is a message reification that holds a future so that I can get result back to the sender when necessary (for exmaple getter method, as in the following example. result in that case get the future and ask its value.
diamNumber
^ (self addAction: #diamNumberPrimitive) result
The step method goes over the queue and execute the actions one after the other. It then puts the future value
step
| action res | ^ actionQueue isEmpty ifFalse: [action := self removeAction. res := self perform: action selector withArguments: action arguments. action setFutureValue: res]
Now I have the following problem that you can try just by loading the cs. If I create a morph NewBot new openInWorld, inspect it and execute self diamNumber in an inspector, the complete environment is blocked.
I simplified the problem to its essence in the attached file. If you open an inspect and evaluate self diamNumber the system freezes. Apparently there is not enough thread in morphic. So I started to see where I could put another thread. The problem is that
- in an inspector doing [self diamNumber] fork does not help because I
would need another future to get the value form the thread
- opening an inspector in another block (self inspect fork) and in this
new inspector doing self diamNumber still freezes the system My impression is that the UI scheduler does not let me doing that.
---------------------------------------------------------------------------- ----
does anybody has an idea of how I could solve that problem?
stef
---------------------------------------------------------------------------- ----
Your problem is that the UI process (which is responsible for invoking #step) waits for the promise to compute its value. However, that promise will only be evaluated upon the next step, which would have to be run via the UI process which blocks on the promise. In short, you have a classic deadlock.
Yes I see that :). Naively I was thinking that Morphic was more concurrent. I was wondering how I can introduce more concurrency in the problem. I'm bit afraid by the idea of forking the stepping mechanism. I will try to see how I can make a workspace that does not create the deadlock and play with the solutions suggested by boris.
I was wondering if other people using Morphic for simulation did not get the same problem
Stef
On 31 janv. 04, at 23:03, Andreas Raab wrote:
Hi Stef,
Cheers,
- Andreas
----- Original Message ----- From: "ducasse" ducasse@iam.unibe.ch To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Sunday, February 01, 2004 1:52 AM Subject: Multi-thread Question in Morph?
Hi all
I'm designing a simple environment with a bot evolving in a maze. The user can control the bots from a kind of workspace. In an old implementation, I did not use step and put some delay and World doOneCycle. Not so good. I decided to clean that and to use the step method to execute commands sent to this morph.
The morph has a queue of actions (which are reified message sends with a future to hold their result).
For example the method go is implemented as NewBot>>go
self addAction: #goPrimitive
this means that when the action is executed the method goPrimitive will be executed which is in fact implemented.
goPrimitive
self position: (self position + (10@10))
addAction: and similar methods are implemented that way: a command object is created and put in the queue and returned.
addAction: aSelector arguments: anArray
| anAction | anAction := (BotCommand selector: aSelector arguments: anArray). actionQueue addLast: anAction. ^ anAction
A command object is a message reification that holds a future so that I can get result back to the sender when necessary (for exmaple getter method, as in the following example. result in that case get the future and ask its value.
diamNumber
^ (self addAction: #diamNumberPrimitive) result
The step method goes over the queue and execute the actions one after the other. It then puts the future value
step
| action res | ^ actionQueue isEmpty ifFalse: [action := self removeAction. res := self perform: action selector withArguments: action arguments. action setFutureValue: res]
Now I have the following problem that you can try just by loading the cs. If I create a morph NewBot new openInWorld, inspect it and execute self diamNumber in an inspector, the complete environment is blocked.
I simplified the problem to its essence in the attached file. If you open an inspect and evaluate self diamNumber the system freezes. Apparently there is not enough thread in morphic. So I started to see where I could put another thread. The problem is that
- in an inspector doing [self diamNumber] fork does not help because I
would need another future to get the value form the thread
- opening an inspector in another block (self inspect fork) and in
this new inspector doing self diamNumber still freezes the system My impression is that the UI scheduler does not let me doing that.
does anybody has an idea of how I could solve that problem?
stef
ducasse ducasse@iam.unibe.ch wrote:
Yes I see that :). Naively I was thinking that Morphic was more concurrent.
I haven't followed the ins and outs, but please notice that Morphic *intentionally* will not call a #step method that is already executing. It waits until the previous execution to finish before calling the next one.
It used to not do this, and if your #step raised an error then you could get cascading pre-debug windows popping up on your screen. Additionally, a major advantage to using #step is that you do not need to handle any synhcronization, because you know that everything is sitting still while you execute. If step was to become reentrant then this would no longer be true.
So, it would be more Morphic-friendly to find some way to set aside a blocked pseudo-process. If one of your bots tries to dereference a promise that is not yet fulfilled, then suspend that bot somehow, and arrange for it to wake back up when the promise is fulfilled.
-Lex
What I do not really understand is why if I fork an inspect still the system get blocked.
- opening an inspector in another block (self inspect fork) and in this new inspector doing self diamNumber still freezes the system
Because this would solve my problem.
On 1 févr. 04, at 00:07, Lex Spoon wrote:
ducasse ducasse@iam.unibe.ch wrote:
Yes I see that :). Naively I was thinking that Morphic was more concurrent.
I haven't followed the ins and outs, but please notice that Morphic *intentionally* will not call a #step method that is already executing. It waits until the previous execution to finish before calling the next one.
It used to not do this, and if your #step raised an error then you could get cascading pre-debug windows popping up on your screen. Additionally, a major advantage to using #step is that you do not need to handle any synhcronization, because you know that everything is sitting still while you execute. If step was to become reentrant then this would no longer be true.
So, it would be more Morphic-friendly to find some way to set aside a blocked pseudo-process. If one of your bots tries to dereference a promise that is not yet fulfilled, then suspend that bot somehow, and arrange for it to wake back up when the promise is fulfilled.
The fun part of it is that I'm doing that do avoid to break morphic by having World doOneCycle
Stef
-Lex
Stef, maybe SqueakElib would provide some ideas. (on SqueakMap) There are plenty of problems unsolved, including the one you are having, but it does allow you to send messages to promises. You could create the BotCommand as an eventual reference then send a #whenResolved: msg to it like so:
addAction: aSelector arguments: anArray
| anAction | anAction := (BotCommand selector: aSelector arguments: anArray). actionQueue addLast: anAction. ^ anAction eventual
and
diamNumber
^ (self addAction: #diamNumberPrimitive)
finally
bot diamNumber whenResolved: [:eNum | transcript show: eNum asString].
or you could inspect the bot and inspect diamNumber, a promise which will #become an eventual reference to the diamNumber result. You could replace the future in the BotCommand with an eventual reference to the BotCommand above. My example here makes the sys double futured in a sense. If you want to wait for the value, send #immediate to the eventual reference. That will block until it resolves.
Now the missing stuff. Evaluating expressions in an inspector on an eventual ref will get screwed up. I think it has something to do with it getting confused about where to compile the DoIt, since there is a double proxy there. It may also have trouble referencing self. Bad inspector, no spyglass and no pipe! Another issue is that #immediate blocks for the resolution, but it doesn't unwrap the eventual reference proxy. I can't recall if I have another msg that does that. All in all the behavior of these things are quite intriguing but my implementation is very complicated and there are big holes. One of the biggest holes is that you can't use an eventual reference as a parameter to a primitive, so I had to hack a bunch of asString methods to even allow the inspector to work. Bad solution - a hack long ago. I think I'd eventually like to see the VM detect primitive args are eventual and basically condition the eval of the primitive on resolution of all args. I think this is creating a continuation on the primitive eval...
sorry for the discombobulated answer. SqueakElib itself is a bit discombobulated.
cheers, Rob
ps. DESPlugins for linux and Windows are at: http://minnow.cc.gatech.edu/squeak/2410 at the very bottom.
Instead of blocking on the future by sending value, On Saturday, January 31, 2004, at 02:57 PM, ducasse wrote:
Your problem is that the UI process (which is responsible for invoking #step) waits for the promise to compute its value. However, that promise will only be evaluated upon the next step, which would have to be run via the UI process which blocks on the promise. In short, you have a classic deadlock.
Yes I see that :). Naively I was thinking that Morphic was more concurrent. I was wondering how I can introduce more concurrency in the problem. I'm bit afraid by the idea of forking the stepping mechanism. I will try to see how I can make a workspace that does not create the deadlock and play with the solutions suggested by boris.
I was wondering if other people using Morphic for simulation did not get the same problem
Stef
On 31 janv. 04, at 23:03, Andreas Raab wrote:
Hi Stef,
Cheers,
- Andreas
----- Original Message ----- From: "ducasse" ducasse@iam.unibe.ch To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Sunday, February 01, 2004 1:52 AM Subject: Multi-thread Question in Morph?
Hi all
I'm designing a simple environment with a bot evolving in a maze. The user can control the bots from a kind of workspace. In an old implementation, I did not use step and put some delay and World doOneCycle. Not so good. I decided to clean that and to use the step method to execute commands sent to this morph.
The morph has a queue of actions (which are reified message sends with a future to hold their result).
For example the method go is implemented as NewBot>>go
self addAction: #goPrimitive
this means that when the action is executed the method goPrimitive will be executed which is in fact implemented.
goPrimitive
self position: (self position + (10@10))
addAction: and similar methods are implemented that way: a command object is created and put in the queue and returned.
addAction: aSelector arguments: anArray
| anAction | anAction := (BotCommand selector: aSelector arguments: anArray). actionQueue addLast: anAction. ^ anAction
A command object is a message reification that holds a future so that I can get result back to the sender when necessary (for exmaple getter method, as in the following example. result in that case get the future and ask its value.
diamNumber
^ (self addAction: #diamNumberPrimitive) result
The step method goes over the queue and execute the actions one after the other. It then puts the future value
step
| action res | ^ actionQueue isEmpty ifFalse: [action := self removeAction. res := self perform: action selector withArguments: action arguments. action setFutureValue: res]
Now I have the following problem that you can try just by loading the cs. If I create a morph NewBot new openInWorld, inspect it and execute self diamNumber in an inspector, the complete environment is blocked.
I simplified the problem to its essence in the attached file. If you open an inspect and evaluate self diamNumber the system freezes. Apparently there is not enough thread in morphic. So I started to see where I could put another thread. The problem is that
- in an inspector doing [self diamNumber] fork does not help because
I would need another future to get the value form the thread
- opening an inspector in another block (self inspect fork) and in
this new inspector doing self diamNumber still freezes the system My impression is that the UI scheduler does not let me doing that.
does anybody has an idea of how I could solve that problem?
stef
I was wondering how I can introduce more concurrency in the problem.
It's not exactly trivial. The essential issue is to decide on what a good default policy for concurrent programming by users is. In my understanding it's simply too hard to constantly deal with locks, critical sections etc. The policy that I ultimately settled upon was simply to define that programs run until they are complete or they block (where blocking is defined as "waiting on external event"). Interestingly, it seems that Scratch is following the same idea which is maybe not so surprising - in the end that's what the stepping policy does, just in a more general way (#step always runs to completion or until it waits for the next #step event).
I will try to see how I can make a workspace that does not create the deadlock and play with the solutions suggested by boris.
The real trick here is that you can't have the "scheduler process" (which organizes the individual steps) do the work since if it does, it will block and thusly fail to organize any other activities. IOW, you need to decouple "step scheduling" from "step evaluation" - once you do that it'll work nicely. Be warned though that getting the scheduling right has a few very subtle implications which aren't obvious at all.
I was wondering if other people using Morphic for simulation did not get the same problem
Well, at least me and John both ran into the problem and came up with very similar solutions ;-)
Cheers, - Andreas
----- Original Message ----- From: "ducasse" ducasse@iam.unibe.ch To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Saturday, January 31, 2004 11:57 PM Subject: Re: Multi-thread Question in Morph?
Your problem is that the UI process (which is responsible for invoking #step) waits for the promise to compute its value. However, that promise will only be evaluated upon the next step, which would have to be run via the UI process which blocks on the promise. In short, you have a classic deadlock.
Yes I see that :). Naively I was thinking that Morphic was more concurrent. I was wondering how I can introduce more concurrency in the problem. I'm bit afraid by the idea of forking the stepping mechanism. I will try to see how I can make a workspace that does not create the deadlock and play with the solutions suggested by boris.
I was wondering if other people using Morphic for simulation did not get the same problem
Stef
On 31 janv. 04, at 23:03, Andreas Raab wrote:
Hi Stef,
Cheers,
- Andreas
----- Original Message ----- From: "ducasse" ducasse@iam.unibe.ch To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Sunday, February 01, 2004 1:52 AM Subject: Multi-thread Question in Morph?
Hi all
I'm designing a simple environment with a bot evolving in a maze. The user can control the bots from a kind of workspace. In an old implementation, I did not use step and put some delay and World doOneCycle. Not so good. I decided to clean that and to use the step method to execute commands sent to this morph.
The morph has a queue of actions (which are reified message sends with a future to hold their result).
For example the method go is implemented as NewBot>>go
self addAction: #goPrimitive
this means that when the action is executed the method goPrimitive will be executed which is in fact implemented.
goPrimitive
self position: (self position + (10@10))
addAction: and similar methods are implemented that way: a command object is created and put in the queue and returned.
addAction: aSelector arguments: anArray
| anAction | anAction := (BotCommand selector: aSelector arguments: anArray). actionQueue addLast: anAction. ^ anAction
A command object is a message reification that holds a future so that I can get result back to the sender when necessary (for exmaple getter method, as in the following example. result in that case get the future and ask its value.
diamNumber
^ (self addAction: #diamNumberPrimitive) result
The step method goes over the queue and execute the actions one after the other. It then puts the future value
step
| action res | ^ actionQueue isEmpty ifFalse: [action := self removeAction. res := self perform: action selector withArguments: action arguments. action setFutureValue: res]
Now I have the following problem that you can try just by loading the cs. If I create a morph NewBot new openInWorld, inspect it and execute self diamNumber in an inspector, the complete environment is blocked.
I simplified the problem to its essence in the attached file. If you open an inspect and evaluate self diamNumber the system freezes. Apparently there is not enough thread in morphic. So I started to see where I could put another thread. The problem is that
- in an inspector doing [self diamNumber] fork does not help because I
would need another future to get the value form the thread
- opening an inspector in another block (self inspect fork) and in
this new inspector doing self diamNumber still freezes the system My impression is that the UI scheduler does not let me doing that.
does anybody has an idea of how I could solve that problem?
stef
I was wondering how I can introduce more concurrency in the problem.
It's not exactly trivial. The essential issue is to decide on what a good default policy for concurrent programming by users is. In my understanding it's simply too hard to constantly deal with locks, critical sections etc. The policy that I ultimately settled upon was simply to define that programs run until they are complete or they block (where blocking is defined as "waiting on external event"). Interestingly, it seems that Scratch is following the same idea which is maybe not so surprising - in the end that's what the stepping policy does, just in a more general way (#step always runs to completion or until it waits for the next #step event).
I see. I was wondering if I was idiot because my problem is quite simple (at least the requirements :)).
I will try to see how I can make a workspace that does not create the deadlock and play with the solutions suggested by boris.
The real trick here is that you can't have the "scheduler process" (which organizes the individual steps) do the work since if it does, it will block and thusly fail to organize any other activities. IOW, you need to decouple "step scheduling" from "step evaluation" - once you do that it'll work nicely.
Yes I felt that too. Trying to thread the evaluation.
Be warned though that getting the scheduling right has a few very subtle implications which aren't obvious at all.
Thanks for the warnings.
I was wondering if other people using Morphic for simulation did not get the same problem
Well, at least me and John both ran into the problem and came up with very similar solutions ;-)
I can understand because what I want is just a bit more than a morph animating itself :). Ok I see. I like the hear that because I not good in concurrency generally but I always fall on non-trivial stuff which confirms to me that we still do not have a good abstraction for concurrency (but may be this is just ebcause this is complex).
Stef
Cheers,
- Andreas
----- Original Message ----- From: "ducasse" ducasse@iam.unibe.ch To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Saturday, January 31, 2004 11:57 PM Subject: Re: Multi-thread Question in Morph?
Your problem is that the UI process (which is responsible for invoking #step) waits for the promise to compute its value. However, that promise will only be evaluated upon the next step, which would have to be run via the UI process which blocks on the promise. In short, you have a classic deadlock.
Yes I see that :). Naively I was thinking that Morphic was more concurrent. I was wondering how I can introduce more concurrency in the problem. I'm bit afraid by the idea of forking the stepping mechanism. I will try to see how I can make a workspace that does not create the deadlock and play with the solutions suggested by boris.
I was wondering if other people using Morphic for simulation did not get the same problem
Stef
On 31 janv. 04, at 23:03, Andreas Raab wrote:
Hi Stef,
Cheers,
- Andreas
----- Original Message ----- From: "ducasse" ducasse@iam.unibe.ch To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Sunday, February 01, 2004 1:52 AM Subject: Multi-thread Question in Morph?
Hi all
I'm designing a simple environment with a bot evolving in a maze. The user can control the bots from a kind of workspace. In an old implementation, I did not use step and put some delay and World doOneCycle. Not so good. I decided to clean that and to use the step method to execute commands sent to this morph.
The morph has a queue of actions (which are reified message sends with a future to hold their result).
For example the method go is implemented as NewBot>>go
self addAction: #goPrimitive
this means that when the action is executed the method goPrimitive will be executed which is in fact implemented.
goPrimitive
self position: (self position + (10@10))
addAction: and similar methods are implemented that way: a command object is created and put in the queue and returned.
addAction: aSelector arguments: anArray
| anAction | anAction := (BotCommand selector: aSelector arguments: anArray). actionQueue addLast: anAction. ^ anAction
A command object is a message reification that holds a future so that I can get result back to the sender when necessary (for exmaple getter method, as in the following example. result in that case get the future and ask its value.
diamNumber
^ (self addAction: #diamNumberPrimitive) result
The step method goes over the queue and execute the actions one after the other. It then puts the future value
step
| action res | ^ actionQueue isEmpty ifFalse: [action := self removeAction. res := self perform: action selector withArguments: action arguments. action setFutureValue: res]
Now I have the following problem that you can try just by loading the cs. If I create a morph NewBot new openInWorld, inspect it and execute self diamNumber in an inspector, the complete environment is blocked.
I simplified the problem to its essence in the attached file. If you open an inspect and evaluate self diamNumber the system freezes. Apparently there is not enough thread in morphic. So I started to see where I could put another thread. The problem is that
- in an inspector doing [self diamNumber] fork does not help
because I would need another future to get the value form the thread
- opening an inspector in another block (self inspect fork) and in
this new inspector doing self diamNumber still freezes the system My impression is that the UI scheduler does not let me doing that.
--
does anybody has an idea of how I could solve that problem?
stef
--
second proposal for a question from: ducasse ducasse@iam.unibe.ch >
does anybody has an idea of how I could solve that problem?
Hi Stef,
playing with this problem is just fun.
Please try also this ( with an open Transcript, otherwise you will not see the trace messages):
1. NewBot new inspect. 2. In the evaluation pane of the inspector evaluate: [self diamNumber] fork inspect.
The future tells you that it is waiting and you get a second inspector, for a process.
3. In the evaluation pane of the new inspector, evaluate:
self suspendedContext receiver value: 9999
suspendedContext answers a MethodContext, receiver answers the Future and that future is the receiver of the value: message.
For this experiment, you do not need an accessor to get the future. This may be seen as an advantage.
When you have an inspector on a BotCommand, you can evaluate the setFutureValue a second time and will get an error notification.
When you have an inspecxtor on a Process, you will not be able to evaluate the
self suspendedContext receiver value: 9999
a seond time because the first evaluation terminated the process, a fact that is also shown in the inspector.
Greetings, Boris
does anybody has an idea of how I could solve that problem?
Hi again Stef,
here is the hopefully ultimate answer (it works only in Morphic. MVC does not evaluate expressions that follow the opening of a view, therefore this will not work in MVC):
1. NewBot new inspect. 2. In the evaluation pane of the inspector evaluate: [ | p pHasValue | pHasValue := Semaphore new. [p := self diamNumber. pHasValue signal.] fork inspect. pHasValue wait. p inspect. ] fork
The future tells you that it is waiting and you get a second inspector, for a process.
3. In the evaluation pane of the new inspector, evaluate:
self suspendedContext receiver value: 9999
The story is continued in the transcript, but, most exciting, you get a third inspector with the value of the future!
Greetings, Boris
squeak-dev@lists.squeakfoundation.org