Four Paradigms every developer needs to know

FImage by Arek Socha from Pixabay

In this paper, the term

  • PP Procedural programming
  • FP Functional Programming
  • LP Logical Programming Logical Programming
  • OOP Object-oriented Programming

I’m a big believer that as a developer, you need to understand how something works outside of your comfort zone, even if you never intend to step outside. The very fact that you know there are different ways to do one thing opens your eyes to new methods and techniques.

Of course, you have to try, otherwise you won’t really learn, however, the jump from “read” to “try” isn’t really that big, so try one or more of the four programming paradigms I’ll mention here. You may learn a thing or two while doing this, and if you happen to use a language that is compatible with more than one of these paradigms, you can easily try them out.

Open dry!

Process-oriented programming

Most developers start programming from this paradigm, even if they don’t know its name. However, once they start learning the paradigm, they often confuse it with functional programming, since most modern programming languages rename the word “procedure” to “function.” This leads to awkward moments in technical interviews when developers are asked about FP and claim to have used it for years, but are unable to answer questions such as “* What is a pure function?” * or “What is HOF?” Questions like that.

PP does nothing more than work with programs (also known as functions) and regular data structures. We are not talking about “functional programming” here, because this paradigm does not cover concepts (such as higher-order functions) that are unique to functional programming.

Why is PP(Procedural Programming) so special?

It’s easy to learn, which is why most developers (both self-taught and those from universities and other places) tend to learn this programming paradigm first. You don’t need to know a lot of complicated concepts to master it. Once you understand what basic types, control flows, and conditional expressions are, the next logical step is to understand how to combine these lines of code into something that can be called multiple times from different places. In other words: a program.

Many languages allow you to work this way because they don’t force you to use a particular paradigm. Examples include JavaScript, Python, PHP, and so on.

Was that a good paradigm at the start of your career? Yes. It has two main features that make it a top choice: first it’s simple, and then you can do anything with it.

Disadvantages of procedural programming

Is it a good paradigm for large teams working on large projects? Maybe not. While you may be building great software with it, you either extend this paradigm with concepts from other paradigms, or you don’t use a more appropriate paradigm.

The main problem with procedural programming is that it is too simplistic.

  • You cannot logically group states and behaviors unless you have modules. If you use them to simulate classes and objects, you are not using procedural programming, but using concepts from other paradigms.
  • Because you can’t use some of FP’s concepts, you have to write prescriptive code, which is harder to parse and understand than declarative code. In other words, you’re not tellingCompiler/parserYou want to do what the code does after execution, but rather tell it how it needs to happen. This is the"For each element in this list of elements, multiply by 2 one by one and store the result at the end of the new list I just created. "* (imperative)with"* Store the result of the mapping of each element in this list in the new variable I just created "* (declarative)The difference between.
  • Without providing an elegant alternative, there are typically bad uses, such as the abuse of global variables. Of course, you can pass properties between function calls, but if you have many nested calls, you may end up having parameters from the global context (global variables) passed into the function call, just so they can be used at levels below 3.

Examples are as follows:

const myName = "Fernando" function startProcess(name) { //... bunch of logic secondStageOfProcess(name); } function secondStateOfProcess(name) { //... bunch of more logic startThinkingAboutGreetingUser(name) } function startThinkingAboutGreetingUser(name) { //... even more logic here sayHi(name) } function sayHi(name) { console.log("Hi there", name, "!" ) } startProcess(myName)Copy the code

The code above is bad because we have to pass the myName constant through three different functions before we can get to the logical part that really needs it. This creates a lot of clutter in the code, making it both difficult to read and difficult to maintain.

Let’s take a look at some alternatives that extend the concept of procedural programming to create a better development experience.

Tip: Build everything from separate components

Say goodbye to indie apps and leave the tears of development behind you.

The future is componentized and modular software that is faster, more scalable, and easier to build. Open source software tools like Bit provide a great development experience for building standalone components and applications. Many teams use bits to build their design systems or microfront-end systems. Try a Bit →

The figure above shows a separate source control and shared “Card “component. On the right is the dependency graph for =>, automatically generated by Bit.

Functional programming

FP is a paradigm that is very easily misunderstood, often in terms of its scope of application, which is that it is primarily used in formal education. You see, a lot of college-going developers learn FP from languages like Haskell and Clojure, but the use cases they’re involved with are usually mathematically oriented.

Don’t get me wrong, this is a very pure way of learning, and if you’re lucky enough to have been studying this topic, you’ll find that FP can actually be used in many real-world applications, and it makes things easier.

However, this is not the case, and many developers are unaware that they have a JVM-based language to use, Scala, and many of the main concepts of JavaScript support for FP, which are available right out of the box.

What are the advantages of FP?

If you ask me why I like FP, one of its first advantages is that you can easily write declarative code.

You can just describe what your business logic does without getting into the implementation details.

Let myInvoices = filterOutPaidOnes(filterByThisMonth(getInvoices()))) //.. or perhaps something like this let myInvoices = getInvoices( filterByCurrentMonth( filterOutPaidOnes ) )Copy the code

None of the examples above are commented, but you don’t need to understand the language to understand the logic. The first example is kind of a mathematical concept, it’s very similar to f(g(x)), you first need g(x), then you call the function f. And then, the function has to have a name, give the name to the function and you can figure out the logic of this.

Another advantage is that in FP we are dealing with the concept of “pure functions” (a function that has no side effects and returns the same output every time the same input is executed), which simplifies some tasks such as:

  • Unit testing. It’s much easier to test something that you know is impossible to affect outside of its scope.
  • Safer, because there are no unforeseen side effects (i.e. you can’t accidentally change a global variable by calling a function)
  • The signature of pure functions is more meaningful than that of ordinary functions. This is mainly because ordinary functions don’t have to follow strict specifications, they can read data from outside (even from global scope), and their output is similarly unconstrained. Given the way pure functions work, they don’t have this permission, so function signatures are key to determining what data they can access and what, if anything, they return.

What are the disadvantages of FP?

The main drawback I know is the way functional programming is usually taught. Limited by the types of problems they are taught to solve with FP (mathematical problems), students often overlook the fact that it is a very useful method.

In fact, few of the languages used in FP occur outside of an educational setting (when was the last time you saw a Haskell program run outside of academia?). This means that even if they wanted to use FP, it would be difficult for them to deduce the corresponding knowledge on their own, because they don’t have the right tools to start with.

Conversely, if they also see more real-world use cases, such as those that combine functional programming with other paradigms like Python and JavaScript, they will quickly see the benefits and quickly fall in love with it.

Note that I don’t think Haskel, Clojure, or any other language used to formally teach FP should be banned. However, the “purist” approach commonly taken may benefit from taking a more pragmatic line.

Logic programming

Logical programming is very different from other patterns in that it breaks patterns in every way when it comes to solving problems.

If you missed FP, I hope you don’t miss this one.

Logical programming is another paradigm that is very rooted in mathematics and logic. Instead of dealing with code, loops, and conditions, it deals with facts and rules. Let me explain.

In the LP world, when you want to solve a problem, the solution takes the form of an answer to a problem. In order for you to be able to ask this question, you first need a context.

So, you start stating facts that are basically true things about entities. For example.

Einstein is a scientist
Copy the code

That’s great. That’s our reality. No one would dispute that fact.

Second, we start writing rules, which are inferences about our field (in this case, about scientists).

All scientists are smart
Copy the code

Finally, there’s our question, which is what we wanted to know in the first place.

Is Einstein smart?
Copy the code

According to our facts and rules, the answer to our question is, of course, ‘yes’. While this example is silly and simplistic, it also shows the amazing power of logical programming. Because I didn’t write a single line of code, not the kind of code we’re used to writing.

I didn’t set up a list of smart people’s characteristics, nor did I write an IF statement anywhere. To be honest, I’m just looking directly at the issue at hand, and the low-level stuff is inferred by the interpreter. Cool, huh?

One of the major LP languages currently available is Prolog, which is used in some very niche areas of the industry, although you’ve probably never heard of it. If you want to learn more and see more interesting examples of how LP can be used for more than just answering a very simple question, check it out.

Have you ever heard of Prolog?

A quick review of this lesser-known programming language and why it’s likely to shape your career

betterprogramming.pub

What’s the downside of Prolog?

Yes, there is, but it doesn’t make it useless, it just makes it unknown to most of our community of developers. The main downside is that it works so well at solving very few and very limited set of problems, that most developers (who have never had to face such problems) don’t know about it.

In fact, many developers delving in AI for example, which is one of the main industries where it’s being used right now, use other classical approaches because they’ve never heard of it. That’s how niche LP is!

The other problem with LP is that it’s so different from The way we’re used to code, That honestly considering it as an actual solution to one of our problems becomes a leap of faith. Until you’ve tried it and played around with it long enough, You won’t really be able to understand if this is the right tool for the job. And even if you think you see the potential of LP, making the jump and using it will require a lot of practice and headaches.

Don’t get me wrong, if you’re considering LP, go for it, give it an honest test drive. But make sure you understand that picking up Prolog or any other LP alternative is not like going from PP to FP, the distances are longer and the mental model switch will be bigger.

Yes, there is, but that doesn’t mean it’s useless, just that most developers don’t know about it. The main drawback of Prolog is that it works so well at solving so few and limited problems that most developers (who have never encountered such a problem) are unaware of it.

In fact, many developers deep into AI (one of the major industries using AI right now) are using other classic methods because they’ve never heard of it. That’s the niche of LP!

The other problem with LP is that it’s so different from how we’re used to coding that it’s a leap of faith to think about it as a practical solution to one of our problems. Unless you’ve tried it and used it long enough, you won’t really know if it’s the right tool to work with. And, even if you think you see LP’s potential, using it proficiently will require a lot of practice.

Don’t get me wrong, if you’re thinking of using the LP, go ahead and give it an honest test drive. However, make sure you understand that picking up Prolog or any other LP alternative is not as simple as going from PP to FP, the distance is longer and the mental model shift is greater.

Object-oriented programming

Finally, OOP is the last paradigm I want to cover. Most of you probably know it and have been using it for years, but I’m sure others don’t, which is why I thought I’d introduce it here, too.

Maybe you’re just getting started, and the language you’re using doesn’t enforce OOP, but does allow you to use object-oriented concepts. This is a great way to get started, because you can slowly start incorporating more and more things into the programmatic environment.

So, what is OOP? Well, in the OOP world, you take a very physical approach and represent your problems through concepts like classes and objects. In other words, you try to attribute attributes to the entities you want to deal with as if they were physical objects sitting next to you. For example, if you’re considering the concept of representing a door in a video game, you might create a class that represents the type of object, such as’ gameobject ‘, with features such as the coordinates the object is in, the game scene it should appear in, and maybe even a numeric value that represents the hit ratio of the door. The point is that you have classified it as a “gameobject”, and by doing so, you have given it attributes that other objects in the game world may share (other “gameobjects”, if you will).

This general classification that allows you to group entities together is called a class, and every entity that fits into that class is called an object.

Note that while these concepts are great for representing real-world objects in our code, they can be used to represent any type of entity. For example, a linked list of values can be represented by several classes, which makes little sense. But the fact that you turn these abstract concepts into physical objects in your head is what makes OOP so intuitive, at least as far as the basic concepts of the paradigm are concerned.

What are the advantages of OOP?

How is OOP better than FP? That’s not the right question. They’re not as good as each other! They just have their strengths.

Some people may prefer OOP to FP, while others prefer other paradigms, depending on the problem to solve.

That being said, OOP has some advantages:

  1. Depending on how OOP transforms abstract concepts into physical objects, you can use diagrams (such as UML) to represent these objects and the relationships between them. This allows you to represent a high-level overview of complex business logic graphically. You can show others your ideas and concepts before you write the next line of code.
  2. It’s a pretty straightforward way to think about it. Not every problem can be solved using OOP, but it is much easier to find the answer by thinking about the problem in this way. Our way of thinking is to deal with them and manipulate them, so thinking in them is second nature to us.
  3. Logic is where logic is supposed to be. Think of it this way except for the nature of the door, evenGameObjectYou want to interact with other objects besides. Which approach makes more sense? Do you put this code in a separate file, full of unrelated functions, or do you put everything in a single file, all within the scope of an entity called a “class”, and make sure that every instance of it (but no other) has access to the code?
  4. There are plenty of pre-established patterns to help you solve your problems. Partly because of paradigms, and partly because OOP is so widely used, many developers have come up with design patterns to template typical solutions. For example, if you need to access an entity that can only be instantiated once, you might use the singleton pattern, if your logic needs to observe and react to some objects, you might want to look at the Observer pattern, and so on. They are not pre-built solutions, but rather templates that you can incorporate into your code to help you find the best way to solve the problem.

The list goes on, it’s one of the major programming paradigms out there, and it’s been analyzed, studied, and stretched to its limits.

Is there a downside to OOP?

B: of course! When it comes to programming paradigms, there are no silver bullets, and OOP is no exception.

Some questions do not lend themselves to reasoning with physical objects. This means that, with an OOP approach, you are trying to force a square into a circle. If the circle is big enough or small enough, it will fit, it will work, but it will never be a perfect match.

Another drawback of OOP is that it is too complex. I’ve only scratched the surface of OOP here, and I haven’t talked about inheritance, encapsulation, polymorphism, and all the fancy words that have grown up around this paradigm.

Fully understand and leverage OOP with a combination of years of reading and experience. Mind you, it doesn’t make it any less powerful, but it’s by no means easy to learn.

Finally, because it is a powerful paradigm, some languages take it to extremes, incurs a lot of overhead just to comply with every point of the paradigm. Let me explain: Some languages are 100% OOP, which means they don’t accept any other options, and if you use them to solve simple problems, you’ll have to write more template code to solve the problem at hand. Of course, this makes sense if you’re developing a large application that requires a lot of internal structure. So it’s a matter of using them to solve the right type of problem.

I always say that programming languages are like tools, you need to use the right tools for each job, and the same goes for programming paradigms. They are not meant to solve every problem, and some of them work better on a broader scale, while others are less flexible. In both cases, if you understand the types of problems they help solve, and which languages can help solve one of them, you can get the most out of them.

As a developer, understanding the different paradigms will help you think about the way to solve each problem. If you’re lucky enough to use a language that allows more than one, you can adjust your coding style without changing the language. It’s a great way to practice new paradigms with minimal impact.

What other paradigms have I missed that you think are important to others? Leave your thoughts in the comments!