user29439
user29439

Reputation:

Monads and Actors

I've been trying to find anything that discusses when you should favor the use of monads over actors (in concurrency scenarios), but I've found nothing. In particular, I'm wondering about the use of the Reactive Extensions (LINQ to Events) vs. F#'s MailboxProcessor. Please give examples in addition to any philosophical reasoning you might have.

Update For better context, the Reactive Extensions implement the continuation monad in the form of IObservable/IObserver. I'm not necessarily saying I have to use F#, just that F# has a concrete "actor model" available in a .NET language in the form of MailboxProcessor<'T>.

What I'm trying to understand is when to use a monad (in this case a continuation monad) vs. an actor model for concurrency purposes. Where the monad (as I understand it) doesn't introduce state, the actor has its own internal state that is modified as necessary to provide protected access.

I've seen a number of examples of using both: Rx and node.js (CPS, not really the continuation monad) vs. F#'s MailboxProcessor and Scala's Akka framework. I just don't know why you would choose one over the other.

Upvotes: 8

Views: 2846

Answers (4)

SemanticBeeng
SemanticBeeng

Reputation: 977

Would you accept answers from the Scala world?

If you seek "a purely functional alternative to actor model" then please see this great post from Paul Chiusano's blog

pchiusano.blogspot.ro/2010/01/actors-are-not-good-concurrency-model.html (archived here: http://archive.is/NxNLc)

and some references below:

http://noelwelsh.com/programming/2013/03/04/why-i-dont-like-akka-actors/

Actors do not Compose Akka’s Actors are not Usefully Typed The type system is the reason we use Scala.

https://opencredo.com/akka-typed/

Unfortunately, the current API suffers from a few drawbacks, which are to a good degree associated with the lack of type safety

http://doc.akka.io/docs/akka/snapshot/scala/typed.html

Status of this Project and Relation to Akka Actors Akka Typed is the result of many years of research and previous attempts (including Typed Channels in the 2.2.x series) and it is on its way to stabilization, but maturing such a profound change to the core concept of Akka will take a long time

A side-effect of this is that behaviors can now be tested in isolation without having to be packaged into an Actor, tests can run fully synchronously without having to worry about timeouts and spurious failures. Another side-effect is that behaviors can nicely be composed and decorated

Composable application architecture with reasonably priced monads

The concept of "function passing style" from Heather Miller might be key to a distributed functional programming model.

SF Scala: Heather Miller, Function-Passing Style, A New Model for Distributed Programming

Update 12/2018 : now we can use Aecor which provide the means to:

  • implement business domain logic with a functional programming model and
  • use an Akka based runtime

"behaviors belong to the domain layer and runtime is out there in the infrastructure layer."

Source: https://pavkin.ru/aecor-part-3/, http://aecor.io

Upvotes: 1

user29439
user29439

Reputation:

I'm going to respond to my own question and say you should use both. This is based on Don Syme's post. A MbP uses the Async computation to do its work, and the Async is a thread-aware continuation monad. Looks like you can use it by itself for some uses, but the MbP definitely requires it.

I don't really like this answer, and I'd be happy for someone to respond with a better explanation of when to use each.

Updated:

See MiniRx, which is now apart of FSharpx, for an implementation of an Rx-style monad implemented using MailboxProcessor. As MailboxProcessor is itself implemented using the async monad, these pieced to indeed work together. They are just different means of abstraction.

Upvotes: 0

kvb
kvb

Reputation: 55185

I'm not sure that the question makes sense as phrased - there are many different monads (e.g. the identity monad, the list monad, the option monad, ...), most of which have nothing to do with concurrency. Furthermore, it would be helpful to know more about the particular scenario that you're dealing with - "concurrency" is a bit of a nebulous topic. Depending on what you're trying to achieve, F#'s async workflows (which are built on the Async monad) might be your best bet.

If you're using F#, I'd recommend against using LINQ-to-anything directly, since those libraries have a very alien feel when accessed via F#. You could, however, create pleasant F# wrappers (such as the existing Seq and Observable modules). Additionally, for monadic types, you could create a computation expression builder (e.g. you could create a builder using the Reactive Extensions which would enable you to use computation expressions to build and compose IObservables).

Upvotes: 4

jdoig
jdoig

Reputation: 1492

Please excuse my newbie-ness as I'm just learning F#.

I'm intrigued to see the use of RX in place of a MailboxProcessor, if you have any links to relevant materials.

With my limited understanding; I would choose MbP's in my own code as events are a bit messy to set up in F# (from what I can take from this article: MSDN). And you need events for RX to hook into right?

Where as with a MbP all I need is a discriminated union of messages, a list of functions I wish to be executed when a given message is received. And the mail box processor that handles this.

This all looks pretty neat in the code. I can bunch my MbP's together in a module then my "object" module looks like

  • Record
  • Message DU
  • Wrapper with some getters and setters that post data to the MbP

For me this looks a lot neater than it would If I wrote my code with events as described in that MSDN article I linked to.

Though I am just an F# junior so I may be a miles off with my reckoning and it is a look-&-feel thing rather than a suitability-for-purpose choice (as I'm not qualified to make that call, yet)

Upvotes: 1

Related Questions