JavaScript brought up functional programming into the mainstream. Thanks to functions and closures, it opened up the way for functional programming patterns. But JavaScript is way more than just a functional language. It implements a lot of fundamental object-oriented programming principles. If you want to learn more about the differences between the two approaches, you’re in the right place, because here, we’ll cover the basics of both, as well as showcase some JavaScript code to exemplify those concepts.
Definitions of object-oriented & functional programming
Object-oriented programming is a programming paradigm that’s based on the concept of “objects” which can contain data in the fields, known as attributes, and code in the form of procedures, known as methods. The most popular object-oriented programming languages are class-based, meaning that objects are instances of classes, which determine their types. Some well-known and widely used programming languages, like Python or Java, are multi-paradigm, meaning they support object-oriented programming to a greater or lesser degree, but usually in combination with imperative and procedural programming. Among other OOPs are C++, C#, Ruby, Objective-C, Swift, JavaScript, Scala, and others.
Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids changing states and mutable data. Functional programming is considered declarative programming because programming is done with expressions and declarations rather than states. Among functional programming languages are Scheme, Haskell, Racket, JavaScript, and others. The thing with JavaScript is that it has the properties of dynamically typed functional language and imperative and object-oriented paradigms at the same time. Besides, functional programming can be implemented in such languages as Perl, PHP, C++, and Scala. Scala essentially occupies a grey area between the programming paradigm, because even being written in a functional style, the presence of mutable state places it between functional and imperative languages.
A short discourse on history
“Object” and “oriented” terms first appeared in the late 1950s – early 1960s at the MIT. Artificial intelligence group first used the term “object” to refer to identified items (LISP atoms) with properties or attributes. In 1963, in the technical report about his Sketchpad dissertation, computer scientist and researcher, Ivan Sutherland, defined notions of “object” and “instance.” Later, in the 1960s, object-oriented programming was finally put into practice with the Simula programming language, where class, object, inheritance, and dynamic binding were first fully introduced. However, data encapsulation through levels of scope for variables (private and public) were not realized in Simula. Because of the work of computer scientists from Sweden, Norway, Germany, and the Soviet Union, Simula became widely available. By 1966, Simula compiler was born, and later, class and subclass hierarchy was introduced, as well as the possibility of generating objects from those classes. The later history involved the development and appearance of Simula 67 compiler in 1972. Nevertheless, Simula was still primarily used by researchers who were involved in physical modeling (for example, in the study for improvement of ships). The other languages that followed included Smalltalk, Objective-C, C++, and Eiffel.
Object-oriented programming was officially sealed as the legitimate programming paradigm of the future by the Association for Computing Machinery, which organized the first Conference on Object-Oriented Programming, Systems, Languages, and Applications in 1986. By the mid-1990s object-oriented programming became the dominant paradigm mainly because of the availability of languages which supported those techniques. Its dominance was later enhanced by the popularity of graphical user interfaces. Object-oriented programming, in turn, enhanced the popularity of event-driven programming. Even later, OOP features were added to many existing languages, like BASIC, Pascal, and COBOL. Then, Python, Ruby, and Java were developed.
As far as functional programming is concerned, then its inception goes way back to 1930s, to lambda calculus, a formal system which was developed at the beginning of the 20th century with a purpose to investigate computability, function definition, function application, and recursion. What lambda calculus essentially is — a theoretical framework for describing functions and their evaluations. However, it’s not a programming language per se, but rather – a mathematical abstraction, which forms the basis of all current functional programming languages. There’s another mathematical abstraction, which is considered even more abstract, and that is a combinatory logic. Both of these abstractions were developed to achieve a clearer approach to the foundations of mathematics.
Lisp was the early sort of functional programming language, developed in the 1950s at the MIT, however, it was also multi-paradigm, meaning that it involved support for many other numerous programming styles. Information Processing Language born in 1956, is sometimes referred to as the first computer-based functional language, which is, in its essence, an assembly-style language for manipulating lists of symbols. In the early 1960s, in his programming book A Programming Language, Kenneth Iverson described the APL language; even later, in 1990s Iverson created another language, called J, later, closer to the mid of the 90s languages like K and Q were born. Meanwhile at the same time, in 1973, the ML language was created by Robin Milner, and the SASL language was developed by David Turner. In the same 1970s, other languages have emerged, one of them was NPL.
The initial motive for developing APL was to provide a tool for writing and teaching. Although APL has been exploited mostly in commercial programming, I continue to believe that its most important use remains to be exploited: as a simple, precise, executable notation for the teaching of a wide range of subjects.
- “A Personal View of APL”, IBM Systems Journal, 30 (4), 1991 — Kenneth Iverson
The functional programming was brought to the wider audience by the classic 1985 textbook, Structure and Interpretation of Computer Programs with the description and the development of Scheme, a simple lexically scoped functional dialect of Lisp. Institutional type theory, which described functional programs with constructive proofs expressed as dependent types, was developed in the 1980s by Per Martin-Lof and led to new approaches to interactive theorem proving, which, in turn, influenced other functional programming languages. Then there were Miranda, Haskell, and others.
Similarities and differences
While everything described above, including the programming concepts and theoretical definitions, sound pretty complicated, let’s break that down a bit for those of us not as much mathematically gifted as, say, a typical MIT researcher.
Both OOP and FN programming languages have the same common goal, which is to create a functional working program that’s bug-free and understandable. However, how this is achieved differs tremendously based on whatever approach you choose.
There are two main components of every program: the data and the behaviors. The data is something that the program knows, and the behavior is how essentially the program treats what it knows. According to object-oriented programming, data and behavior are concentrated with an object to make it easier to make a program understandable. In functional programming, these components are completely different and kept separate. Besides, all objects that are created in functional programming cannot be changed, and thus, are rendered immutable; objects do not share scope with other objects, meaning the shared state is avoided. Since FP primarily exercises an adherence to pure functions, hence the name, let’s dive into pure functions per se and what they actually mean and imply.
A pure function is a function where the return value depends on the input, there are no side effects (like no database calls can affect the return value), and they do not alter data that was passed into them.
To dive into the aforementioned concepts deeper, let’s explore the JavaScript language from both object-oriented and functional programming perspectives since JavaScript incorporates both.
JavaScript: OOPS vs FN
The case with JavaScript is that it makes it easy to combine both object-oriented and functional styles. JavaScript has many complicated concepts, so you might want to find tutorials to learn JavaScript to master them. To make the code easily modifiable and composable, separate data and processes that change it.
Let’s consider the following example:
// functional function getPrice(transport) { switch (transport.type) { case "fly": return transport.ticket + transport.insurance + transport.luggage case "train": return transport.ticket + transport.service case "bus": return transport.ticket } throw new Error("Invalid Shape") } const trainTrip = { type: "train", ticket: 30, service: 5 } const price = getPrice(trainTrip) console.log(price) // OOP class Transport {} class Fly extends Transport { constructor(ticket, insurance, luggage) { super() this.ticket = ticket this.insurance = insurance this.luggage = luggage } getPrice() { return this.ticket + this.insurance + this.luggage } } class Train extends Transport { constructor(ticket, service) { super() this.ticket = ticket this.service = service } getPrice() { return this.ticket + this.service } } class Bus extends Transport { constructor(ticket) { super() this.ticket = ticket } getPrice() { return this.ticket } } const trainTripObj = new Train(30, 5) const trainPrice = trainTripObj.getPrice(); console.log(trainPrice)
In the first sample, the function returns the result depending on the type of input object and contains a part of the logic for working with these objects. In the second sample, similar logic is stored in classes separately.
Here’s a great video explanation on how it all applies to TypeScript:
OOP vs FN: what’s the debate about?
Developers preferring object-oriented programming argue that it’s a better approach at creating programs rather than a functional approach, and conversely, the developers advocating for functional programming argue that their approach is better. The proponents of OOP appeal that the concept of inheritance and encapsulation makes it easier to manage and manipulate data, whereas the functional programming advocates argue that the separation of data and methods, as well as the high level of abstraction achieved with the approach, leaves very little room for errors. The debate is not going to end anytime soon, because new articles on the subject and twitter discussions pop up like mushrooms after a summer rain with an all too regular basis.
Conclusion
Hopefully, we’ve covered the basic differences between OOP and FN programming and how it applies and relates to JavaScript. Meanwhile, if you’re interested in more articles on the programming subject, please check the following:
Angular Interview Questions
Node.js Interview Questions
JavaScript Interview Questions Part 1 and Part 2
*