DEV Community

Nijeesh Joshy
Nijeesh Joshy

Posted on

Functional Programming vs OOPS : Explain Like I'm Five

what is the difference between Functional Programming vs OOPS

Top comments (13)

Collapse
 
avalander profile image
Avalander

Imagine three people sitting in a room, lets call them Anna, Brad and Carol.

In object oriented programming, Anna has a paper with cats written on it, and Brad has a paper with are cool written on it. Then Carol comes and asks Brad what do you think?. Brad asks Anna what do you have?, Anna looks at her paper and answers cats. Brad then looks at his paper and answers to Carol Cats are cool.

In functional programming, Carol comes and asks What do you think? then Anna produces a piece of paper, writes cats on it and passes it to Brad. Brad looks at the paper and writes are cool next to cats. Then they hand out the paper to Carol and she reads cats are cool.

Collapse
 
bhaibel profile image
Betsy Haibel

Ooof! I can't blame you for being confused here. The definitions of "functional programming," "object-oriented-programming," "logic programming," or any other programming paradigm out there aren't set in stone. In a practical sense, they shouldn't be. It matters more how any given language uses functional ideas, or object-oriented ideas.

(This is even more true nowadays than it was forty years ago. Forty years ago, there were languages that were "purely" functional, or "purely" logic-oriented. But today, most commonly used languages are "multi-paradigm." They incorporate ideas from FP, OOP, and other programming styles, but they aren't just one thing. When we say that a modern language is a functional language, or an object-oriented language, usually we mean that it's "mostly" functional or "mostly" OO.)

In general, when you're doing functional programming, you think about "functions" as the basic unit of the language. Functions can be passed around like variables, and you can assemble other mega-functions out of functions. If you wanted to sum a list of numbers, you wouldn't use a for loop. You'd use a special function called a reduce that applied the add function to every number in the list.

add(1, 2)
=> 3
sum = reduce(0, add)
sum([1, 2, 3])
=> 6

When you're doing object-oriented programming, you think about functions as being attached to data. Instead of having an add function that operates on two numbers, you make every number have an add function be attached to it. Or every cat have a meow function attached to it.

3.add(4) => 7
cat.meow() => "meow!"

Different styles are suited for different things! For example, if I'm doing math, I usually find functional programming easier to think about. To me, add(1,2) is simpler than 1.add(2). But if I'm doing other things, I often have an easier time with object-oriented programming. It's easier for me to think about a cat meowing than about a meow function that takes a cat.

Everyone has their favorite style of code, and every language implements these paradigms differently. That's why there are so many definitions of FP and OOP out there! Let's say that someone really likes Haskell. They like it both because they can define functions in terms of other functions (which is a FP thing) and because it has an awesome type-checker (which some, but not all, FP languages have). Because they love Haskell, they love functional programming. But when they talk about functional programming, they often talk about the things they love about Haskell's version of it, not functional programming in general. So people talk about FP as about "immutability" and "type checking" and stuff like that, rather than "building functions out of other functions," and everyone's definitions get confused. :(

The same thing happens on the OOP side! Some folks love using inheritance to organize their code. Inheritance is more common in object-oriented languages than it is in functional ones, so people talk about inheritance like it's necessarily an OOP thing. But! There are also object-oriented languages that don't do inheritance (Rust, arguably). And Haskell's "newtype deriving" isn't called inheritance, but it's basically inheritance. Similarly, just because we think of static type checkers in FP more often, there are totally FP languages without them (Erlang, Elixir) and OOP languages with them. (Java).

People say a lot of things about OOP and FP. A lot of the time, it's to justify why they think that one of them is better than the other. They'll say things like:

OOP is easier to understand in complex systems because objects maintain their own state. Stuff that's far away from the object I'm working with can't affect my code.

or

FP is better than OOP, because immutability means that I never need to deal with state bugs.

These statements tend to get truer if we sprinkle phrases like "for me" and "usually" through them. So we can translate the above statements into:

I usually think that OOP is easier to understand in complex systems because in my style of OOP objects maintain their own state. Stuff that's far away from the object I'm working with usually can't affect my code.

I think FP is better than OOP, because in functional languages with immutability, I never need to deal with state bugs within a single function.

In general, I wouldn't sweat the difference between FP and OOP too much! Instead, I would look for what aspects of a language make you feel more confident in the code you're writing. When you're looking for teams to work with, seek out people who value those aspects! You'll find each other's code much easier to read than code written by people who value different things.

Collapse
 
gmartigny profile image
Guillaume Martigny

Functional is based on functions and OOP (Object Oriented Programming) is based on objects. It's two distinct ways to write code. It's not the only two nor they are mutually exclusive. While OOP tends to replicate the real world with objects you act on, functional is way too abstract for a five year old. It's more like a flow of actions rather than objects interacting with each others.

Consider this recipe:

functional

const crepe = step([
  () => [getFlour(300), getEggs(3), getMilk(60)],
  mix,
  cook,
]);

OOP

const flour = new Ingredient("flour", 300);
const eggs = new Ingredient("egg", 3);
const milk = new Ingredient("milk", 60);

const crepe = new Recipe();
crepe.mix(flour, eggs, milk).cook();
Collapse
 
jamesmh profile image
James Hickey

Why not lol:

Programming is like lego. You build stuff by stacking blocks together.

In FP blocks are functions.

In OOP blocks are classes.

That's a very rudimentary explanation 😉

Collapse
 
mfekadu profile image
Michael Fekadu

Ah yes! Wonderful!

What are the connection points between each LEGO?

Collapse
 
jamesmh profile image
James Hickey

They could be method invocations, shared state (which I don't suggest overall), asynchronous messages, etc.

Collapse
 
thejhonny007 profile image
Jhonny • Edited

I know, I am late to the party, but functional programming and OOP are not exclusive. You can have things like classes, inheritance and polymorphism in pure functional code. Have a look at this Scala code:

abstract class SimpleList[+T] {
  def head: T
  def tail: SimpleList[T]
  def isEmpty: Boolean
  def length: Int

  def ::[S >: T] (newHead: S): SimpleList[S] = new ListNode(newHead, this)
}

class ListNode[T](hd: T, tl: SimpleList[T]) extends SimpleList[T] {
  override def head = hd
  override def tail = tl
  override def isEmpty = false
  override def length = 1 + tail.length
}

object EmptyList extends SimpleList[Nothing] {
  override def head = throw new NoSuchElementException
  override def tail = throw new NoSuchElementException
  override def isEmpty = true
  override def length: Int = 0
}

val squareNumbers = 1 :: 4 :: 9 :: 16 :: EmptyList
println(squareNumbers.length)
Enter fullscreen mode Exit fullscreen mode

We have a immutable list class that stores no mutable state, but uses all features of OO design. By definition of the pure functional paradigm this is also pure functional code.

It is a common misconception that fp and oop are exclusive.

Collapse
 
drbearhands profile image
DrBearhands

FP vs OOP is a false dichotomy.

FP is about lacking side-effects, or as I like to think about it, having a complete type system (over both data and effects). It's a subset of declarative programming, which in turn is the opposite of imperative programming.

OO is a guideline usually applied in imperative languages that advocates constructing a solution in terms of 'objects' which have predefined ways in which they can be accessed.

Functional style is a guideline applied on both declarative and imperative languages that advocates passing functions around as arguments to other functions.

In theory you can combine OO and functional styles but it's rare, as limiting the interaction you can have with an object seems to go against the notion of passing arbitrary functions. But I've seen it done in Scala for big data analysis.

OO generally expects mutability of objects, which can be a side-effect and therefore appears to be incompatible with FP. This can be resolved by making all objects linear types (or uniqueness types), or simply by dropping mutability.

Collapse
 
anurbol profile image
Nurbol Alpysbayev

Want to get s**t done, but suffer from errors? Use OOP.

Want to achieve grail of programming and minimize number of errors, but waste few years (decades?) for education? Use FP.

Collapse
 
avalander profile image
Avalander • Edited

Yeah, you're right. I wondered how to include immutability, but I figured discarding the first paper would confuse a 5yo more than anything. Maybe they would just accept that one can not modify the paper once it's passed, though, I should not underestimate them.

Thread Thread
 
mfekadu profile image
Michael Fekadu

Perhaps the writing fills the entire piece of paper, thus there’s no room to write anymore, which might necessitate either
1) re-writing on a new piece of paper or
2) taping/concatenating that paper with a new piece of paper that says “are cool”?

This analogy of taping may still be non-ideal.

Collapse
 
anurbol profile image
Nurbol Alpysbayev • Edited

You probably missed the "waste few years (decades?) for education" part. Of course, having superficial knowledge of FP not only will lead to many errors, but probably will make impossible to write real FP code. You also might have missed "minimize number of errors" part. I mean you can minimize them, but not eliminate. And FP is really less error-prone compared to OOP, because there is almost nothing that can break in a small, tested, pure function, or in a chain of such functions. But the hard part is... there are gazillion of functions and you have to remember how they work.

 
anurbol profile image
Nurbol Alpysbayev • Edited

Well I saw your background thank you for sharing this observation from the "inside". It is very valuable.