(Functional) OOP With Message Passing

I promise this will not be another article on OOP vs FP! Why not build OOP using FP? Much better!

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.

The truth is that what object-oriented programming really represents has been lost over the years as modern languages kept copying the syntax and ideas imposed by the C programming language. Alan Kay has declared publicly many times that the essence of OOP is the concept of message passing, and that modern programming languages focus more on the object notation itself than in the concept of message passing. This of course is the motivation for this article and our focus here will be to show the essence of object-oriented programming using a popular modern programming language, JavaScript. I hope you enjoy this journey.

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.

Our problem…

Suppose I want to grab a student's best grade from a list of grades in all the exams he participated. We could write a silly function to do that without complex functionality, just vanilla JavaScript for the masses:

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:

  1. We change the name of the function to getStudentBestGrade
  2. 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

But this is not the idea behind this article. It looks quite nice but we are using JavaScript object-oriented notation to do that. Why not do it with functions only? So keep on reading :)

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? ;)

Now that we understand state injection, we can complicate things a bit more and write a JavaScript-only class using functions only. Why JavaScript only? Because we will use JSON (JavaScript Object Notation).

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.

This implementation is very common on old JavaScript source codes but is very powerful. But as I promised before, we want to do it the right OOP way, and that means that we need to use the concept of message passing. The message passing implementation is language agnostic and should work on any decent programming language out there.

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.

As we can see, this OOP implementation at first sight does not look very elegant in JavaScript, but I can guarantee it will work on most popular programming languages. The idea is not what this implementation can do differently, but how we can extend this and implement real cool hierarchy and polymorphism (We will do this after the next title).

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:

  1. Students must have a name and an age. So for now on, the constructor should also have name and age
  2. One of the attributes of our class will be the base class that will be constructed with the parameters sent on the Student constructor
  3. 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.

Conclusion

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.

Amazonian • Hacker • Former CTO at InvestPro • Cloud solutions expert • Enterprise Architect • Loves his wife, family and maths.