Programming Paradigms

Programming Paradigms

Continuing the theme of digging deeper into topics I'm familiar with but not an expert in, today I want to focus on programming paradigms.

What are programming paradigms?

Programming languages can be designed to accommodate what "style" of programming you can do with them. This is not to say, what you can build with them, but more of how you build with them. A paradigm is an abstract way of thinking about writing code. This is what I understand about it at the moment. I will have to look up the definition and come back here.

Ok so I was not too far off, this is from Wikipedia:

Programming paradigms are a way to classify programming languages based on their features. Languages can be classified into multiple paradigms.

At this point, I ran into an interesting issue. Wikipedia mentioned "programming models" which is a term I haven't used before and haven't heard much before so I started looking into this.
Both programming models and programming paradigms almost step on each other's toes when being defined and I'm going to try my best to separate out the two. A programming model is a way to structure code and/or how a program's design is implemented at a high level. While a programming paradigm is a fundamental way of thinking about how a problem can be solved using a specific language.
I think I'll have more differentiation in the examples below

Examples of programming paradigms

Let's list some programming paradigms so it might make more sense.

Declarative programming

This paradigm focuses on what you expect to see as a result of writing some code, it is usually found in languages like SQL, HTML, and CSS. These examples are all languages that are not general purpose programming languages and are instead used for specific purposes. In the SQL example, you are telling the database to give something back based on a statement instead of computing or using a lot of logic. Logic is possible in declarative programming but it's more oriented towards rules or conditions instead of loops and computed checks.

Here's a CSS example of something completely declarative:

h1 {
  color: blue;
  font-size: 24px;
}

In this CSS example, we're not checking or referencing anything and in general just telling the rendering engine what the color and font size should be.

And a SQL example:

SELECT name, age FROM users WHERE age > 25;

In the SQL example, it's all declared to the database engine instead of anything being calculated or determined in the code.

I learned a lot about declarative programming from this Stack Overflow answer →.

Imperative programming

Naturally, the next paradigm that makes sense to look at is something that contrasts pretty hard against declarative. Instead of being declarative statements of what a program should do, imperative programming uses statements that change the program's state as it runs. It tells the program "how" something should be done.
Imperative programming is made up of procedures or functions which is also why it's sometimes called procedural programming.
There are a lot of programming languages that use imperative programming, like C, Python, Javascript, Java, and so many more.
Below are some examples of the same thing being accomplished with these two different paradigms:

Addition example using declarative programming

const numbers = [1, 2, 3, 4, 5];
const result = numbers.reduce((acc, current) => acc + current, 0);
console.log(result); // prints out: 15

Addition example using imperative programming

function sumArray(arr) {   
	let sum = 0;   
	for (let i = 0; i < arr.length; i++) {     
		sum += arr[i];   
	}   
	return sum; 
}  
const numbers = [1, 2, 3, 4, 5]; 
const result = sumArray(numbers); 
console.log(result); // prints out: 15

Both these examples accomplish the same thing but in the imperative example, we can reuse that sumArray function in multiple places, it's the "how" to do the addition, while in the declarative example, we simply do the math by using numbers.reduce() which makes code very clearly a one-time use.

What about object-oriented programming?
Object-oriented programming (OOP) takes imperative programming one step further by introducing the use of objects which can contain both data and code. The "code" in these objects is usually methods (functions within objects) which are more generally just procedures.
OOP also allows us to model real-world concepts as objects, like a 'person' object with properties such as name, age, and location, and methods to interact with the object. The person object would contain properties (data) like name, age, location and it would also have methods (procedures) which would allow you to add them as a friend, message them, or view a computed value like their full name in a sentence. OOP also introduces many other programming concepts like encapsulation, inheritance, and polymorphism which I'm not going to get into today.

Functional programming

This one is a subset of declarative programming. Functional programming is a loaded term, it can be a subset of declarative programming or it can be a purely functional programming which treats all functions as deterministic mathematical functions (aka pure functions). Functional programming emphasizes preventing side effects while running a program. This means if a function is written to simply do one thing and does not produce any side effects, there's potentially less room for errors or bugs. Haskell is a common example of a programming language that uses functional programming. Javascript can have functional code coexist with other types of code like imperative or declarative.

Addition example from before using functional programming

function add(a, b) {
  return a + b;
}

const result = add(3, 4);
console.log(result); // prints: 7

In this example, the add function will always return the same thing as long as the same input is given. The function also tries not to have any side effects like a console.log or some other unrelated operation.

Logic programming

This is brand new to me, I have been skimming through Wikipedia and ChatGPT to get a grasp of it. Logic programming is based on formal logic. It is declarative but unlike declarative programming where you state "what" you want, you can use it to build expert systems (decision making like humans) and natural language processing (NLP) and artificial intelligence. Rule based systems can also use logic programming to answer questions about a heuristic like fraud, trust, quality, etc.
Unlike other programming paradigms, in logic programming, you write statements and rules, and the computer determines the answer based on these rules.
The computer determines the answer based on the rules and statements you've provided to it.

I got the following example from ChatGPT so take it with a grain of salt.

% Define the criteria for a fraudulent user
fraudulent_user(User) :-
    has_many_accounts(User),
    has_unusual_activity(User),
    has_recent_suspicious_activity(User).

% Define predicates for various conditions
has_many_accounts(john).
has_unusual_activity(john).
has_recent_suspicious_activity(john).

% Sample user data
user(john, "John Doe", "johndoe@email.com").

% Query to check if a user is fraudulent
% Example: Is John a fraudulent user?
% Query: fraudulent_user(john).
% Expected Output: true (since John meets all the conditions).

In this example we're trying to determine if the user is fraudulent based on the various predicates. It's weird to me because it reads pretty much like a declarative language but I'm guessing this is because I'm looking at it from a decade plus of declarative and imperative programming experience.

Symbolic programming

The last one for today that I'm learning about is symbolic programming allows a program to manipulate its code as data. Lisp introduced symbolic programming. You can use symbolic programming to solve mathematical proofs and evaluate expressions on the fly. By the end of learning about symbolic programming, I didn't come away with a use-case for my own day to day programming but it's one of those things that will make sense over time.

Conclusion

Each of these programming paradigms really opened up old pathways in my brain that haven't been thought about for a long time now. Writing this up and then learning about new ones was a good use of time today.