Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# MailboxProcessor and Functional Design

If state is regarded as a bad idea for functions why is it regarded as okay have a state when you use a MailboxProcessor?

To expand, I was explaining functional programming to someone, how functions don't use state (no variables outside the function - i.e. same data out for same data in) and the good things that this brings. But then I got thinking about MailboxProcessor and the way it uses recursion to persist state between function calls, and I can't quite reconcile why it's okay in that situation.

Is it a case of it being the least bad way of persisting state?

like image 454
Fsharp Pete Avatar asked Apr 09 '14 13:04

Fsharp Pete


1 Answers

The evil really is shared mutable state. In single-threaded case, shared mutable state means that functions cannot be safely composed - because one call can modify some state which is then read by a second call and so you'll get unexpected results. In multi-threaded case, shared mutable state means that you have potential for race conditions.

Functional programming generally avoids mutation. Functions can still share some state (e.g. closure can capture a state), but it cannot be mutated. In single-threaded case, there is also no non-determinism. In multi-threaded case, pretty much the only thing that you can do in pure functional style is to do fork-join parallelism (and data-parallelism) which does not need mutable state and is fully deterministic.

Agent-based programming also avoids shared mutable state, but in a different way. You have isolated agents that can only share immutable messages. So there is some non-determinism (because they communicate by sending messages), but they only exchange immutable values. In fact, you can even use mutable state inside an agent - as long as it is not shared, you still avoid shared mutable state.

like image 111
Tomas Petricek Avatar answered Nov 15 '22 07:11

Tomas Petricek