DEV Community

Hayden Rear
Hayden Rear

Posted on

Effect Handlers in Functional Programming

What are side effects in functional programming? Why are they used?

What is FP

I am not going to bore you with the introduction you usually get. If you are reading this, then you already know about immutable state and pure functions.

What are side effects?

You probably know what side effects are, but I'll talk about them here. Side effects are something that is something that causes an effect to happen outside of the application. They are introductions of instability into your pure code. They are toxicity in the water. We must manage them well if we maintain reasonability in our code.

For example, let's say I am creating a new age database. This new age database is distributed, and says that it is consistent, but it's eventual consistency hinges on the fact that the interactions with the database are compiled WASM modules. The WASM modules are passed in, with an identifier for the component that is interacting with the database.

Every time that a new behavior is added to the database, query is pre-registered. Then, the component that interacts with the database sends the parameters to the query. The query sits in the databases stack and on a clock when all the nodes of the database confirm, they are committed.

But here's the thing: if the nodes disagree on the ordering of a transaction, the transactions can be reordered, and that means that the output of the transaction changes. So the user includes their transaction ID, and all is well. The transactions are re-ordered and re-executed on the stack, and everything is fine. And I make billions of dollars overnight because I used the acronym WASM DB.

Side Effects Ruin Everything

Unfortunately, there is something wrong with our WASM compiled distributed new-age ridiculous database. If the user receives a response, which is "eventually consistent", then that response is subject to change. Of course if they just continue interacting with the database with their component ID, then it will propagate up through the stack. Of course, if there is no question about the ordering of the transaction, then the result they ended up getting will be the result (and under normal circumstances they can trust the result), HOWEVER if they are to perform some action outside of the system with the result, and it turns out to be outdated, then - sorry - everything starts to fail. Let's say they write to a log with the result, and then some other component reads from that log, and performs some actions, such as locking a user account. The user calls in and says, "why did you lock my account?", or a thousand users call in all at once.

How to Properly Manage Side Effects

Side effects are a part of life, sort of like shit in the ocean. So how do you introduce the impure into the pure, without making it impure? Here are a few ideas:

  1. Have a pure function describe the effect.
  2. Have another function take the description of the effect and perform the actual side effect.

What does this mean? We take some behavior of the system and have a deterministic output. Determinism is key, because at this point we have all the different possible outputs. And then we can write test cases for each one, if we are good enough :).

Top comments (0)