Function vs Object
(Source/Credits: https://dev.to/stereobooster/function-vs-object-1pe3)
There is an ongoing discussion about the difference between object-oriented programming (OOP) and functional programming (FP). Let's talk about similarities instead. Let's talk about the main building blocks: functions and objects.
title: Function vs Object published: true canonical_url: https://stereobooster.com/posts/function-vs-object/ series: "fp vs oop" draft: false tags: [beginner, explainlikeimfive, computerscience, javascript] description: "There is an ongoing discussion about the difference between object-oriented programming (OOP) and functional programming (FP). Let's talk about similarities instead. Let's talk about the main building blocks: functions and objects." cover_image: https://thepracticaldev.s3.amazonaws.com/i/f3dlty7lxhc2bjyuc5yq.jpg
There is an ongoing discussion about the difference between object-oriented programming (OOP) and functional programming (FP). Let's talk about similarities instead. Let's talk about the main building blocks: functions and objects.
If I won't be lazy this is gonna be a series of posts.
What is an object?
I tried to find a good definition, but it was harder than I thought a lot of sources talking about what is OOP, but nobody bothers to explain what is an object.
Let's go with object definition from Java, I guess:
Objects are key to understanding object-oriented technology. Look around right now and you'll find many examples of real-world objects: your dog, your desk, your television set, your bicycle.
Real-world objects share two characteristics: They all have state and behavior. Dogs have state (name, color, breed, hungry) and behavior (barking, fetching, wagging tail). Bicycles also have state (current gear, current pedal cadence, current speed) and behavior (changing gear, changing pedal cadence, applying brakes). Identifying the state and behavior for real-world objects is a great way to begin thinking in terms of object-oriented programming.
Pretty approachable definition. I will rephrase it a bit. The object is a state with a behavior attached to it.
What is a function?
I wrote 2 posts about it:
Let's go with the simplified definition (in the same vein as the object definition) and say that function is a behavior (for precise definition see links above).
In functional programming, they like to pass functions as values, to be able to do this functions "converted" to closures (converted is not a precise word here, because closure is a function with free variables, but let's go with a simplified view).
What is closure (in programming language)?
Closures are data structures with both a code and a data component.
I will rephrase it a bit. Closure (or function as value) is a behavior with a state attached to it. (State, in this case, is immutable. I refer to any data as a state)
Wait a second 🤔
Compare those 2 definitions again:
- The object is a state with a behavior attached to it
- The closure (or function as value) is a behavior with a state attached to it
Aren't they the same?
I don't believe it. What is your proof?
Let's write some codes. I will use JavaScript because it supports both paradigms.
js
class DogClass {
#name;
constructor(name) {
this.#name = name;
}
bark() {
return `${this.#name} is a good dog!`;
}
}
const belka = new DogClass('Belka');
belka.bark();
Note: this example uses "Class field declarations for JavaScript" proposal to declare private field name. At the moment of posting example works in Chrome.
js
const DogFunction = (name) => {
return {
bark: () => {
return `${name} is a good dog!`;
}
}
}
const strelka = DogFunction('Strelka');
strelka.bark();
Note: function returns record data structure (which in JS confusingly named "Object", but we don't use any "objecty" feature we use it as a simple key-value data structure). Variable name
privately stored in the scope of a closure, there is no way to access it outside.
Not a new idea
If you think about it makes a lot of sense: all computers deal with state (data) and behavior. This idea was discovered again and again:
Here is how Lamport defines computation:
There are several ways to define computation. For now, I take the simplest: a computation is a sequence of steps, which I call a behavior. There are three common choices for what a step is, leading to three different kinds of behavior:
- Action Behavior. A step is an action, which is just an element of some set of actions. An action behavior is a sequence of actions.
- State Behavior. A step is a pair
(s, t)
of states, where a state is an element of some set of states. A state behavior is a sequences1 → s2 → s3 → · · ·
of states. The step(si, si+1)
represents a transition from statesi
to statesi+1
.- State-Action Behavior. A step is a triple
(s, α, ti)
, wheres
andt
are states andα
is an action. A state-action behavior is a sequences1 -α1→ s2 -α2→ s3 -α3→ · · ·
. The step(si, αi, si+1)
represents a transition from statesi
to statesi+1
that is performed by actionαi
.-- Computation and State Machines. Leslie Lamport, 19 April 2008
Wirth wrote the book "Algorithms + Data Structures = Programs".
Ray Toal wrote about types: A type consists of a set of values and a set of allowable operations.
PS
The question which we haven't touched is a mutation. In "pure" FP, mutations are not allowed. In OOP they are allowed. When I say pure I mean lambda calculus with lazy evaluation and IO monad, which is a narrow area ¯\_(ツ)_/¯
.
Photo by NordWood Themes on Unsplash
Comments section
kelleyvanevert
•May 1, 2024
Yes, I love this insight, also known as: "Objects are a poor man's closures!"
For example, for better or for worse, d3 uses a lot of this (closure state instead of objects) in their API. See e.g. github.com/d3/d3-scale/blob/master...
wiktorwandachowicz
•May 1, 2024
Ok, just three silly questions.
1) How do you model and use in FP relations between domain "things", like orders, clients, suppliers, goods, invoices, organizational units, etc.?
2) How do you handle in FP graphical user interfaces with widgets?
3) Are there easy to follow FP frameworks based on MVC patterns, for example?
stereobooster Author
•May 1, 2024
This is kind of out of the scope of the post. I didn't try to compare the whole FP vs OOP. I simply presented a small slice of FP and OOP that has similarities (closures and objects as value).
There are different approaches, but I guess simple data structures would work - lists, trees, graphs? The question is too broad.
Broad question. It can be interpreted in different ways, for example, take a look at how they do it in Elm.
¯\_(ツ)_/¯
In FP they don't use design patterns. Read the next post in the series for details.
stereobooster Author
•May 1, 2024
Yes it uses free variables. My question is
closure ≡ open lambda term
(open lambda term - the one with free variables)? Because from implementation point of view closed lambda terms can be closures as well.(This is just some thoughts out loud. Not questioning your comment)
codemouse92
•May 1, 2024
Basically, from what I've understood, a closure is still functional, but according to some purists, it's not "pure functional" because it has state.
Not that I really prioritize "purity" in terms of functional programming. Avoiding state is good for the most part, but at some point it becomes relatively impractical. Common sense required.
stereobooster Author
•May 1, 2024
I tried to find the source for this definition (which I remembered myself, but wasn't sure where I got it from, probably from exactly this wiki). Interestingly nothing else refers open lambda term as closure. In every source that I met closures are treated as implementation detail of lambda terms🤔.
(I agree that closures are "functional", this is lambda term + environment)
rbilash
•May 1, 2024
Sorry to say man but it is all terribly wrong, objects are not state with attached behaviors, they are holding a state but not state itself. Functional programming is against manipulating state, it is declarative. In FP "they" don't like to pass function, it is not a key principle but just a result of principles of FP. You have started with wrong assumptions and make totally wrong conclusions, however it was curious to read.
stereobooster Author
•May 1, 2024
Ok, not sure where to start here...
codemouse92
•May 1, 2024
Functional Programming is not just made up of functions, but of pure functions. You've already started to touch on this, but these are the most important traits of a pure function according to FP:
That said, I have a feeling you're going to go into all this later? (At least, I hope you will.)
stereobooster Author
•May 1, 2024
I don't want to touch the whole surface, I would need to explain, lazy evaluation, side effects, IO monad (I'm not ready for that one). So I keep it simple for now.
Why not? Closures with mutation and re-assignment are not pure FP, but otherwise...
jamesmh
•May 1, 2024
I think it's an even more interesting question to ask "What were objects intended to be in the first place?"
Alan Kay is considered one of the fathers of OOP. Here's his take on what he intended objects to be:
So, while it's true that objects can be viewed as are merely state + behaviour, that was not necessarily the original intent.
Kay also said:
In other words, he didn't want objects to be passing data to each other (directly). He wanted objects to send messages to each other - and the messages themselves might happen to have data inside them, if needed.
In another place, Kay said:
For those interested, I'd highly recommend looking into the actor model. I think this represents a closer realization of what Kay intended.
On a larger scale, something like event-driven microservices is also within this line of thinking.
stereobooster Author
•May 1, 2024
I plan this as a series of posts. At some point I want to write posts "What is OOP?" and "What is FP?". The problem with the definition of OOP is that there is no single right definition. I consider 3 main sources (which have equal rights): Simula (Ole-Johan Dahl, Kristen Nygaard), C++ (Bjarne Stroustrup), SmallTalk (Alan Kay).
I need some time to gather full picture, meantime you can consult with those sources:
Interpretation of OOP as
The big idea is "messaging"
is pretty close to the idea of actor model:olvnikon
•May 1, 2024
Well, the FP example looks the same because it is, actually, almost the same. The function returns an object. "bark" is a function with a side effect. In FP world this kind of function would be executed in some IO structure. At least it should return something, e.g.:
`` const bark = name => { console.log(
${name} is a good dog!`); // Dirty side effect return name; }```
Bark in DogFunction becomes a map function:
``` const DogFunction = name => { return { map: f => { return DogFunction(f(name)); } } }
```
Then we call it like this:
``` const dog = DogFunction("good boy"); const dogAfterBark = dog.map(bark); // logs "good boy is a good dog!" and return a new dog
```
This is how I see the example with a dog.
Edit: added code parsing
stereobooster Author
•May 1, 2024
This is JS specifics, I don't have other key-value data structure
This was for the demo purpose, changed it to return.
sebbdk
•May 1, 2024
OOP has hammers, functional programming has the ability to smash things.
Advocates of OOP, like having specific things to smash with. Advocates of functional programming think just being able to smash is enough because they aren’t throwing thunderbolts, like hammers also can do.
When it comes down to it, if we measure by smash, both Hulk and Thor do it quite well.
It really just comes down to the style of smashing you like to do.
mjölnir.smash() or smash()
vlasales
•May 1, 2024
OOP: mjölnir.smash()
// mjölnir is an object
FP: mjölnir.smash()
// mjölnir is a namespace