This blog post is extracted from a talk I gave at St. Petersburg’s excellent Joker Conf in 2018.

The goal of this post is to examine whether the cost-benefit trade-off stacks up for functional programming in Java across 3 dimensions

Correctness

Performance

& Complexity

Correctness

An informal definition of correctness is :

an algorithm is correct if it is error free.

In Java we could define hierarchy of errors as something like

Compile time errors : errors the Java compiler catches and alerts us about.

Runtime errors : Runtime exceptions and errors the Java runtime (hopefully) alerts us about.

Logic errors


Tagless final is all the rage in the Scala community at the moment. It is a technique that allows you to define the general structure of the code to be executed, such that we can configure different implementations (or interpreters) to inject effects such as Optionality, Asynchronicity, Parallelism, Non-Determinism, Error Handling depending on our needs. Need to simplify a highly concurrent piece of code for a test case so that you can debug a nasty production issue? With Tagless final — no problem!

Photo by Vitaly Taranov on Unsplash

Defining Mini-DSLs

Much like the Free Monad, Tagless Final allows us to define mini-DSLs and apply different interpreters to…


No-one in Java-land is doing functional programming, and that is a good thing.

Just because you are using Lambda expressions, does not mean you are doing functional programming.

Lambda expressions in Java are simply a less verbose way of creating (slightly constrained) Objects and as such the most likely outcome of adopting Lambda’s without a good understanding of core functional concepts is gnarly, twisted, hard to follow, obfuscated imperative Object Oriented code with a nice concise syntax. Yes, we could write exactly the same dodgy code in a more verbose way by creating individual classes and lambdas.

Conversely, even when…


From Dysfunctional to Functional

In episode 2 of Dysfunctional Programming in Java we covered why and how to make your Java Objects Immutable, in this article we will dive deeper with Immutable Collections. (Elsewhere in the series we have covered laziness, functional composition, null handling, error handling, and concurrency.)

Photo by Susan Yin on Unsplash

Recap on Immutability

Method signatures like this are painfully common in Java


From dysfunctional to functional

Photo by juan pablo rodriguez on Unsplash

Its time to see how adopting principles from functional programming can help us simplify the challenge of implementing concurrent and parallel code in Java. So far we’ve explored how laziness, immutability, functional composition, banning null assignments and throwing exceptions can bring calmness and serenity to our code base. Concurrency produces the most hair-pullingly-frustrating bugs of all.

Let’s start with some really dysfunctional imperative code

Mutable non-volatile Fields

Given a number of non-volatile, non-final fields


This weeks functional and reactive Java blogs and talks!

Photo by Kea Mowat on Unsplash

Functional Blogs and Talks

The Functional Style — Part 6 by Richard Wild

Functional Programming (not necessarily with Java!) by Alex Macavei

Introduction to the Functional Web Framework in Spring 5 by Eugen (Baeldung)

Dysfunctional programming in Java 5 : No Exceptions by john mcclean

Imperative Loop or Functional Stream Pipeline? Beware of the Performance Impact! by Lukas Eder

Reactive Blogs and Talks

Bringing Reactive To Enterprise Java developers by Thomas Segismont and Julien Ponge

Reactive Microservices using RSocket by Ryland Degnan

Understanding Spring Reactive by Naveen Katiyar

Exploring Reactive Programming in Java by Miro Cupak

Embeds


8 examples of working with Java 8 Functions with Cyclops FluentFunctions

Photo by Fotis Fotopoulos on Unsplash

Error and recovery

Example 1. Handling exceptions with FluentFunctions

Given suspended method that throws an Exception (in this case suspended contrived example where the first call always fails, but subsequent calls succeed).

int times =0;
public String exceptionalFirstTime(String input) throws IOException{
if(times==0){
times++;
throw new IOException();
}
return input + " world";
}

We can make use of FluentFunctions to retry the method twice 500ms apart.

FluentFunctions.ofChecked(this::exceptionalFirstTime)
.println()
.retry(2,500)
.apply("hello");

And the output will look something like this (thanks to the println operator).

(fluent-function-Parameter[hello])
java.io.IOException
at com.aol.cyclops2-react.functions.fluent.FunctionsTest.exceptionalFirstTime(FunctionsTest.java:95)
...
(fluent-function-Parameter[hello])
(fluent-function-Result[hello world])

Alternatively we could decide to recover from the thrown exception.

FluentFunctions.ofChecked(this::exceptionalFirstTime) .recover(IOException.class, in->in+"boo!") .println() .apply("hello ")…

John McClean

Architecture @ Verizon Media. Maintainer of Cyclops. Twitter @johnmcclean_ie

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store