Hi Peter, It struck me that I should clarify something I said, that probably misled you.
Rob Withers wrote:
That's a nice example. The difference with E's promises is that a Promise doesn't block for value, it sends the new msg eventually and returns a second promise. The way I have this implemented in SqueakElib, is you send #eventual to get an eventual ref, then you can send a msg to the eventual ref, returning a promise, which you can then send a second msg to, returning a second promise.
| promise1 promise2 | promise1 := anObject eventual foo. promise2 := promise1 bar. promise1 whenResolved: [:val | Transcript show: ' foo: ', val printString]. promise2 whenResolved: [:val | Transcript show: ' bar: ', val printString]. Transcript show: 'sent foo bar...'
This prevents deadlocks.
From the first paragraph, I talk about both E and SqueakElib. When I make
this claim about eventual refs and promises preventing deadlocks, I mean it does this for E, not for SqueakElib. Since E processes msg sends in an event-loop, they have no Processes nor Semaphores. Since they restrict scope when compiling and executing code, so you can't even reference them. There is no way to block in E.
This is what I aspire to with SqueakElib but it won't make it, except perhaps in a very constrained environment, namely a restricted scope Island. An Island that likewise does not include Processes nor Semaphore (nor lots of other stuff that may use them, internally). In the general case, which I am interested in, I want to integrate refs and promises in the general image, with its Processes and Semaphores. I may need to block for immediate values, processing primitives with promises and processing method contexts which include promises with multiple points of return. I am going to be blocking and I make, or I intent to make, no claim that I don't block.
Sorry for the confusion, Rob