The only difference is the concepts that are used to solve the problem. Any one of these can solve any problem any other can solve.
Imperative: Do this. Now do this. Now do this. Ok, you are finished.
Object Oriented: These things do this to those things. Here is a thing. Now have the thing do this. Ok, you are finished.
Functional: Everything you put in here comes out changed in this specific way. Put this in there. Ok, you are finished.
I’ll give it a shot:
Think of imperative like step-by-step recipe, for this example. When you write imperative code, you’re telling the computer what to do, sort of like a baking recipe.
Functional is like having a magical box, and whatever you put in always comes out the same. Example, if you do 2 + 3, it always comes out with 5.
Object-oriented is a little more complicated, but essentially, each toy has its own super special ability! You can tell the toy what to do based on what it represents, for example, you can tell a toy plane to fly, and it will fly for you. You can tell a toy car to “honk” and “drive”.
I don’t usually see “imperative” in this list. The lists I usually see come in two flavors:
* Imperative vs. Declarative
* Structured vs. Procedural vs. Object-Oriented vs. Functional
# Imperative vs. Declarative
In “imperative” code, you tell the computer exactly what to do.
In “declarative” code, you sort of describe some things you want, but let the computer ultimately decide how to do them.
This is really weird without examples. Let’s say I’m trying to make cheese toast. The “imperative” way to do this is:
* Obtain one piece of bread.
* Obtain one piece of cheese.
* Place the cheese on top of the bread.
* Place the cheese and bread in a toaster oven.
* Set the toaster oven to toast the desired level of darkness.
* Wait.
* Remove the cheese toast.
The “declarative” way to do it is more like this:
* Before you can remove cheese toast, the oven must be finished.
* For the oven to be finished, you need to have configured the oven and waited to hear a bell.
* Before you can configure the oven, you must place the toast assembly into the oven.
* To build a toast assembly, place one slice of cheese on top of bread.
* To be able to make cheese toast, you need:
* One slice of bread
* One slice of cheese
* A toaster oven
* To make cheese toast, do the things required to be able to remove cheese toast from the oven.
After writing all this, you tell the computer “make cheese toast”. It looks over all the steps and figures out what order it should do them in. You could even put these steps in a different order, it won’t matter.
If they look kind of the same… well, they are. Making cheese toast is pretty simple. Imagine the instructions to build a pizza at a restaurant with like, 50 toppings. In “imperative” code, we’d have to have a lot of:
* If the user wants pepperoni:
* Place this much pepperoni on the pizza.
* If the user wants green peppers:
* Place this much green peppers on the pizza.
In “declarative” code, we’d do:
* Here is a table of portion sizes for each topping:
* sauce: <this much>
* pepperoni: <this much>
* green peppers: <this much>
* …
* To build a pizza you need:
* 1 crust
* 1 portion of sauce
* 1 portion each of every desired topping
* To build a pizza:
* Spread a portion of sauce on the pizza.
* Place one portion of every desired topping on the pizza.
* Bake the pizza.
That kind of shows a difference. Imperative code is very “do this, now do this, if this is true do this, if not do that”. Declarative code is more like a lot of guidelines and eventually ends in a “simpler” series of steps based on those guidelines.
# Structured vs. Procedural vs. Object-Oriented vs. Functional
The simplest programming languages are machine code or “assembly”. These languages are “just” lists of instructions for the CPU. They are very difficult for humans to understand as they get larger.
Later, “structured” languages were developed. These languages didn’t use specific CPU instructions, as they intended to try and make programs that could run on many machines. The “structure” of these programs came from the introduction of “flow control statements” that helped deal with some common but relatively confusing things assembly and machine code had to do.
So, for example, the machine code to add pepperoni to the pizza might end up looking like:
* Look in the book for how many pepperonis should go on the pizza.
* Write that number on a post-it.
* Let me call this line “start”.
* Compare the number on the post-it to 0.
* If the number is 0, go to the line I will call “end” later.
* Place one pepperoni in your dominant hand.
* Find a part of the pizza without a pepperoni.
* Place the pepperoni on that part of the pizza.
* Subtract 1 from the number on the post-it.
* Write that number on the post-it.
* Go to the line I called “start”.
* Let me call this line “end”.
* Determine if there are more toppings…
But the “structured” code would look more like:
* Look up how many pepperonis to add, call this number “pepperoniLeft”.
* While “pepperoniLeft” is not 0:
* Place one pepperoni on the pizza.
* Subtract 1 from “pepperoniLeft”.
* Determine if there are more toppings…
See how much simpler that is? In machine code we had to be very specific about when to go “back” and do things over again and when to go “forwards” because we’re done. We couldn’t call our post-it “pepperoniLeft”, we just had to write a number down and hope the person reading our code understood what it was.
The move to object-oriented code is about managing complexity. What if it’s a restaurant with many pizza cooks, and we’re writing a program for a robot to monitor them. Each pizza chef has their own bins with ingredients, and it’s the robot’s job to look at how many ingredients they have left and decide if it’s time for a refill. Doing this in a structured manner would work something like this:
* Determine the ID number of the cook who owns this station.
* Check the pepperoni bin that belongs to the cook with this ID.
* Check the green pepper bin that belongs to the cook with this ID.
* …
Object-oriented code notices that it’s kind of awkward to keep referring to the cook by an ID like that. In this kind of code we’d write it more like:
* Go to the next cook’s station.
* Check the cook’s pepperoni bin.
* Check the cook’s green pepper bin.
* …
For a lot of code, this is only a *subtle* improvement. You really have to see actual code to understand why it’s so much easier to understand.
For example, this bit of code is how I’d tell a text box in a Windows program to have the word “hello” in it using a C-like language and the procedural Windows API:
SendMessage(hwName, WM_SETTEXT, null, “hello”);
This is telling Windows to:
* Send a message, which is how we make controls do things:
* To the control identified by “hwName”, which is a “handle to a window”.
* The message is “WM_SETTEXT”, which is how it knows to change its text.
* The “lparam” is “null” because this message does not use this parameter.
* The “wparam” is the text we would like the control to change it to.
The object-oriented code to do this in Windows Forms, a C# framework that is object-oriented, looks like:
txtName.Text = “hello”;
This tells the program:
* I have a control named “txtName” and I’d like to do something with it.
* I am setting its “Text” property to the value “hello”.
“Objects” in object-oriented code have “properties” that represent the data they hold. They can also have “methods” that represents the things they can do.
In structured code, there aren’t “objects”. So instead these programs tend to have big fat data tables where an “identifier” is used to tell it which thing we’re working with and further “parameters” to a method help define what data we want to change or retrieve.
Functional programming isn’t very different from object-oriented code in this kind of example. It has some… weird concepts that are hard to ELI5. In a functional program, the programmer becomes tasked with defining a “state” representing the program’s data. The “state” can be changed if something happens, and the code the programmer writes is mostly a big glorified “call this function if this happens and update the state with new results”. GUI code like I demonstrated above is notoriously hard to write in functional languages for, again, very complex to describe reasons.
One way to put it is everything here has been imperative. But functional programming can get sort of declarative. It is best at solving problems where you provide some inputs, then let it do its thing, then read the outputs, then the program is over. Managing programs that take some inputs, do some things, provide outputs, then let you provide new inputs to get new outputs requires a concept called “state” that is generally frowned upon in functional programming. But people are incredibly smart, and realized a certain kind of math functional languages are good at can tolerate the concept of state, then they ran with it.
Someone who is very experienced with it might tear my example apart, but I’ll try. In a functional program we might end up with something roughly like this:
* Let’s make an object called “the program state”. It has a “first name”. This object is “the current state”.
* Let’s make a function called “Change First Name”. To call it, you need to provide a new name.
* This function returns a new “program state” object that is a copy of “the current state” except “first name” is now the new name.
* WHEN this text control’s text changes, call “Change First Name” with the new text.
Again, it looks very declarative. This is a lot of, “Here’s how you do this,” then a few lines that say, “When this happens, do this.”
Functional programming is VERY good at math algorithms, particularly ones that can divide the work into “chunks”, work on the “chunks” in parallel, then combine all of the results at the end. Looking back to pizza analogies, it’s best suited for a robot that knows there are 10 chefs and 100 pizzas to make and it needs to figure out which chefs should make what pizzas so everyone finishes at about the same time. The slightly more declarative style makes this kind of problem a little easier to solve with functional languages.
—
Most modern languages are object-oriented, but there’s been a shift in the last 10 years. Functional languages got very popular again, so the most popular object-oriented languages have been adopting some features from functional languages. Describing how that works takes a lot of explanation. I’d have to teach you how a feature called “polymorphism” works in an object-oriented language, then how that’s really just a concept called “indirection” and it can be implemented in procedural or functional languages.
Hey, you covered the main ones, but there are several other programming paradigms, including some rare ones. Here’s a more comprehensive list:
– **Imperative Programming**: Writing explicit step-by-step instructions for the computer.
– **Object-Oriented Programming (OOP)**: Organizing code into objects with properties and methods.
– **Functional Programming**: Using pure functions and avoiding state changes.
– **Procedural Programming**: A subset of imperative programming focusing on procedures or routines.
– **Logic Programming**: Using formal logic to express computations (e.g., Prolog).
– **Declarative Programming**: Describing what the program should accomplish, rather than how to accomplish it.
– **Event-Driven Programming**: Building programs that respond to events or user actions.
– **Concurrent Programming**: Writing programs that can execute multiple tasks simultaneously.
– **Aspect-Oriented Programming (AOP)**: Separating cross-cutting concerns to improve modularity.
– **Constraint Programming**: Defining constraints that need to be satisfied by the solution.
– **Reactive Programming**: Working with asynchronous data streams.
– **Dataflow Programming**: Modeling programs as a directed graph of data flowing between operations.
– **Agent-Oriented Programming**: Using autonomous agents with behaviors and goals.
– **Prototype-Based Programming**: Creating objects based on a prototype instance, without classes.
Each paradigm offers different approaches and benefits depending on the problem you’re trying to solve.
That’s ChatGPT, that’s not me, I don’t know all of them.
Latest Answers