In this blog and my book (rus), I repeat, time and again, the same mantra about "separating the effects from the logic." I think it’s necessary that my readers fully understand what I mean. However, when I started to analyze the existing terminology, I was surprised to find out there’s no uniform framework. The options that are available don’t include the nuances I believe to be important. Therefore, I decided to write an article series about the terminology I’m using.
Pure functions have it easy. There’s a Wikipedia article about these that provides a decent enough definition:
<…> a pure function is a function that has the following properties: . The function return values are identical for identical arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams). . The function application has no side effects (no mutation of local static variables, non-local variables, mutable reference arguments or input/output streams).
Well, even this isn’t exactly perfect, as it references a bunch of random books. Moreover, the definition relies on side effects.
Alright, let’s find out what side effects are using Wikipedia.
In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, that is to say has an observable effect besides returning a value (the main effect) to the invoker of the operation. […] Example side effects include modifying a non-local variable, modifying a static local variable, modifying a mutable argument passed by reference, performing I/O or calling other side-effect functions.
Well, some questions certainly arise.
And the most important one is, what is the effect side to?
And what if I’m only invoking the function for the "side" effect?
printf, for example, side?
It seems sensible that apart from side effects, there are also effects.
The other question is, what’s the in-between for pure functions and side effects functions? For example, a function that reads the current time. Or a function returning the value of a global variable. These are undetermined, that is, not pure. They also don’t change their global state, that is, they have no side effects as per Wikipedia’s definition.
That’s where the funny part starts. They say that an effect is how a monad implements the flatMap. Apart from everything that Wikipedia brands as side effects, they also put under that umbrella the functions I mentioned above that read the global state, as well as asynchronous effects (Future), errors (Try), and even the value absence (Option). For them, effective functions are functions that instead of a result, such as T, return some wrapping around that result, such as F. And side effect is a bug.
Well, that’s the painful sight that the current effect terminology framework is. In this article series, I’ll present to you my full uniform terminology framework. :)
Here’s a book on this topic I’d recommend picking up: Concepts of Programming Languages, Chapter 7.2.2