Back when I was a newbie programmer, one statement was particularly popular:
“Object-Oriented Programming (OOP) is the best way to program because it reflects real world-building with objects.”
A while later, when I went to college, the same idea was still on top and basically all that I was being taught was OOP. Recently it all changed for me though. A few months ago, while sorting some Ruby on Rails issue I came across the Elixir and Phoenix Framework and it significantly changed my perspective on application’s structure building. Today I’d like to show you the new exciting world of functional programming and why you should use it too.
Object-oriented world
Let’s start where it all begins – with OOP. Why do so many people think it’s the best way to create business apps? The main purpose of OOP is to create objects that represent real-life elements. For example, when I was learning C++, most cases involved creating animal objects. They were simple and easy to understand – so I was using them too. Take, for example, an object “dog”. The dog has its specific data, including name, breed, fur and more. When we create the object, we set it to know that we are talking about this one specific dog with all of its features. So let’s name the dog Max; it’s a German Shepherd with short hair. Close your eyes and picture it. The dog is just as real as you describe it. It does things real dogs do. It can walk or run or bark. And this is how you create an object in OOP. You take it and name it, give it features and description.
Now let’s add some other objects from real life. We can have other animals like cats, birds and more. What should we do with them now? How should we describe them? All animals have some of the same elements – for example, their name, age, ability to walk and perform other actions. But they can also have some individual features. For example, a cat can meow and a bird can fly. To achieve this in OOP, we can use inheritance. We have the class „animal” and from that: cat, dog, and bird. We use inheritance to add some individual specifics to each object. It sounds pretty simple, right? The main OOP assumption is to inherit methods from one class to another and then build an object from the class. But – unfortunately – programs are not like real-world objects. The computer saves all data combined into one information, so if you change something it influences everything else in the code – line after a line.
Short, fast, and maintainable
So, let’s now see how our animal could look if we used a different, Elixir-based programming approach. Elixir is a dynamic, functional language designed for building scalable and maintainable applications. Phoenix is a web development framework written in Elixir which implements the server-side MVC pattern. To visualize how programming in Phoenix Framework works, let’s start with the dog, as before. Our dog has a name, breed and fur. Knowing that we can create data that will be used for our functions:
%Animal{type: “dog”, name: “Max”, breed: “German Shepherd”, fur: “short”}
When you see that part of code you can easily tell what it represents. Creating intuitive data in Elixir is very easy. Imagine, now we need data about a cat. It is analogous to the dog – we can, for example, create:
%Animal{type: “cat”, name: “Bingo”, breed: “Aegean”, hair: “semi-longhaired”}
We needed only a few seconds to put our characteristic elements of Bingo and Max into the system. Our second step will be to create functions that will change the state of our animals. Let’s, for example, teach our animals to say something. In OOP we create a method; for the dog we’ve created “bark” and for the cat – “meow”. In Phoenix Framework (PF) we can create modules for all the animals with one function to say something. For example – Animal, say (cat) where cat is equal to %Animal{type: “cat”, name: “Bingo”, breed: “Aegean”, hair: “semi-long”}. In Elixir we can create many functions with the same name but with different implementations, depending on data that we send. For example:
def say(%Animal{type: “dog”}) do IO.puts " bark" end
def say(%Animal{type: “cat”}) do IO.puts " meow" end
We have created separate code for storing data, and functions to change this data. If in the future, we decide that we would like to change how “say” works, and we save the result to file, we can easily change just the function and reload it. So you see, the PF code is much easier to modify and maintain. Each part of the system can operate independently and if necessary we can change just one small piece without having to rewrite the rest.
Let it crash
The beauty of PF lies in code maintenance. Imagine, that for some reason, the Animal module crashes. In OOP, if an object crashes, we lose most or even all of our data. It usually means a need to rewrite a huge part of code – hours and hours of work irreversibly gone. In PF, data is kept safe, saved in separate places. If the source of the problem is an unachievable external API we don’t need to waste time to get back to the previous state. We can easily let the Animal module crash, then reboot it and run the function again. After rebooting, everything would work without any further interruptions.
What next
I would strongly suggest to explore and start using PF while making some simple business applications, creation of which would simply be easier than in OOP. Not every app requires predefining classes and setting the whole structure at the start. Using Elixir and PF you can program more spontaneously and insert changes as you go. It makes the process much more friendly and interesting. I assure you it’s worth your while.
If you want to learn more:
http://elixirsips.com/episodes.html
http://elixir-lang.org/learning.html
http://www.phoenixframework.org/
Author: Przemek Olesiński