Programming Paradigms
Programming Paradigms are ways to classify programming languages based on their features. They are how methods to solve a problem using tools and techniques that are available to us following some approach or strategy, and languages can be classified into different paradigms depending on their properties. There is also no strict form of a paradigm: some can consist mainly of the implications of the execution model for a language or whether it defines the sequence of operations explicitly, and others can be concerned only with how the code is structured and organized, like grouping code with the modified state. Other paradigms mainly involve syntax and grammar. Despite its vagueness, it’s mainly just a classification system to describe programming languages and their functionalities.
There are two main types of Programming Paradigms: Imperative and Declarative. Imperative programming is when a programmer instructs a computer to change its state (seems obvious, but is actually a distinguishing feature). With commands for the computer to perform, imperative programming tells the computer "how" to accomplish a task, not just to do it. It uses explicit and defined step-by-step code to achieve this. There are many imperative languages with some of the most commonly-used and well-known being Python, Java, C#, and C++. Some of its advantages include its ease of reading, its conceptual nature, and its facility of learning, but this can also lead to extensive and complicated code, lots of errors, and difficulty in optimization and extension.
A subset of imperative programming is Procedural Programming. Often used synonymously, procedural programming is a type of imperative programming where the program is built from procedures or functions, but it still make explicit references to the state of the execution environment. Typically, procedural programming makes use of blocks and and scope, such as “if” and “while” statements to ensure control flow, which is the order in which commands or functions are executed. It’s really helpful just for general programming, and has most of the same advantages that come along with imperative programming.
Another form of imperative programming is Object-Oriented Programming. It’s based on the concept of “objects”, as its name suggests, which can contain data in the form of fields and code in the form of procedures (hence the relation to procedural programming and imperative programming), instead of functions and logic. In Object-Oriented Programming, computer programs are designed by making them out of objects that interact with one another, and it’s very useful when working collaboratively, since the code is easy to be divided into groups, and it also allows for more reusability and scalability.
Another type of programming paradigms is Declarative Programming. Unlike imperative programming, which tells the computer how to perform a program, declarative programming tells the computer what to accomplish. To analogize the differences, imperative programming is like a recipe to cook something, while declarative programming is like a picture of the final product for the cook to recreate. While declarative programming is pretty abstract, overall they always describe the desired end result rather than outlining all the intermediate work steps, and the solution path is determined automatically by some form of algorithm. Since it works at a high level of abstraction, it can be optimized a lot and improved as time goes on. Some languages that utilize declarative programming are Prolog, Lisp, and Miranda (and SQL but in a very broad sense). Some advantages are that it produces short and efficient code, with easy optimization and maintenance, but it can be hard to understand for external people and it’s hard to really look at the characteristics of the code.
A sub-type of Declarative Programming is Functional Programming. Again, since it is a form of declarative programming, it is very high level and tells the computer what to accomplish. However, it evaluates expressions via functional application, placing little emphasis on explicit sequencing and uses more recursive higher-order functions. It works by composing pure functions, avoiding shared state, mutable data, and side-effects. But overall, it helps make the code more efficient and easier to optimize.
Ultimately, these different paradigms should be taken into consideration when beginning a project, and should be chosen based on what would be most effective for the team. They each have their advantages and drawbacks, but they are extremely important to understanding different programming languages and how to incorporate them in really complex projects.