{{announcement.body}}
{{announcement.title}}

# Inverting Functions: Effect Thread Binding for Stateless Actors

DZone 's Guide to

# Inverting Functions: Effect Thread Binding for Stateless Actors

### Functional programming can be tough. Learn how to easily implement effective thread binding for stateless Actors in Scala.

· Java Zone ·
Free Resource

Comment (1)

Save
{{ articles[0].views | formatCount}} Views

Functional programming can be perceived as "hard." Yes, spend time with it and it gets simpler — the benefits outweigh the learning curve. However, when type errors start spanning multiple lines, it does suggest that abstract concepts may be "hard" to see clearly.

You may also like:  Getting Started With Akka: Actors in a Nutshell

We really need to make it easier for junior developers to assist in functional programming of larger systems.

Now, as functional programming pulls heavily on mathematics, I look to a prominent mathematician's early 1800's statement regarding getting better clarity on hard problems:

"Invert, always Invert" — Mathematician Carl Jacobi

(Though he was German, so it was actually: "man muss immer umkehren.")

What I understand Carl Jacobi was saying is that invert the problem for a different perspective to try and get an answer. Therefore, maybe in inverting functional programming, we can get clarity on making it perceived as "easier." It's all about perspective.

So what can we invert about the function?

We invert the coupling.

I've written about Inversion of Coupling Control in object-oriented paradigms. This is even to the point of identifying the OO Matrix. In summary, there are five couplings of the method that restrict us:

1. Method Name
2. Varying number of parameters
3. Varying number of exceptions
4. Return type

Yet, what does this have to do with functional programming?

The function suffers similar coupling. Ok, the exceptions are not thrown but are, instead, returned as values. However, changing the function's return type, name, parameters, and executing thread requires changing all other functions calling that function.

Now, beyond concurrency,  `Actor`s provide means to isolate the coupling impact of these changes. As long as the messaging semantics between  `Actor`s do not change, the `Actor` is free to change all its internal functions as it sees fit.  This isolates the impact of changing a function to just the `Actor`.

So I have to ask: Functional programming is appearing in many mainstream languages. Furthermore, we've now been moving to multi-threaded programming for some time now. So why aren't `Actor`s also becoming more prevalent?

For me, the reason is the thread binding in the `Actor` is to `State` rather than `Effect`. This to me makes use of  `Actor`s difficult.

My reasoning comes from these observations:

•  `Actor`s encapsulate changes to `State` to make this thread-safe
•  `Effect`s can wrap changes to `State` (whether internally in the system or externally)
• Multi-threading provides more efficient execution of blocking  `Effect`s (such as I/O) *
• Threading is configured to the `Actor`

*Multi-threading also enables parallel processing CPU intensive algorithms on multiple CPUs. For the purposes of this discussion, we will model this as an `Effect` requiring a different `Thread`.

Therefore, what I see in `Actor` modeling is the following relationship:

Thread (pool) -> Actor -> State

When it should actually be:

Thread (pool) -> (Blocking / Long running) Effect

In attempting to get the right break down of the system into Actors, we have to simultaneously:

• Consider an `Actor` an `Effect` to assign it the appropriate `Thread` (pool)
• Decompose `State` of the system into these arbitrary `Actor`s

Now, we're caught in the precarious problem of trying to find the right mix of logic, threading, and state decomposition. This is a "hard" problem to get right. Once threading becomes involved, it immediately becomes a problem only for intermediate to senior developers. No longer can we have junior developers assist in the system (or at least they need significant supervision).

Furthermore, developer resources are scarce and we need a way for junior developers to assist in building systems. Yes, there is a beauty and satisfaction in building a finely tuned system that fits together like clockwork. However, businesses don't really want to keep building expensive finely tuned watches just so customers can tell the time. We need to make things easier, not harder.

Hence, that's why I believe we need to invert the function to create a stateless `Actor` with a focus on mapping `Threading` to `Effects`.  Details of how this can be achieved are available in the following articles:

What this achieves is the following:

``````def Actor(m: Message, s: State, t: Thread): Array[Effect]
def Effect(r: Resource): AlteredState``````

Simplifying this down:

``def Actor(m: Message, s: State, t: Thread, r: Array[Resource]): AlteredState``

Hey! `Effect` was just removed!

Yes, because we don't really make the mapping decision of `Thread` to `Effect`.  We make it based on the nature of the `Effect` — blocking/long-running.  The Effect encapsulates this so we don't really know whether we are just quickly updating internal memory or making a blocking I/O interaction.

We make the `Thread` mapping decision based on the resources used by the `Effect`.  If the `Effect` requires a database connection, it is likely to be making blocking SQL calls.  If the `Effect` requires an HTTP Client, it is likely to be making blocking HTTP calls. If, however, the `Effect` only uses non-blocking resources, it is very unlikely to be blocking.

Now, if we extract out the `Thread` from the above `Actor`, we get:

``````def ActorEffect(m: Message, s: State, r: Array[Resources]): AlteredState
def Actor(e: ActorEffect, t: Thread): AlteredState``````

The junior developer is now free of threading to write the `ActorEffect`.

Later, a senior developer is able to make the correct mappings of `Thread` to `ActorEffect`.  This is because the determination can be made by the resources (whether blocking or not) used by the `ActorEffect`.

Furthermore, the `ActorEffect` can be written just as a function with `State` passed in. This makes the `ActorEffect` stateless so the junior developer is not involved heavily in thread-safety.

The `ActorEffect` is now able to be written by the skill level of the junior developer.

There are further improvements on the weaving together of the `ActorEffects`.  The following article provides a working code of how junior level functions can be weaved together with threading configured separately afterward: Weaving Together Functions (And Other Paradigms).

Therefore, it is now easy for junior developers to assist in building large functional applications. With the use of prototype threading by IoC, this is potentially to millions (even billions) of stateless `Actor`s scattered across thousands of underlying physical machines. But the ease of writing small functions remains for the junior developers, making it easier for them to be involved in large scale projects.

And thus I ask, whether in attempting to improve functional programming by finding even more niche and complex mathematics is the right way forward?  Or do we follow Carl Jacobi's advice and invert, always invert!?

Getting Started With Akka: Actors in a Nutshell

Scalable, Distributed Systems Using Akka, Spring Boot, DDD, and Java

[DZone Refcard] Reactive Programming With Akka

Topics:
actors ,concurrency ,effect ,first-class procedure ,functional programing ,functional programming ,inversion of control ,monad ,scala ,thread

Comment (1)

Save
{{ articles[0].views | formatCount}} Views

Published at DZone with permission of Daniel Sagenschneider . See the original article here.

Opinions expressed by DZone contributors are their own.