[squeak-dev] The Inbox: KernelTests-jr.383.mcz

Jakob Reschke forums.jakob at resfarm.de
Thu Jun 25 06:32:01 UTC 2020

Hi Chris,

I was sometimes confused about this too: future itself does not return
a Promise, but future + the following message send does. This is due
to the compiler transformation explained in FutureNode. So value will
not be sent to the Promise and p will hold the Promise right away and
not be nil.

So, I agree that #future is confusing, but it is also much less to
read than p := Promise new. Project current addDeferredUIMessage:
[[... p resolveWith: ...] ifCurtailed: "or whatever we settle on" [p

I don't think you ever could use Promises and values interchangeably.
Promise>>wait does more or less what you want, but it means you have
to use the promise explicitly, not interchangeably. You can chain
promises with then:[ifRejected:], and consume the Promise outcome in
the respective block argument, turning your control flow from
left-to-right-top-to-down into Promise style... But just getting the
value of the Promise at some point without wait might just answer nil
if still unresolved.

About signalling errors upon #value as you put it: you mean you want
to get the original Exception when you get the result of the promise,
so you don't have to check in which state the promise is? It sounds
useful at first, but the result or reason (for errors) can be
retrieved more than once; would the exception only be signalled
(again) upon the first retrieval of the result? Also it would look
funny in the Debugger stack: either you put the original stack of the
exception on top of the current (result getting) one, or you hide the
current stack, or you cut away the sender of the exception context
(which makes it less useful). Do you have an idea how to resolve this?

Also note that you can reject a promise with something else than an
Exception. It could also be some kind of error value or just a string
that explains the rejection. You would not be able to distinguish that
from a regular result without type checking. Maybe we could have a
specialized promise that only rejects on exceptions and would allow
the kind of workflow you seem to have in mind where the promise is
like a proxy for the result. If we determine that it is useful. :-)

Kind regards,

Am Do., 25. Juni 2020 um 02:55 Uhr schrieb Chris Muller <asqueaker at gmail.com>:
> Hi Jakob,
> Unrelated to your concern about Notifications, I notice the test assigns p to the result of sending #value to the Promise, which will very possibly still be nil at that point, even though it then goes on to test it against #isResolved and #isRejected right afterward.
> I find the impedance mismatch between values and Promises of values confusing, too, -- afterall, I thought the purpose was to be able to use them interchangeably.  Equally, I wish 'error' were always some kind of Exception, and would signal it when #value (wait) was sent instead of exposing Promises by forcing clients to ask, #isRejected?  #isResolved?
>  - Chris
> On Sun, Jun 21, 2020 at 12:46 PM Jakob Reschke <forums.jakob at resfarm.de> wrote:
>> I am trying to come up with a nice solution for this failing test.
>> Am So., 21. Juni 2020 um 19:27 Uhr schrieb <commits at source.squeak.org>:
>> >
>> > A new version of KernelTests was added to project The Inbox:
>> > http://source.squeak.org/inbox/KernelTests-jr.383.mcz
>> >
>> > ==================== Summary ====================
>> >
>> > Name: KernelTests-jr.383
>> > Author: jr
>> > Time: 21 June 2020, 7:27:47.560506 pm
>> > UUID: ecddb3cb-25c9-6c43-a879-59e527a3a9ee
>> > Ancestors: KernelTests-tonyg.382
>> >
>> > Test whether Notifications reject the promises of future sends
>> >
>> > In my opinion, they should not.
>> >
>> > =============== Diff against KernelTests-tonyg.382 ===============
>> >
>> > Item was added:
>> > + ----- Method: PromiseTest>>testFutureResolutionWithNotification (in category 'tests - future') -----
>> > + testFutureResolutionWithNotification
>> > +       | p |
>> > +       p := [Notification signal: 'should not reject'. 3 + 4] future value.
>> > +       self assert: (self waitUntil: [p isResolved or: [p isRejected]] orCycleCount: 100).
>> > +       self assert: p isResolved.
>> > +       self assert: 7 equals: p value.!
>> >
>> >

More information about the Squeak-dev mailing list