Should workflows without asynchronous operations be automated in F #?

If I have a parameterless async parameterless workflow in F #, is it necessary and / or idiomatic to make this function, or is it better to leave it as the original value?

For example, if I want to determine whether it getRemoteCounterAfterOneSec

will poll some remote counter source if it should be

let getRemoteCounterAfterOneSec = 
  async {
    do! Async.Sleep 1000
    return! ...
  }

      

or

let getRemoteCounterAfterOneSec () = 
  async {
    do! Async.Sleep 1000
    return! ...
  }

      

It seems that they should be doing the same thing, only the latter has an unnecessary parameter. However, I saw how this was done in two versions of the code. I've also seen places where behavior ends up differently: if you use MailboxProcessor

and do

let myFunc = mailboxProc.PostAndAsyncReply(fun reply -> GetCount reply)
async {
  let! count1 = myFunc
  let! count2 = myFunc
}

      

then the mailbox is processed only once; the second time it just returns the same value computed in the previous call. However, if myFunc

is a function, it calls mailboxProcessor twice as you'd expect.

let myFunc() = mailboxProc.PostAndAsyncReply(fun reply -> GetCount reply)
async {
  let! count1 = myFunc()
  let! count2 = myFunc()
}

      

Is this an implementation bug? What's going on here and what is the idiom?

+3


source to share


1 answer


When it comes to regular async that you define yourself, the addition ()

has no effect (well, it means that the async process that describes the computation is instantiated repeatedly, but it has no practical effect).

I sometimes write this just to make my code clearer or when the async is recursive (because then you get a warning when you have a recursive value). So everything is fine, but this gives you a warning:

let rec loop = 
  async {
    do! Async.Sleep 1000
    if 1 > 2 then return 1
    else return! loop }

      



The method is PostAndAsyncReply

written a little differently - and the name tries to reflect that. Common F # asynchronization methods are called AsyncFooBar

. It has PostAndAsyncFooBar

to indicate that it sends first and then waits asynchronously, something like:

let PostAndAsyncWait () =
  post(message)
  async { let! sth = wait ()
          return sth }

      

So, here it is actually being placed outside of async - this allows you to call the function even if you are (syntactically) outside the block async

. And the name is trying to be very explicit. (But I personally would prefer it to be inside async, i.e. AsyncPostAndWait

).

+2


source







All Articles