Returning a value from a future computation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Returning a value from a future computation

vinref

Hi

Here is an attempt to get a value from a future computation:

| a |
p := (EsPromise async future then: [ a := 5 factorial ]) complete: nil.

(Delay forSeconds: 5) wait.
p isComplete and: [ a isNil ]

The whole thing evaluates to true so a is nil. How do I get a value from a future computation?

Vince

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/308b8d9e-efac-46c9-90ca-4ae084af1e76n%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Returning a value from a future computation

vinref
This works as expected:

| a |

[ a := 5 factorial ] fork.
(Delay forSeconds: 5) wait.
a

So then next questions is, what are the recommendations around when to use Futures and Promises, and when to just stick to forks and callbacks?

Vince

On Wednesday, 28 April 2021 at 10:47:53 UTC+10 [hidden email] wrote:

Hi

Here is an attempt to get a value from a future computation:

| a |
p := (EsPromise async future then: [ a := 5 factorial ]) complete: nil.

(Delay forSeconds: 5) wait.
p isComplete and: [ a isNil ]

The whole thing evaluates to true so a is nil. How do I get a value from a future computation?

Vince

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/6d1d83de-b5cc-4863-8261-44ae60315ff7n%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Returning a value from a future computation

Seth Berman
Hi Vince,

Futures
A Future represents the completion of a computation.
computeFactorial := EsFuture on: [5 factorial].

You then chain together more tasks using #then:
Maybe in this example, after you have computed a factorial, then add 3 to the result.
computedFactorialPlus3 := computeFactorial then: [:factorial | factorial + 3].

You can keep going on and on, chaining together futures for complicated workflows, which is a heck of a lot nicer than lots of forks, semaphores and callback hell...especially when it involves exception handling.
Even more advanced usage such as the EsFuture class>>all: and EsFuture class>>any: is worth trying out.

Exception handling is another big win with the async framework.
There are also equivalents to the ensure: [] block as well.
Try the following.
future := EsFuture on: [Exception signal: 'Uh-oh'].
handledEx := future then: ["I never make it here"] catch: [:ex :st | ex inspect. st inspect].
complete := handledEx ensure: [Transcript show: 'I have finished'].

It's generally frowned on to add synchronous code to these workflows.  That is why in Dart (from which this EsFuture/EsPromise framework was ported) it has no analog to blocking on waiting for a future completion.
However, I found it was necessary in the VAST environment, so I added it.  You can add #waitFor to any future, and the current smalltalk process will block until its completed and answer the completion result of the future.
[complete waitFor.]

Promises
Promises are a great way to take synchronous code and create an asynchronous interface to it.  Its usually used by the implementor side of the house.
In fact, I recently did an async version of SstHttpClient by subclassing it and using promises to create an async interface that returned futures and didnt' block.

| future promise |
promise := EsPromise new.
future := promise future.
future then: [:number | number inspect].
promise complete: 42.

The big win from these frameworks are with I/O.
When network and disk I/O is in involved, the asynchronous framework can help make your code dramatically more efficient.
The examples shown above don't really do it justice, but they are just simple examples.
A nicer example might do something like wrap an SstHttpClient fetch with it.
Something like
(EsFuture on: [SstHttpClient fetch: 'https://www.instantiations.com'])
     then: [:response | response inspect]

Be sure to read the method and class comments carefully.  I tried to bring all the commenting over from Dart, and made the necessary
Smalltalk changes.

Let me know what other specific questions you have beyond these and I'll try and help.  It is getting a little late for me so I was trying to keep it short for tonight:)

- Seth
On Tuesday, April 27, 2021 at 8:53:04 PM UTC-4 [hidden email] wrote:
This works as expected:

| a |

[ a := 5 factorial ] fork.
(Delay forSeconds: 5) wait.
a

So then next questions is, what are the recommendations around when to use Futures and Promises, and when to just stick to forks and callbacks?

Vince

On Wednesday, 28 April 2021 at 10:47:53 UTC+10 [hidden email] wrote:

Hi

Here is an attempt to get a value from a future computation:

| a |
p := (EsPromise async future then: [ a := 5 factorial ]) complete: nil.

(Delay forSeconds: 5) wait.
p isComplete and: [ a isNil ]

The whole thing evaluates to true so a is nil. How do I get a value from a future computation?

Vince

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/fe8c8343-bf3a-4409-83da-d420fa2d6b20n%40googlegroups.com.