As a university student who just have been learning programming for a year. After I learned about the concept of state machine and the pure function in functional programming, I suddenly got an idea about combining them together as a programming style.
- Everything is either a state machine or a function. (So all the variables and objects in the Object Oriented Programming are considered as state machines.)
- If a function is a member function of a class. Then it is an action which will change the state of the instance of this class. (As mentioned above, this instance object has been considered as a state machine)
- If a function is not a member function of a class. Then it is a pure function.
- An action can only change the state of a single state machine. If the actions of multiple state machines need to be execute together. Then these changes should be abstracted as an action of a single higher level state machine which represent all these states machines.
After the exciting of eureka, I suppose I couldn't be the first one who got this idea. There must be some research about this programming style and I'd like to learn. But I really didn't find any information about this kind of programming style which specifically summarize principles just like I summarized above (The search result is filled with introductions to state machine and pure function). Does anyone know anything similar?
For more details, here is the sample C++ code about my idea.
#include <stdlib.h>
namespace Array
{ /* Although the pure function can't be a member function of class,
* I still need a way to organize the data structure and the
* functions together. I choose to use namespace to do this. */
class Object {
public:
int length;
int *array_data;
Object(int l) {
length = l;
array_data = (int*)calloc(length, sizeof(int));
}
~Object() {
free(array_data);
}
// It's not a pure function for it change the state of array.
void set(int index, int data) {
array_data[index] = data;
}
};
// It's a pure function.
int get(Object *array, int index) {
return array->array_data[index];
}
// It's another pure function which use a buffer to return
// the result. It only write the result to the buffer and
// doesn't change anything else.
void get_all(int* buffer, Object *array) {
int i;
for (i=0; i<array->length; i++) {
buffer[i] = array->array_data[i];
}
}
}
int main() {
Array::Object test_array(10);
test_array.set(0, 10);
for (int i=0; i<10; i++) {
test_array.set(i, i);
}
int value = Array::get(&test_array, 7);
int buffer[10];
Array::get_all(buffer, &test_array);
}
I suppose the biggest advantage of this programming style is readability. I used to write addon of Blender to practice programming. And I still remember when I read the source code of some other addons of Blender, I was really confused by whether a variable is changed or not. As for my programming experience, I found that the main cause of most bugs is the unexpected state change of variables and objects.
This programming style will easily remind us about whether the state is changed or not. When you see a function which is not a member function of class, you can confirm that this function is a pure function and didn't change anything. It also owns the advantages of pure function that it's easy to analyze the code and locate the bugs.