We covered about what are stateful and stateless in our previous post. In this post, lets see how are the stateful and stateless design principles applied in writing programs. This post will also give you an insight on the difference between stateless and stateful programs. This helps in understanding Imperative and Functional programming paradigms.
Stateful Programming
What can be a program’s state?
I added a self-made definition of state in my previous post. In programming, the state of the program is stored in it’s variables which can be read or mutated during execution. It is the data in these variables at a given point of time during the runtime.
Example
public class StatefulProgram { private int add(final List<Integer> items) { /* The state of the program is maintained in the variable total */ int total = 0; for (int item: items) { /* During each iteration, the state is mutated by updating the variable total. */ total = total + item; } return total; } public static void main(String[] args) { final StatefulProgram aStatefulProgram = new StatefulProgram(); final List<Integer> items = Arrays.asList(1, 2, 3, 4, 5); final int sum = aStatefulProgram.add(items); System.out.println("Sum is: " + sum); } }
Output
Sum is: 15
What happened here?
- In the
main
method a list of integers1, 2, 3, 4 and 5
is passed to theadd
method. - In the
add
method, this list is iterated and the total sum of all the list elements is computed and stored in the variabletotal
. - This variable
total
is returned to main method where it gets printed.
Note the variable total
initialized outside the for
loop. The state of the program changes when the variable total
is mutated in the for
loop at each iteration. Also, during iteration the previous state is used to compute the next result in the line total = total + item;
Stateless Programming
In a stateless program, the program doesn’t maintain a state. Instead of maintaining a separate state, the data required for the function to execute are passed as inputs (the program should have value semantics) . The invoked function uses these data, processes and sends back the output to the caller.
Example
// This function will add the two given inputs and returns the sum. const add = (a, b) => a + b; const values = [1, 2, 3, 4, 5] // I have used reduce and add to compute the sum. const total = values.reduce(add, 0); console.log(`Sum is: ${total}`);
Output
Sum is: 15
What happened here?
- I created a function
add
. This function gets two input values, adds them and returns the sum of the inputs. - I have an array of five numbers ranging from 1 to 5.
- I have used
reduce
with the functionadd
as callback.
Here, when I invoke the method reduce
on values, it uses the add function to calculate the sum and returns the computed the output. Here, there are no external variables used to maintain the state. All the required values for the computation are passed as inputs to the function.
Lets dig a bit deeper
In general, any entity that undergoes transition from point A to point B, will undergo the transition through one or more states. Being in point A at the beginning and in point B at the end are also states.
In both the above examples, the variable total
changes from having zero value to having value 15. It’s state is changed from zero value to 15. In a stateful program, it has few intermediate states inside the for loop iteration to reach 15.
If a stateless program doesn’t maintain state, how is this achieved?
A stateless program doesn’t maintain an external shared mutable state. Instead of external states, the state is passed as value input to the functions. The function which receives state as input, computes using it and returns a new version of the state as output (which will be further used as input to other function calls). Since functions called will not have shared states, they will be executed in a modular fashion.
Advantage of stateless programming in concurrency
When it comes to writing a performant code, we opt for a concurrency patterns like multi-threading.
In a stateful program, we might need to add extra precautionary codes to jump over hurdles like resource sharing, dead locks, race conditions, etc. Why? Because mutable data are the enemy of a multi-threaded code.
Meanwhile, stateless programming encourages concurrency. No shared mutable states maintained which makes it easier to write multi-threaded programs. There will be no race conditions thus eliminating dead-locks. This will eliminate occurrence of any related bugs.
Well, that’s that about stateful and stateless programs. If you noticed, the style of both the example programs are completely different. This comes under programming paradigms which is another fun topic.
Whats next?
Checkout the next posts in this series.
I hope this post was helpful 😊. If you find this post informative, support us by sharing this with fellow programmers in your circle 😀.
For any suggestions, improvements, reviews or if you like us to cover a specific topic, please leave a comment.
Follow us on twitter @thegeeksclan and in Facebook.
#TheGeeksClan #DevCommunity
Pingback: Functions and Methods - The Geeks Clan
Pingback: Imperative Programming Paradigm - The Geeks Clan