State as defined by Wikipedia is the snapshot of the condition of the system. It can mean different things depending on how you view it from a program or system perspective. From a programmer point of view, there are two parts in a program:
- Main program – control program (parent program)
- Sub-programs (child programs) – the procedures in imperative programming (IP) or functions in functional programming (FP), the ones being called by the main program
There is no question that you have to make your sub-programs functional, that is, free of side effects. It will make your code self-sufficient and stand-alone, thus taking advantage of code reuse. If sub-programs are written in a shared-nothing fashion, that is the way to go for making programs scalable.
In object-oriented programming, you try to encapsulate program logic (methods) and data as one unit of computation namely the object, whereas in functional programming, you do it as monads.
Monads are a kind of abstract data type constructor that encapsulate program logic instead of data in the domain model. A defined monad allows the programmer to chain actions together and build different pipelines that process data in various steps, in which each action is decorated with additional processing rules provided by the monad.
In this context, functional programming advocates writing your sub-programs as functions and writing your main program as monads.
But there is a disadvantage with monads (well, if you come from imperative programming, which most of us do):
The primary disadvantage of languages which enforce referential transparency is that it makes the expression of operations that naturally fit a sequence-of-steps imperative programming style more awkward and less concise. Such languages often incorporate mechanisms to make these tasks easier while retaining the purely functional quality of the language, such as definite clause grammars and monads.
For an example of how functional programming can be awkward, click here.
On the other hand, consider another example: MVC (model-view-controller). The controller program holds the entire state of the application. It is after all the main program. The controller calls its subprograms namely the view and model modules. See how state is maintained at the controller while addressing separation of concerns.
- OOP – main programs (objects call public methods of other objects), sub-programs (objects call its private methods only)
- FP – main programs (monads), sub-programs (functions)
- IP – main programs (procedures), sub-programs (sub-procedures)
But there’s no stopping OOP or IP languages to have sub-programs written as side-effects-free functions!
The gist of the lesson here is:
Your main program controls the entire state of the program. Do not sweat the state stuff. State really belongs to the main program, whereas make your sub-programs as side-effects-free as possible (regardless if you come from OOP, FP or IP). Sub-programs with no side effects are not the sole province of functional programming.
As a historical example of this whole issue of state, consider that Linus Torvalds had a considerable debate with Andrew Tanenbaum as to how large an OS kernel can really be. Torvalds advocates a monolithic kernel (a case of big main program coupled with subprograms – the userspace modules) versus Tanenbaum’s microkernel architecture. And see how purely-functional programming language like Haskell turns into a kind of religious schism among OOP and IP languages!
This is not an attack on Haskell but clearly, the point is:
State is not bad after all (provided you know how to use it in your main program ONLY)
Scala, however, doesn’t mind melding the OOP and FP paradigms.
Having said that, let’s tackle state from the system point of view, and it all boils down to your database. Regardless if you use relational databases or NoSQL data store, it doesn’t matter. Your system state is your data. Well, we can rephrase it as, your business state is your data. Without data, there is no business. State in RDBMS is otherwise called as transactions. It’s either all-or-nothing, a finite state machine.
The essence of data state from systemic perspective is best captured with the notion of CAP Theorem.