Functional Programming – The Starting Line
Functional programming feels like a secret club that only the brave of heart may enter. It just so happens that it’s become a popular programming paradigm. Now, what’s a programming paradigm? Let’s explore that concept.
A programming paradigm is a way of structuring, developing, and reasoning about a program. Some examples are Procedural Programming, Object-oriented Programming. A good example is structuring your code into a set of objects that all interact each other (object-oriented). As of right now, Object-oriented Programming is still the most popular kind. But, today we talk about one that’s gaining popularity — Functional Programming. So, let’s focus on an important concept of Functional Programming — Declarative Programming.
There are two steps of programming that people usually know. Imperative and declarative programming. The main difference between them is that in an imperative design, the programmer structures their code as a set of instructions that the computer should carry out. Now, in a declarative design that’s not the case; in a declarative design, the programmer is modeling the flow of data throughout the application without structuring the code into step by step instructions. That might sound strange, so let’s give an example of both.
Let’s say I want to convert a string into a set of numbers based on the character code of each character and some arbitrary offset number of my choice. Here’s the imperative approach.
In the imperative approach using the object-oriented paradigm, the approach would take the string and pass it into a method of a static or instance class, then mutate the string into the form we request using methods attached to the class. The original string is altered forever and can’t be used in its original form anywhere else in our program. We don’t have to mutate it, but that’s usually the case in an object-oriented design, we pass along the data to each function, changing the original value. Another important thing to notice is that in an imperative approach a lot of boilerplate code is added to get the job done on any level. Now, let’s look at the declarative approach.
The declarative approach, which is at the heart of Functional Programming, mutating data that is passed into a function is not allowed; data is instead copied and passed along as an immutable value. Another big thing is that we don’t model the instruction order or use classes to perform operations on data. Here’s an example of this approach.
The key benefits of this approach come in the form of code reusability on a grander scale and easier to understand code. When dealing with objects in large applications, we often end up debugging our code by looking at the links between each object. Often times, you have to pass a reference to another object to handle a task in another object, creating a tightly coupled system. The disadvantage of this becomes apparent when you have to make changes to the system; edits have to made within all the affected objects to add new features. This doesn’t happen in the declarative approach; functions are reusable Lego blocks that can be composed together and passed around the program freely without relying on the internal state of any object. By using that concept effectively, we can manage large scale applications and separate our concerns into smaller parts that are easily testable.
With that said, these are just some of the thing I learned while researching functional programming and there will be more as I come to understand the secrets of the club.