open System
open System.Threading
open Hopac
open Hopac.Infixes
let hello what = job {
for i=1 to 3 do
do! timeOut (TimeSpan.FromSeconds 1.0)
do printfn "%s" what
}
run <| job {
let! j1 = Promise.start (hello "Hello, from a job!")
do! timeOut (TimeSpan.FromSeconds 0.5)
let! j2 = Promise.start (hello "Hello, from another job!")
//do! Promise.read j1
//do! Promise.read j2
return ()
}
Console.ReadKey()
Hello, from a job!
Hello, from another job!
Hello, from a job!
Hello, from another job!
Hello, from a job!
Hello, from another job!
This is one of the examples from the Hopac documentation. From what I can see here, even if I do not explicitly call Promise.read j1
or Promise.read j2
the functions still get run. I am wondering if it is possible to defer doing the promised computation until they are actually run? Or should I be using lazy
for the purpose of propagating lazy values?
Looking at the documentation, it does seem like Hopac's promises are supposed to be lazy, but I am not sure how this laziness is supposed to be manifested.
For a demonstration of laziness, consider the following example.
Had the values not been memoized, every time the enter is pressed, there would be two
Hello
s printed per iteration. This behavior can be seen ifmemo <|
is removed.There are some further points worth making. The purpose of
Promise.start
is not specifically to get memoizing behavior for some job.Promise.start
is similar toJob.start
in that if you bind a value usinglet!
or>>=
for example, it won't block the workflow until work is done. However compared toJob.start
,Promise.start
does give an option to wait for the scheduled job to be finished by binding on the nested value. And unlikeJob.start
and similarly to regular .NET tasks, it is possible to extract the value from a concurrent job started usingPromise.start
.Lastly, here is an interesting tidbit I've discovered while playing with promises. It turns out, a good way of turning a
Job
into anAlt
is to turn it into anPromise
first and then upcast it.Uncommenting that first case would cause the program to block forever, but if you memoize the expression first that it is possible to get what would be backtracking behavior had the regular alternatives been used.