Why use a recursive function rather than `while true do` in F#?

  • A+

Whilst watching a Pluralsight course by Tomas Petricek (who I assume knows what he is talking about), I saw code like the following...

let echo =   MailboxProcessor<string>.Start(fun inbox ->     async {       while do true         let! msg = inbox.Receive()     printfn "Hello %s" msg     }) 

Ignore the fact that this was to demo agents, I'm interested in the inner function, which uses while do true to keep it running indefinitely.

Whilst looking around for other example of agents, I saw that many other people use code like this...

let counter =   MailboxProcessor.Start(fun inbox ->     let rec loop n =       async { do printfn "n = %d, waiting..." n         let! msg = inbox.Receive()         return! loop(n+msg) }     loop 0) 

Code copied from Wikibooks.

The inner function here is recursive, and is started off by calling it with a base value before the main function declaration ends.

Now I realise that in the second case recursion is a handy way of passing a private value to the inner function without having to use a mutable local value, but is there any other reason to use recursion here rather than while do true? Would there be any benefit in writing the first code snippet using recursion?

I find the non-recursive version much easier to read (subjective opinion of course), which seems like a good reason to use that whenever possible.

Talking about MailboxProcessor specifically, I think the choice depends on what exactly you are doing. In general, you can always use while loop or recursion.

Recursion makes it easier to use immutable state and I find while loop nicer if you have no state or if you use mutable state. Using mutable state is often quite useful, because MailboxProcessor protects you from concurrent accesses and you can keep the state local, so things like Dictionary (efficient hash table) are often useful.

In general:

  • If you don't need any state, I would prefer while
  • If you have mutable state (like Dictionary or ResizeArray), I'd go for while
  • If you have some immutable state (like functional list or an integer), then recursion is nicer
  • If your logic switches between multiple modes of operation then you can write it as two mutually recursive functions, which is not doable nicely with loops.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: