Welcome!

Java IoT Authors: Elizabeth White, Pat Romanski, Liz McMillan, William Schmarzo, Stackify Blog

Related Topics: Java IoT

Java IoT: Article

The Rise of Functional Java Programming

Better living without side effects

This sum example we started with may be simple, but it already illustrates how functional programming is different. The obvious way to code this in Java would have been to initialize a counter to zero, iterate through the list, and keep modifying the counter by adding the next value. If you’ve been writing Java code for a long time, you may not realize how deeply ingrained it is for us to solve problems by constantly modifying variables, calling methods that modify objects, and so on. But in functional programming, your first instinct should be to think of every problem in terms of computing an output directly from an input, breaking it into smaller problems that you solve recursively if necessary.

Let’s come back to our original problem now and try to apply these concepts.

Rewriting Our Original Example
First let’s consider the Reader interface we started with:

public interface Reader {
  String read();
}

The idea of this interface is to provide access to a list of strings one at a time, presumably so we can do something to those strings. But the fundamental idea of this interface is not in keeping with functional programming, since every time you call read you change the state of the object. Can we come up with a more functional way of doing the same thing? Indeed we can, by changing the responsibilities slightly. Instead of feeding strings to a consumer one at a time, we will instead ask the consumer to tell us what work they want done on each string (using a callback) then we will do it to all of the strings. In Scala the equivalent to a Java interface is a trait, so our revised example will look like this:

trait Reader {
  def repeatForEach (f: String => Unit) = ()
}

We are replacing the read method with one called repeatForEach, which takes a callback as an argument. The callback must take a string as input and return nothing as output (that’s what the Unit type means in Scala), the idea being that repeatForEach will invoke the callback for each individual string. We say = () to declare that by default, this method does nothing. Now we need an equivalent to the ArrayReader that takes a list of strings at construction time, and can be used later to provide one-at-a-time access to those strings. In Scala you don’t implement an interface, you extend a trait. Furthermore, although Scala supports an Array type, we want to use the List type, which is immutable and emphasizes our functional style. So we end up with this:

class ArrayReader (strings : List[String]) extends Reader {
  override def repeatForEach (f: String => Unit) = {
    strings.foreach (f);
  }
}

This defines a class ArrayReader that extends the Reader trait and that requires a list of Strings upon construction. Note that in Scala you can specify arguments in a class definition (almost like a function definition). This means that the arguments must be provided in every use of the constructor and they automatically become available as immutable class members. Thus the following code in Scala:

class ArrayReader (strings : List[String]) {
}

is analogous to the following Java code:

public class ArrayReader {

  private final List<String> strings;

  public ArrayReader (List<String> strings) {
    this.strings = strings;
  }
}

Once you have an instance of the Scala ArrayReader class, at any point in the future you can call repeatForEach and pass it a callback, and it will perform the callback on each of the strings in the original list, in sequence. This is equivalent in usefulness to our original ArrayReader class. For example, here is how you would print out all of the strings:

object Main {
    def main(args: Array[String]) {
           val arrayReader: Reader = new ArrayReader(List(“Foo”, “Bar”, “Baz”));
        arrayReader.repeatForEach (println);
    }
}

Now let’s write the CharReader class. It requires a Reader upon construction, and provides character-by-character access to all of the items in that reader:

class CharReader (r: Reader) extends Reader {
  override def repeatForEach (f: String => Unit) = {
    r.repeatForEach ((s: String) =>
        s.toList.foreach ((c: Char) =>
            f (c.toString)));
  }
}

This is more difficult to understand, so let’s work through it step-by-step. The CharReader takes any kind of Reader as an argument upon construction, and is also a Reader itself – just like in our original example. Like the ArrayReader it provides a repeatForEach method that takes a callback argument. Whenever this method is called with a callback argument f, the CharReader calls repeatForEach on its underlying reader, providing its own callback, which calls toList.foreach on each String, allowing each character to be processed individually. The callback f is invoked on each character after converting it to a one-character string.

Scala supports type inference, meaning that you can omit many of the type declarations without sacrificing any type safety at all. Thus you can write this more compactly this way:

class CharReader (r: Reader) extends Reader {
  override def repeatForEach (f: String => Unit) = {
    r.repeatForEach (s => s.toList.foreach (c => f (c.toString)));
  }
}

Now let’s try using our new classes:

object Main {

    def main(args: Array[String]) {

           val arrayReader: Reader = new ArrayReader(List(“Foo”, “Bar”, “Baz”));
        val charReader: Reader = new CharReader (arrayReader);

        arrayReader.repeatForEach (println);
        charReader.repeatForEach (println);
    }
}

Here’s the output:

Foo
Bar
Baz
F
o
o
B
a
r
B
a
z

This looks surprisingly like our original example, doesn’t it? We have a Reader interface with ArrayReader and CharReader implementations with roughly the same meanings as in the corresponding Java versions. The only difference is that this example has no mutable state whatsoever. There is no point at which any variable is modified from an old value to a new value. Although state is still shared between the arrayReader and charReader objects (the charReader contains a reference to the arrayReader), it’s simply not possible for them to interact inappropriately. Whenever you call:

arrayReader.repeatForEach (...)

a given input of ... will always produce exactly the same result. There isn’t any method for resetting the iterator either, because there’s no such concept in this design. You can call arrayReader.repeatForEach as many times as you like, and each time it will iterate through the entire list with no possibility of problems occurring. It can be used in a multithreaded environment and race conditions won’t even be possible. Race conditions can only occur when you have mutable state.

It may seem like cheating to convert the program to a functional one by changing the design to use callbacks, but we argue that it’s fair game. Functional programming is all about programming without side effects (i.e., mutating state), and that means coming up with new idioms for solving familiar problems. In this case, the original iterator-based solution was very typical Java code. To achieve the same thing without side effects we had to pass callbacks around (also known as closures, function objects, or anonymous functions) but this is very typical in functional languages, which typically provide a clean, elegant syntax to support that style of programming.

Functional Programming in Java
Let’s explore how we can introduce functional programming concepts into our Java code, in case our managers are not yet ready to allow the use of Scala for commercial software development. Unfortunately Java lacks many advanced functional programming features and its syntax is not ideal for this. Higher order functions (i.e., functions that operate on other functions) are almost impossible to express, especially if you want to make them strongly typed. (Defining strongly typed higher order functions requires the use of generics and Java’s “type erasure” implementation of generics throws away a significant amount of type information at runtime in the interest of efficiency. Martin Odersky giveth and Martin Odersky taketh away.)

That being said, the recent support in Java for anonymous classes still allows us to represent our Scala Reader example reasonably faithfully in Java.

The reader example is revisited on Listing 2.

This Java solution is written in a functional style, although it may look awkward to most Java programmers. We had to introduce a StringCallback interface to represent the callback, and used the new anonymous class capability in several places. However this solution has all the virtues of the Scala solution. It is immune to the problems associated with shared mutable state, and can be used safely in a multithreaded environment without any need for locking or any risk of race conditions.

Not all functional programming idioms can be translated into Java, but some of the simpler ones can, and although they may seem unnatural at first, they do bring benefits. It’s always worth asking the question: Can I solve this problem without the use of mutable state?

A Reconciliation Example
Say you have two lists of information that have to be reconciled. You want to know which items are in one list and not in the other, and vice versa. This kind of problem sometimes crops up in financial applications, and is often solved by traversing both lists and building a data structure to store the differences (e.g., a hash table). A more functional solution to the problem is to write code that can subtract the contents of one list from another as shown in Listing 3.

This example shows a functional approach to reconciling lists of information, but also shows the kind of compromise that has to be made when doing this style of programming in Java. Unfortunately the built-in Java Collection classes do not efficiently support immutable lists, so there is no way in the diff function to build up the result without either using mutation or creating our own immutable collection classes. We chose a practical approach: Create a fresh LinkedList object when the recursion bottoms out then mutate it repeatedly by calling addFirst to build up the result. Although this is not functional, we are doing it in only one place, and we are changing an object that was created within the diff method, is never shared, and has no permanent state after the initial call returns. So the implementation of diff is “mostly functional,” and the rest of the example is completely functional. This solution has most of the virtues of functional programming in terms of avoiding the problems of shared mutable state, and doesn’t destroy its input lists the way the removeAll method would (as defined in the Java Collection classes).

A Tree Aggregation Example
Say you have a tree of any type of object. Let’s keep it simple and represent the tree as an array of Java objects, each element of which could be a leaf node or another array. You might want to calculate a value based on all elements of the tree. A functional approach to this problem is to define a TreeWalker that can traverse any tree and accept a user-provided aggregation function (see Listing 4).

Once again we rely on Java’s new anonymous class capability, but we avoid the use of generics because Java’s “type erasure” implementation of generics would not allow us to use instanceof.

In this example we created a tree of numbers called myTree with eight nodes. Then we used the TreeWalker twice, each time passing it a different aggregation rule; one that knows how to aggregate a tree by adding, and another that knows how to aggregate a tree by multiplying.

The point is that tree traversal and aggregation have been factored into a general-purpose capability, and complex operations can be performed on the tree without any need for mutable state. As in the previous example, there is brief use of mutable state in the implementation of the aggregate function, but it’s on a locally created unshared object, so it’s acceptable. Programming languages like Scala that are designed for functional programming would not even require that, since they support immutable collections.

Summary
The use of mutable state makes programs hard to understand, especially in conjunction with currently popular programming practices in which objects are created indirectly and state sharing is not obvious from reading the code. Furthermore in multithreaded environments, programs relying on mutable state are prone to race conditions, requiring the use of locking that can impact performance and make programs even harder to understand and debug.

Functional programming offers an alternative approach to solving computing problems based on transforming inputs into outputs in a stateless way. Functional programs are referentially transparent, meaning function calls can always be substituted with their results without changing the meaning of the program. The loss of expressive power from having to avoid the use of mutable state is compensated for by providing better support for manipulating function objects and combining them in useful ways.

You can start using rudimentary functional programming techniques in Java immediately, but advanced techniques require better programming language support than Java offers. Scala is a useful language for Java programmers to explore, as it provides excellent support for functional programming while fitting smoothly into the Java developer’s world.   

Additional Reading

More Stories By Joe Morrison

Joe Morrison is a managing consultant at Lab49, and has over 20 years of experience leading engineering teams in designing and building complex network-based applications. His projects have ranged from distributed object research at Verizon Laboratories, to value chain management software at Benchmarking Partners in Boston, to in-the-trenches SOA projects for financial services firms in New York. Joe holds a BMath degree in computer science from the University of Waterloo, and a master's degree in computer science from MIT. He is a regular blogger on http://blog.lab49.com/.

More Stories By Kalani Thielen

Kalani Thielen is a Lab49 technology consultant, working in the financial services industry. Prior to joining Lab49 in 2006, he worked for six years developing products for the publishing, advertising, and communications industries. As a specialist in programming language theory, his present work focuses on the development and certification of compilers for bond pricing and trading languages.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


@ThingsExpo Stories
SYS-CON Events announced today that N3N will exhibit at SYS-CON's @ThingsExpo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. N3N’s solutions increase the effectiveness of operations and control centers, increase the value of IoT investments, and facilitate real-time operational decision making. N3N enables operations teams with a four dimensional digital “big board” that consolidates real-time live video feeds alongside IoT sensor data a...
Mobile device usage has increased exponentially during the past several years, as consumers rely on handhelds for everything from news and weather to banking and purchases. What can we expect in the next few years? The way in which we interact with our devices will fundamentally change, as businesses leverage Artificial Intelligence. We already see this taking shape as businesses leverage AI for cost savings and customer responsiveness. This trend will continue, as AI is used for more sophistica...
Real IoT production deployments running at scale are collecting sensor data from hundreds / thousands / millions of devices. The goal is to take business-critical actions on the real-time data and find insights from stored datasets. In his session at @ThingsExpo, John Walicki, Watson IoT Developer Advocate at IBM Cloud, will provide a fast-paced developer journey that follows the IoT sensor data from generation, to edge gateway, to edge analytics, to encryption, to the IBM Bluemix cloud, to Wa...
What is the best strategy for selecting the right offshore company for your business? In his session at 21st Cloud Expo, Alan Winters, U.S. Head of Business Development at MobiDev, will discuss the things to look for - positive and negative - in evaluating your options. He will also discuss how to maximize productivity with your offshore developers. Before you start your search, clearly understand your business needs and how that impacts software choices.
SYS-CON Events announced today that Massive Networks, that helps your business operate seamlessly with fast, reliable, and secure internet and network solutions, has been named "Exhibitor" of SYS-CON's 21st International Cloud Expo ®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. As a premier telecommunications provider, Massive Networks is headquartered out of Louisville, Colorado. With years of experience under their belt, their team of...
SYS-CON Events announced today that Fusic will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Fusic Co. provides mocks as virtual IoT devices. You can customize mocks, and get any amount of data at any time in your test. For more information, visit https://fusic.co.jp/english/.
SYS-CON Events announced today that Enroute Lab will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Enroute Lab is an industrial design, research and development company of unmanned robotic vehicle system. For more information, please visit http://elab.co.jp/.
SYS-CON Events announced today that MIRAI Inc. will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. MIRAI Inc. are IT consultants from the public sector whose mission is to solve social issues by technology and innovation and to create a meaningful future for people.
SYS-CON Events announced today that Mobile Create USA will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Mobile Create USA Inc. is an MVNO-based business model that uses portable communication devices and cellular-based infrastructure in the development, sales, operation and mobile communications systems incorporating GPS capabi...
There is huge complexity in implementing a successful digital business that requires efficient on-premise and cloud back-end infrastructure, IT and Internet of Things (IoT) data, analytics, Machine Learning, Artificial Intelligence (AI) and Digital Applications. In the data center alone, there are physical and virtual infrastructures, multiple operating systems, multiple applications and new and emerging business and technological paradigms such as cloud computing and XaaS. And then there are pe...
SYS-CON Events announced today that Interface Corporation will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Interface Corporation is a company developing, manufacturing and marketing high quality and wide variety of industrial computers and interface modules such as PCIs and PCI express. For more information, visit http://www.i...
SYS-CON Events announced today that Keisoku Research Consultant Co. will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Keisoku Research Consultant, Co. offers research and consulting in a wide range of civil engineering-related fields from information construction to preservation of cultural properties. For more information, vi...
SYS-CON Events announced today that SIGMA Corporation will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. uLaser flow inspection device from the Japanese top share to Global Standard! Then, make the best use of data to flip to next page. For more information, visit http://www.sigma-k.co.jp/en/.
SYS-CON Events announced today that B2Cloud will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. B2Cloud specializes in IoT devices for preventive and predictive maintenance in any kind of equipment retrieving data like Energy consumption, working time, temperature, humidity, pressure, etc.
Agile has finally jumped the technology shark, expanding outside the software world. Enterprises are now increasingly adopting Agile practices across their organizations in order to successfully navigate the disruptive waters that threaten to drown them. In our quest for establishing change as a core competency in our organizations, this business-centric notion of Agile is an essential component of Agile Digital Transformation. In the years since the publication of the Agile Manifesto, the conn...
While some developers care passionately about how data centers and clouds are architected, for most, it is only the end result that matters. To the majority of companies, technology exists to solve a business problem, and only delivers value when it is solving that problem. 2017 brings the mainstream adoption of containers for production workloads. In his session at 21st Cloud Expo, Ben McCormack, VP of Operations at Evernote, will discuss how data centers of the future will be managed, how th...
SYS-CON Events announced today that NetApp has been named “Bronze Sponsor” of SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. NetApp is the data authority for hybrid cloud. NetApp provides a full range of hybrid cloud data services that simplify management of applications and data across cloud and on-premises environments to accelerate digital transformation. Together with their partners, NetApp em...
SYS-CON Events announced today that Nihon Micron will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Nihon Micron Co., Ltd. strives for technological innovation to establish high-density, high-precision processing technology for providing printed circuit board and metal mount RFID tags used for communication devices. For more inf...
SYS-CON Events announced today that Suzuki Inc. will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Suzuki Inc. is a semiconductor-related business, including sales of consuming parts, parts repair, and maintenance for semiconductor manufacturing machines, etc. It is also a health care business providing experimental research for...
SYS-CON Events announced today that Ryobi Systems will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Ryobi Systems Co., Ltd., as an information service company, specialized in business support for local governments and medical industry. We are challenging to achive the precision farming with AI. For more information, visit http:...