avatarGabriel Shanahan

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3966

Abstract

of data (a text file, a string, a list of strings, …), performs some type of analysis (count words, semantic analysis, whatever), and saves the result to a database.</i></p><p id="c934">The exact details are not important for our discussion.</p><h2 id="c9b3">OOP</h2><p id="cd47">Immediately, even as you were reading the sentence above, you were already decomposing the application into smaller components — there’s going to be a <i>controller</i>, a <i>DBO</i>, a <i>service layer</i>, etc. If you didn’t use a framework and wrote the whole thing from scratch, you would certainly encounter many patterns that you would express using an abstraction — repeated code that defines endpoints, processes requests/responses etc. (a <code>HTTPController</code>), code that validates the different kinds of input (a <code>Validator</code>), etc.</p><p id="40f2">All those <i>things</i>, those <i>objects</i>, have <b>behaviors that are useful to the problem we're trying to solve</b>. Of course, this is exactly what OOP is about, but what we want to emphasize is that designing things in an object-oriented manner is really a consequence of the two techniques we talked about (<i>decomposition</i>, <i>abstraction</i>), along with the fact that <b>thinking in terms of <i>objects</i> and <i>behaviors</i> is something that we as humans feel comfortable with</b>.</p><p id="e75f">Now, if we were hardcore members of the OOP camp, the designing phase is likely over. We’ve decomposed the problem into a bunch of objects, so now it’s time to roll up our sleeves and go build them. And for the most part, that means writing methods. So we do that, writing method after method, building each method by implementing its atomic steps using lots of <code>for</code>-cycles and <code>if</code>s and assignments and stuff.</p><h2 id="f17a">FP</h2><p id="b4d0">Here’s my question: <b>why?</b> Instead of approaching those methods as a design problem and using the same techniques we just talked about, the same techniques that we use completely automatically when designing <i>things</i>, we just start ‘hacking away’. No looking for patterns, no decomposition into comprehensive units. For some reason, we tend to approach the problem of building <b>behaviors</b> (as opposed to <b>things</b>) in a completely ad hoc manner.</p><p id="b001"><i>Hey, maybe we should start doing this</i>’ is basically the core idea of FP — just use the same techniques you already do, but apply them when designing behaviors. That’s it, nothing special about it.</p><p id="6e8d">When you start doing that, you will notice <i>a lot</i> of repeating patterns, and that’s where <code>map</code> and <code>fold</code> and all the other functions come from — they are names for units of code that are useful when building behaviors. Every single one of those units can (and is) implemented using a combinations of <code>if</code>s and <code>for</code>-loops, but contrary to <code>if</code>s and <code>for</code>-loops, <b>they have a name which <a href="https://readmedium.com/preface-a65cb535d122#39fa">communicates what they do</a></b>.</p><h1 id="4b4f">Simple FP example</h1><p id="f579">Take a look at the following:</p> <figure id="f812"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2Fe0F-dsraD&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2Fe0F-dsraD&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="530d">Read through the code until you understand it, and take note of the time that it takes for you to get an idea of what this code is doing.</p><p id="0bb0">Now compare it with this version:</p> <fi

Options

gure id="d7b5"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FI5NSArwRL&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FI5NSArwRL&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="29b4">Immediately, in 0 seconds, you know that the code looks up a b<i>ucket</i> from the <i>financial plan</i>, transforms it, and returns the result. It will take longer to figure out what exactly the transformation does and other low-level details, but from the very start, <b>you have a framework in your mind of what this code does</b>. And the generic part (i.e. the <code>find</code>) is also provably correct, as opposed to the previous example, where you could have made a small mistake.</p><p id="fadc">This really is everything there is to know about FP and what its purpose is. Even the more advanced concepts (which are completely beyond the scope of this text) are nothing more than this.</p><blockquote id="a104"><p>For example, think about how many times you wrote a data structure that had a value “inside” it — a <code>List</code>, a <code>Map</code>, a <code>Tree</code> (all those have 0 or more values), but e.g. also an <code>Optional</code> (may or may not contain a value), or a <code>Deferred</code>/<code>Promise</code> (a value that will be there in the future).</p></blockquote><blockquote id="2017"><p>All of those data structures, and many, many others, have the nice property that there's a very natural way to "take the value out", transform it, and "put it back". In the context of <code>List</code>/<code>Map</code>/<code>Tree</code>, that means creating a new <code>List</code>/<code>Map</code>/<code>Tree</code> with the transformation applied to every element, in the context <code>Optional</code>, it means creating an <code>Optional</code> out of the transformed element if it's there, or just keeping <code>Optional.empty()</code> if it's not and with <code>Deferred</code>/<code>Promise</code> we create a new <code>Deferred</code>/<code>Promise</code> which applies the transformation to the result of the original <code>Deferred</code>/<code>Promise</code>.</p></blockquote><blockquote id="88a8"><p>This is a pattern that appears over and over and over until someone got tired of calling it the "thing-with-transformable-insides" pattern and gave it a name - <b><i>functor</i></b>.</p></blockquote><h1 id="25aa">Structure programs using OOP, implement behaviors using FP</h1><p id="6ee1">To sum up, OOP and FP are nothing more than the result of applying the same design technique to different problem scopes:</p><ul><li>OOP tells us how to decompose our application into objects with behaviors, and allows us to logically structure our code into files and packages</li><li>FP tells us how to decompose the behaviors of those objects into fundamental building blocks</li></ul><p id="d751">You can see that it’s not about using one or the other — it’s about using one <b>and then</b> the other. <b>Structure your programs using OOP, and implement behaviors using FP.</b></p><p id="a594">Go back to <a href="https://readmedium.com/programming-with-result-combining-and-composing-result-2a56ea3a890c">Programming with Result: Combining and Composing <code>Res</code>ults</a>, jump to the <a href="https://readmedium.com/table-of-contents-c52573cfa291">Table of Contents</a>, or continue to <a href="https://readmedium.com/collection-operations-overview-5da5dd08172b">Collection Operations: Overview</a>.</p><figure id="8ecd"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*biBSB579iezsNvEQ_NMLBg.png"><figcaption></figcaption></figure></article></body>

Functional vs.? Object Oriented Programming

On the difference between functional and object oriented programming, how they’re actually the same thing and why you should use both.

— — — — — — — — — — — — — — —

THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.

— — — — — — — — — — — — — — —

Tags: #FYI++

This article is part of the Kotlin Primer, an opinionated guide to the Kotlin language, which is indented to help facilitate Kotlin adoption inside Java-centric organizations. It was originally written as an organizational learning resource for Etnetera a.s. and I would like to express my sincere gratitude for their support.

It is recommended to read the Introduction before moving on. Check out the Table of Contents for all articles.

In the following articles, I want to go through the typical (and not so typical) functions which are used to transform collections — map, filter, groupBy etc. Often, I have been confronted with the view that using these functions amounts to functional programming. I’m not sure I agree with that view, similar to how I’m not sure I would agree that changing tires constitutes being an auto-mechanic.

However, since it is at least possible that many readers will share this preconception, I will take advantage of the opportunity to give some general thoughts on functional programming which might be useful to newcomers, and help them incorporate the term into their mental frameworks.

FP vs. OOP?

It is often the case that the techniques of FP (Functional programming) and OOP (Object-oriented programming) are viewed as mutually exclusive — that you somehow have to use one or the other. People from the OOP camp view FP as a kind of black magic filled with big bad words like functors and monads, while people from the FP camp view OOP as the easy way for the stupid, primitive masses which are completely ignorant about “the higher way”. Since OOP has been in the mainstream for a longer time, the OOP camp is larger. It is interesting to realize that, for the same reason, most of the people in the FP camp started in the OOP camp — rarely is the opposite true.

However, I would like to present a different view. I think that this battle between camps is nonsensical, because the two are not mutually exclusive. In fact, not only can you use both FP and OOP, you absolutely should! The reason is this: in a sense, OOP and FP are both a consequence of the same fundamental design techniques, just applied to different design problems.

The design techniques we are talking about are ones that you apply every day, without thinking:

  • Decomposition: When building a big thing, decompose it into comprehensive smaller things
  • Abstraction: When you encounter a repeating pattern, create an abstraction that expresses it

So, let’s use these techniques to tackle the following problem:

Design an application that exposes an API to accept some type of data (a text file, a string, a list of strings, …), performs some type of analysis (count words, semantic analysis, whatever), and saves the result to a database.

The exact details are not important for our discussion.

OOP

Immediately, even as you were reading the sentence above, you were already decomposing the application into smaller components — there’s going to be a controller, a DBO, a service layer, etc. If you didn’t use a framework and wrote the whole thing from scratch, you would certainly encounter many patterns that you would express using an abstraction — repeated code that defines endpoints, processes requests/responses etc. (a HTTPController), code that validates the different kinds of input (a Validator), etc.

All those things, those objects, have behaviors that are useful to the problem we're trying to solve. Of course, this is exactly what OOP is about, but what we want to emphasize is that designing things in an object-oriented manner is really a consequence of the two techniques we talked about (decomposition, abstraction), along with the fact that thinking in terms of objects and behaviors is something that we as humans feel comfortable with.

Now, if we were hardcore members of the OOP camp, the designing phase is likely over. We’ve decomposed the problem into a bunch of objects, so now it’s time to roll up our sleeves and go build them. And for the most part, that means writing methods. So we do that, writing method after method, building each method by implementing its atomic steps using lots of for-cycles and ifs and assignments and stuff.

FP

Here’s my question: why? Instead of approaching those methods as a design problem and using the same techniques we just talked about, the same techniques that we use completely automatically when designing things, we just start ‘hacking away’. No looking for patterns, no decomposition into comprehensive units. For some reason, we tend to approach the problem of building behaviors (as opposed to things) in a completely ad hoc manner.

Hey, maybe we should start doing this’ is basically the core idea of FP — just use the same techniques you already do, but apply them when designing behaviors. That’s it, nothing special about it.

When you start doing that, you will notice a lot of repeating patterns, and that’s where map and fold and all the other functions come from — they are names for units of code that are useful when building behaviors. Every single one of those units can (and is) implemented using a combinations of ifs and for-loops, but contrary to ifs and for-loops, they have a name which communicates what they do.

Simple FP example

Take a look at the following:

Read through the code until you understand it, and take note of the time that it takes for you to get an idea of what this code is doing.

Now compare it with this version:

Immediately, in 0 seconds, you know that the code looks up a bucket from the financial plan, transforms it, and returns the result. It will take longer to figure out what exactly the transformation does and other low-level details, but from the very start, you have a framework in your mind of what this code does. And the generic part (i.e. the find) is also provably correct, as opposed to the previous example, where you could have made a small mistake.

This really is everything there is to know about FP and what its purpose is. Even the more advanced concepts (which are completely beyond the scope of this text) are nothing more than this.

For example, think about how many times you wrote a data structure that had a value “inside” it — a List, a Map, a Tree (all those have 0 or more values), but e.g. also an Optional (may or may not contain a value), or a Deferred/Promise (a value that will be there in the future).

All of those data structures, and many, many others, have the nice property that there's a very natural way to "take the value out", transform it, and "put it back". In the context of List/Map/Tree, that means creating a new List/Map/Tree with the transformation applied to every element, in the context Optional, it means creating an Optional out of the transformed element if it's there, or just keeping Optional.empty() if it's not and with Deferred/Promise we create a new Deferred/Promise which applies the transformation to the result of the original Deferred/Promise.

This is a pattern that appears over and over and over until someone got tired of calling it the "thing-with-transformable-insides" pattern and gave it a name - functor.

Structure programs using OOP, implement behaviors using FP

To sum up, OOP and FP are nothing more than the result of applying the same design technique to different problem scopes:

  • OOP tells us how to decompose our application into objects with behaviors, and allows us to logically structure our code into files and packages
  • FP tells us how to decompose the behaviors of those objects into fundamental building blocks

You can see that it’s not about using one or the other — it’s about using one and then the other. Structure your programs using OOP, and implement behaviors using FP.

Go back to Programming with Result: Combining and Composing Results, jump to the Table of Contents, or continue to Collection Operations: Overview.

Kotlin
Java
Programming
Functional Programming
Object Oriented
Recommended from ReadMedium