(Functional) OOP With Message Passing
There is a great misunderstanding of what object-oriented programming really is and its origins. The term "object" was first coined in the 1950s and became really popular on the early 60s on Lisp circles as a powerful design pattern. Finally on the 70s the first object-oriented language, Smalltalk, was developed by Alan Kay.
What is a message?
Before going deeply into object-oriented implementation it is fundamental to go deeply into the prerequisites. Let's start with messages!
So what the hell is a message? When you want to communicate two endpoints you need a standardized information to be passed along the way. A message is this standardized information and is essential to guarantee that the two endpoints will be as decoupled as possible. It is important to notice that if the producer sends a message that the consumer does not understand, nothing happens because it is not a predefined standard.
The above code works perfectly, but since we are working with an array as a parameter, it does not sound very semantic. It is not clear that the list of grades belongs to a single student. How do we fix this? Well… There are two solutions to this problem:
- We change the name of the function to getStudentBestGrade
- We pass as a parameter the student as an object.
Of course, we will focus on the second one! yay!
Using the "class" keyword
Well, since we are object-oriented programming lovers, we can do it with the class keyword. This is such an easy job anyway:
Now the code looks much better as I can simply pass on the student as a parameter and: Bingo! Much better than the previous version
Our First Functional Object
To understand fully what we will be talking about in the next paragraphs, we need to start simple. We will first use the concept of function scope to create a functional counter with a private embedded value.
Holy cow, that is a function that returns another function. Don't be scared, this is quite a normal thing to do. I know it may sound absurd for many people, but that is actually very useful. I like to tell people that this first function is a function builder because it lets you create more dynamic functions by simply injecting state into them.
Ok, but what the heck is state? Think of state as anything that can cause your functions to output different values for the same input, in this case, the parameter initial does exactly that.
As we can see in the example above, for the same counters, every time we call the function we have as output a different value. So just as a review, note that the Counter function builds in the example two functions with private embedded value inside. Isn't that what private attributes on objects do? ;)
As we can see, we used the same approach as on the counter’s example. Our function student (that represents our class) receives the grades as a parameter and maintains it as a private attribute _grades. The public methods (getGrades, getBestGrade) of this class are returned as a JSON. Since this class is written using a fancy looking function, there is no need to use the new keyword.
I hope you love this, now is when the real fun begins! ❤
Message Passing Object Notation
Let's write the same object as before but using the message passing strategy.
To use the message passing strategy, you have to understand that for each message, the object will have different handlers (functions) that will be specialized in dealing with the message. If we pass no parameters, then we can simply get the function and use it in a more flexible way. Below I show you how you can use the message passing strategy:
An advantage of using this object and not the previously declared object, the one using JSON, is the fact that in case we send an invalid message there will be a predefined response for this request that we can model for our domain.
Inheritance and Polymorphism
For this example, we need a class to extend from, and there is no other class that looks nicer than Person (I was not very creative really). Since every student is a person, this means that every student should have all attributes and methods from the base class. Below I have implemented the class Person.
Since Student needs to extend the base class, we should do some nice things to make it all work out together and produce a nice looking hierarchy:
- Students must have a name and an age. So for now on, the constructor should also have name and age
- One of the attributes of our class will be the base class that will be constructed with the parameters sent on the Student constructor
- If the message we are looking for is not found, we will redirect it to the base class on the default case of the switch.
Here we go, ladies and gentlemen! :D
Finally, we have a nice little class that extends Person using functions and message passing only. You can use it the same way as before, by sending messages.
I hope you liked what you read. This article focus on the main idea behind object-oriented notation and how to use message passing. Of course this is a very humble implementation and most languages optimize a lot how classes are represented when they become bits and bytes. There are lots of other things we could implement such as method overload and multiple inheritances, but they are quite an easy task to do once we have these things implemented.
 OOP v.s. FP — https://kara.codes/til/referential-transparency