Functional Programming vs Object Oriented Programming

Written by myself, Tomas Engquist, and Harpreet Ghotra. They each did more than their share of the work!

X-post from Functional vs Object-Oriented Programming.


Arguments over preferred languages (C++ vs Java, JavaScript vs Ruby, etc.)  have always been prevalent in the programming community. However, programmers disagree on more than just language. Many of them fight over which style of writing code is more optimal, object-0riented or functional programming . While OOP is by far the most popular programming design, many people have not even heard of  functional programming. We’re going to explain the fundamental differences between object oriented programming and functional programming and describe the advantages and disadvantages of each style. 

 

What is Object Oriented Programming?

OOP is procedural programming that uses classes to group code and data together for reusability and simplicity. By separating a program into classes, it is easier to modify parts of the program in isolation. Each class is a template for a type of object, or an instance of the class. When placing methods into different classes, instances of each class can easily be modified, replaced, and reused. However, mutating class instances can get complicated with larger sets of data because it’s harder to track where each instance was changed. 

class Car {
constructor(icon){
this.icon = icon;
}

     changeIcon(newIcon){

         this.icon = newIcon
    }

     carSoldTo(newOwner){

       this.owner = newOwner;
    }
}
const car1 = new Car(‘🚗‘) // Car {icon: ‘🚗‘} 

car1.icon = ‘🚖’           // Car {icon: ‘🚖’} 
car1.changeIcon(‘🚘’)      // Car {icon: ‘🚘’}
car1.carSoldTo(‘Tomas’)   // Car {icon: ‘🚘’, owner:Tomas’}

 

By implementing methods inside a class, it is easy to mutate instances of the class.

 

The Advantages of OOP

 

Since its rise in popularity in the 1980s, object oriented has been the principal design concept of software engineering. Java, C++, Python, and Ruby are the most commonly used OOP languages, but there are over 100 other programming languages that support OOP. These languages compose some of the most widely used programs in history. Gmail and Minecraft are written in Java, Instagram and Spotify are written in Python, Windows and OSX are written in C & C++. We will discuss four important concepts that make OOP a popular design strategy: intuitive problem solving, encapsulation, inheritance, and polymorphism.

 

Intuitive Problem Solving

 

Programmers love OOP because it is easy to learn and conceptualize. OOP places classes in a hierarchy of parents and their children. Humans organize things in a similar hierarchical manner. For example, a vehicle is something that moves things. A car is a vehicle travels over roads. A hybrid is a car that uses electricity in addition to gas. A Prius is a hybrid with five seats made by Toyota. Notice in each sentence, we use the previously defined object to help conceptualize the new, more specific object. In short, OOP makes sense to us.

 

Inheritance

 

Probably the biggest advantage of using OOP is inheritance, or reusing code. Going back to the Prius example, let’s imagine you are the car manufacturer. If you want to switch from producing Priuses to making the Honda Insight instead, you don’t have to research how to make a vehicle, how to make a car, or how to make a hybrid. Why? Because you have already done it. Instead of starting from scratch, you can take your blueprint for making  and work from there. In OOP, the class is the equivalent of the blueprint. Instead of starting every program from scratch, you can inherit a class that contains any methods or properties that you need (a hybrid) and then add new features on top of it (Prius, Insight). Inheriting classes keep you code DRY (don’t repeat yourself) and saves you lots of time.

 

class Hybrid extends Car {
constructor(icon, batteryLife){
super(icon);

         this.batteryLife = batteryLife;

     }


    changeBatteryLife(newBatteryLife){
this.batteryLife = newBatteryLife;
    }
}

const hybridCar = new Hybrid(‘🚓’, ‘10yrs’)

// Hybrid {‘🚓’, ‘10yrs’}
hybridCar.changeIcon(‘🏎’)

//Hybrid {‘🏎’, ‘10yrs’}
hybridCar.changeBatteryLife(‘5yrs’) 

// Hybrid {‘🏎’, ‘5yrs’, ‘Tomas’}

 

The Hybrid class inherits all the Car class methods while keeping access to its own class methods. 

 

Encapsulation

 

OOP allows us to create objects of a certain class. Many OOP programming languages have a way to protect variables from outside access, forcing programmers to only interact with the class through specific methods. This allows us to hide our implementation behind an interface (protecting objects from programmer mistakes) and interact with other parts of the program through these well-behaved interfaces. In addition to providing this security, encapsulation also helps us make flexible code that is easy to change and maintain.

 

class Car

  def initialize(icon)
    @icon = icon
  end

  def changeIcon(newIcon)
    @icon = newIcon
  end

end

car1 = Car.new(‘🚙’)
car1.icon = ‘🚗’        ##NoMethodError
car1.changeIcon(‘🚗’)   ##<Car:0x00007f8bf1039498 @icon=”🚗”>

Encapsulation prevents the object attributes from being directly modified.

 

Polymorphism

 

The literal definition of polymorphism is the condition of occurring in several different forms. In OOP, polymorphism refers to the ability of a variable, function or object to take on multiple forms and have multiple behaviors. This allows us to reuse code in a similar way to inheritance. Going back to our previous example, let’s say we have a vehicle class with a method move. All the subclasses of vehicle can reuse this method move but with different behavior. The car subclass will start spinning its wheels, the boat subclass will start spinning its propellers, and the plane subclass will start spinning its turbines. This cuts down the work of the developers because they can now create a general class with certain behaviors and make small altercations to subclasses when they need something more specific.

 

In dynamic languages we use for the web, this behavior is kind of built in. Functions that accept “vehicle-like” objects already behave polymorphically, spinning the car’s wheels, and the boat’s propellers. In other languages, polymorphism is just as important, but needs to be implemented explicitly.

 

struct Vehicle {
    virtual void move() {
        printf(“generic moving\n”);
};
struct Car : public Vehicle {
    virtual void move() override {
        printf(“vroom!\n”);
    }
};
struct Boat : public Vehicle {
    virtual void move() override {
        printf(“rumble rumble”);
    }
};
void moveIt(Vehicle* vehicle) {
    vehicle->move();
}
Car* car = new Car(); Boat* boat = new Boat();
moveIt(car); // “vroom!”
moveIt(boat); // “rumble rumble”

 

Without OOP, implementing this kind of polymorphism can get very ugly. “Simple” way of simulating it usually involve keeping track of type and writing if statements everywhere polymorphism is desired. Other common methods of implementing polymorphism without OOP get progressively more complex as the “level” of polymorphism increases.

The Disadvantages of OOP

 

While OOP reins king as the most popular program design, developers have certainly encountered issues with it. In many cases, the advantages that OOP bring us come with side effects and additional burdens. In this section, we will go through some of these burdens and how they can affect programs.

 

 Monkey Banana Problem 

 

Inheritance is one of the most important concepts in OOP. It allows for the reuse of code by basing Objects or Classes on other Objects and implementing methods defined in the parent classes. Reuse of code through Inheritance cuts down on redundant code and makes OOP programming seem like a no brainer, that should be a part of every programming language. But just like everything in life, there are tradeoffs that come with inheritance. The main problem has been famously stated by  Joe Armstrong, the creator of the ERLANG language.

 

“ You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” 

 

Classes in OOP may be deeply nested, which means they have a long chain of parents classes they rely on. When inheriting a deeply nested class, you must also inherit its parent class and that parent’s parent class and that parent’s parent’s parent class and so forth. Programs won’t compile until you inherit all of the necessary parents classes. A solution to this is to avoid writing deeply nested classes, but that takes away from the reusability that comes with inheritance.

 

Encapsulation Problem

 

Inheritance creates several dependencies between parent and child classes. It becomes difficult to understand what is happening in the child class without having to open the parent class. Furthermore, the child class has access to the parent class methods, and might overwrite these methods. Encapsulation is done to prevent Object variables from being tempered by child classes. The parent class constructor in Javascript makes a deep copy of the Object and then passes it by reference. Making copies of each parent class bogs down on the efficiency of the program.

 

What is Functional Programming?

Functional programming is similar to “pure” mathematical functions. Instead of specifying a procedure to solve a problem, functional programs compose functions to produce the desired result without using ‘state’. Evaluation of these functions and their relationships are much more important than objects and relationships. Functional programming also makes very little use of variables. Variables depend on state, which changes based on the past path of a program.  Once state is involved, the function can’t be evaluated in isolation – making it no longer pure.

Advantages of Functional Programming

 

Surprisingly, functional programming also has many of the same perks as OOP. Many of these advantages come without the burdens that come with OOP.

 

Eliminate Race Conditioning

 

A race condition exists when two different functionalities depend on a common resource. When the sequence of events occur differently than expected by the programmer, a failure occurs. This may occur when fetching data from an API. For example, let’s say you have a method displayData(data) that uses data from an API and another method to retrieveData()  that fetches it. If you run displayData(retrieveData()), the fetch may not finish in time and displayData will try to run before retrieveData is finished, resulting in an error. Functional programs do not share resources and create dependencies in this manner, avoiding race conditioning altogether.

 

Polymorphism

 

Wait, wasn’t polymorphism supposed to be an advantage for OOP? Yes, it still is, but the truth is you don’t need to use OOP to implement polymorphism. Interfaces will give you this without all of the monkeys, bananas, and jungles of OOP.

 

Easy Debugging

 

Functions in functional programming are ‘pure’ i.e. you expect the same output given the same input. The functional approach stresses simple functions that provide one piece of functionality. Bigger tasks are modularized into multiple simpler functions. In theory, the lack of state makes it much easier to debug these programs.

 

Reusability

 

In the words of Joe Armstrong, “if you have referentially transparent code, if you have pure functions — all the data comes in its input arguments and everything goes out and leave no state behind — it’s incredibly reusable.” In other words, because every function is pure, one can keep reusing them without ever having to worry about state. In OOP, the state of class may change, whether intentional or not, and affect the results of the instance or class methods.

 

Disadvantages of Functional Programming

You can’t really break down the disadvantages of functional programming into different categories. The one main problem with functional programming is quite straightforward: it’s very hard. Because we don’t have the structure and organization that comes with OOP, writing and reading complex functional programs is quite difficult. When lovers of functional programming claim that it is easier to debug and is more reusable than OOP, you must take it with a grain of salt. While it is true that pure functions don’t rely on state, they still can get complicated, difficult to follow, and hard to debug.

Conclusion

Clearly, it’s not so easy to pick a side between OOP and functional programming. The good thing is, you don’t have to. The only thing you have to determine is where to use each approach. Some programs might be better off written with object-oriented design while others might be better off written with functional design. Some programs might be better off using a combination of both. As a programmer, it is your job to make these choices. Hopefully you can now make these informed choices.

 

~ by Alexander Riccio on August 14, 2019.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
Lucky's Notes

Notes on math, coding, and other stuff

AbandonedNYC

Abandoned places and history from the five boroughs and beyond.

Open Mind

KIDS' LIVES MATTER so let's stop climate change

I learned it. I share it.

A software engineering blog by György Balássy

Untapped New York

NYC's Secrets and Hidden Gems

Bit9 + Carbon Black Blog

#ArmYourEndpoints

The Electric Chronicles: Power in Flux

If someone ever tells you that you don't need more power, walk away. You don't need that kind of negativity in your life.

Ted's Energy Tips

Practical tips for making your home more comfortable, efficient and safe

love n grace

feel happy, be happy

Recognition, Evaluation, Control

News and views from Diamond Environmental Ltd.

greg tinkers

Sharing the successes and disasters.

Sam Thursfield's Blog

I want music in my life not questions!

Cranraspberry Blog

Sharing the things I love

Biosingularity

Advances in biological systems.

The Embedded Code

Designing From Scratch

Sean Heelan's Blog

Program analysis, verification and security

EduResearcher

Connecting Research, Policy, and Practice in Education

Popehat

A Group Complaint about Law, Liberty, and Leisure

Warners' Stellian Appliance

Home & Kitchen Appliance Blog

Bad Science Debunked

Debunking dangerous junk science found on the Internet. Non-scientist friendly!

4 gravitons

The trials and tribulations of four gravitons and a postdoc

Strange Quark In London

A blog about physics, citylive and much procastination

The Lumber Room

"Consign them to dust and damp by way of preserving them"

In the Dark

A blog about the Universe, and all that surrounds it

andrea elizabeth

passionate - vibrant - ambitious

Probably Dance

I can program and like games

a totally unnecessary blog

paolo severini's waste of bandwidth

Musing Mortoray

Programming and Life

PJ Naughter's space

Musings on Native mode development on Windows using C++

  Bartosz Milewski's Programming Cafe

Category Theory, Haskell, Concurrency, C++

Brandon's Thoughts

Thoughts on programming

David Crocker's Verification Blog

Formal verification of C/C++ code for critical systems

10 Minute Astronomy

Stargazing for people who think they don't have time for stargazing.

One Dev Job

notes of an interactive developer

Enterprise Architect, IoT, Cloud, Mobile Apps, Technology Evangelist, Technical Pre-Sales, Business Evangelist, Speaker

Coder/Architect for IoT, Cloud Technologies and Mobile Apps, Azure Cloud, Amazon Cloud, Windows Phone 10 Apps, iPhone Apps, Scrum Master, Business Evangelist, Mobile apps developer in iOS and Windows 10 UWP, Azure IoT Hub, Machine Learning, Stream Analytics, Azure Mobile Service, APM Tools

The Angry Technician

No, the Internet is not broken.

Kenny Kerr

Author • Systems programmer • Creator of C++/WinRT • Engineer on the Windows team at Microsoft • Romans 1:16

IT affinity!

The Ultimate Question of Life, the Universe, and Everything is answered somwhere else. This is just about IT.

Eat/Play/Hate

The ramblings of a crazed mind

Molecular Musings

Development blog of the Molecule Engine

%d bloggers like this: