Home > API and Patterns, Functional Programming > Functional Java – partial function application, the LOD and structure agnostic access

Functional Java – partial function application, the LOD and structure agnostic access

It’s been a while since I last wrote something about programming on my private blog and since a lot has been said about Java 8 lambdas, I did not feel to add a lot more. But I recently saw a colleague’s blog on Intel’s Inside Blue about Lambdas and why a functional programming style matters. That motivated me to write something again, and tackle this topic, putting an emphasis on a specific problem and how Lambdas helped me solve it.

Partial Function Application

Partial function application is often referred to as “currying”, but there is a subtle difference. I nearly fell into the same trap until my colleague Alex corrected me (thanks for that). According to Wikipedia partial function application says: “if you fix the first arguments of the function, you get a function of the remaining arguments”, while currying is referred to as “translating the evaluation of a function that takes multiple arguments […] into evaluating a sequence of functions, each with a single argument. “

Here’s a simple example of partial function application in JavaScript:

function multiply(x,y) {
 if (typeof y === "undefined" ) {
   return function (yy) {
    return x * yy;
   }
 }
 return x * y;
}
var twelve = multiply(3,4); // = 3*4 =12, complete application
var triple = multiply(3); // = 3*y, partial application: first argument fixed
var six = triple (2); // “triple” is a single-parameter function. -> triple(2) = multiply(3,2) = 3*2 = 6

Since Java 8 is a static typed language, we can’t just return a function type in one case and a numeric value type in the other. We could try to overload methods, but that would create code bloat and might also create conflicting method signatures. Another solution was described by Claude Martin in his blog https://humanoidreadable.wordpress.com/2014/08/06/java-8-currying/ . He suggests replacing the parameters of a function with container objects of classes like Pair, Triple and Quad. And transform these using utility methods. Even though I find this approach interesting, I don’t think it looks very natural.

What I find the most elegant is creating utility methods that take for example any BiFunction (a Function with two parameters) plus one of its parameters and just return a new Function. Here is an example, it should be rather obvious, just have a look at the main method to see the utility methods in action:

public class PartialApplication {
 public static <X, Y, R> Function<Y, R> applyX(final BiFunction<? super X, Y, R> f, final X x) {
  return (y) -> f.apply(x, y);
 }
 public static <X, Y, R> Function<X, R> applyY(final BiFunction<X, ? super Y, R> f, final Y y) {
  return (x) -> f.apply(x, y);
 }
 public static <X, R> Supplier apply(final Function<? super X, R> f, final X x) {
  return () -> f.apply(x);
 }
 public static <X, Y> Consumer acceptX(final BiConsumer<X, Y> c, final X x) {
  return (y) -> c.accept(x, y);
 }
 public static <X, Y> Consumer acceptY(final BiConsumer<X, Y> c, final Y y) {
  return (x) -> c.accept(x, y);
 }
 public static void main(final String[] args) {
  final BiFunction<Integer, Integer, Integer> times = (a, b) -> a * b;
  final Function<Integer, Integer> times2 = applyX(times, 2);
  final Supplier twoTimesFour = apply(times2, 4);

  System.out.println(times.apply(2, 4));
  System.out.println(times2.apply(4));
  System.out.println(twoTimesFour.get());

  final Function<Integer, Integer> squared = applyX((p, n) -> (int) Math.pow(n, p), 2);
  final Function<Double, Double> cubed = applyY(Math::pow, 3d);
  System.out.println(squared.apply(6));
  System.out.println(cubed.apply(2d));
 }
}

I’ll leave this to you for the moment; I will reuse the class later.

The Law of Demeter

Often regarded as a rather esoteric concept, the Law of Demeter states that a objects should only talk to its closest friends, that is:

  • Parameters
  • Own fields
  • Objects it created

The commonly seen call-chain “foo.getBar().getBuzz()” is a violation of the Law of Demeter, because asking “bar” for “buzz” is neither asking a method parameter, nor is it asking a field or an object that the method created itself. By the way: I have left a note at the end of this blog posting on how to trick yourself regarding the LOD, you might want to read it now or just continue to stay focused. Why should you care about violating the Law of Demeter? After all it is just one of these theoretical rules with hardly any practical relevance, is it? Well, the idea behind the Law of Demeter is to minimize the impact of local code changes to the rest of the code. These “ripple effects”, when a small code change ripples through the rest of the code, requiring a large change that will eventually conflict with other people’s changes, are annoying, they waste time and put your program stability at risk. There is also a security aspect to it, but more on that later. Let me show you an example and it will all become clear.

Structure agnostic access

At work I found myself in a situation where I had a list of Objects that all shared the same base class, but whose structure looked deeply different, depending on their configuration. I will make up an example that demonstrates the problem to not reveal my company’s source code.

Imagine your task is to inspect buildings. There are multiple types of buildings: There are simple bungalows that just have a couple of rooms but no floors. There are skyscrapers that have a large number of floors where each floor has multiple rooms. There are multi-storey car parks that have several levels, which contain parking lots instead of rooms. Buildings usually have roofs, different types of – the roof of a parking deck may be just another level of parking lots, some skyscrapers may have a roof with a landing pad, bungalows on the other hand won’t have these, but they may have a roof with an attic. So even though they’re all buildings their class/object structure may look hugely different. And if your program deals with different building types, it may well be that you might have to add a new type from time to time.

To further complicate the model let’s say that a room has an optional fire extinguisher in it, while in a skyscraper each floor has an optional fire extinguisher (on the hallway) and an optional one in any individual room. So how do you count the fire extinguishers in any building? Here is what I see some people do in comparable situations:

int getNumberOfFireExtinguishers(final Building building){
 if (building instanceof Bungalow){
   return ((Bungalow) building).getRooms()
    .stream()
    .filter(room -> room.getFireExtinguisher().isPresent())
    .count();
  } else if (building instanceof Skyscraper){
   return ((Skyscraper) building).getFloors()
    .stream()
    .filter(floor -> floor.getFireExtinguisher().isPresent())
    .count()
   + ((Skyscraper)building).getFloors()
    .stream()
    .flatMap(floor -> floor.getRooms().stream())
    .filter(room -> room.getFireExtinguisher().isPresent())
    .count();
  } else if (building instanceof ... //numerous other types follow

Don’t do this!

What you’ll get is a kind of combinatory explosion, because for each and every other query you’d get these kinds of cascades. Plus, the moment you decide to change a model graph or add a new building type, you would have to touch a lot of source code, namely each instanceof-cascade and call chain that is affected. It should be intuitively clear what’s wrong with this, but unfortunately I see a lot of code like that in the wild. Worse: We will likely see even more of it, because Lambdas make it pretty convenient to stream, map, flatMap, etc.; but it remains a bad practice.

It becomes apparent if you remind yourself of the Law of Demeter and ask yourself the following question: Why should everyone, who wants to know anything about a building, need to have exact knowledge on the building’s construction? That should be an implementation detail. Like the LOD suggests, you should just put any query to the Building class itself and get the desired result directly, period.

So the usual way of implementing this is to implement a base method, override and delegate. You’d have the Building class implement a method like “int getNumberOfFireExtinguishers(){..}” and make the sub-types override that method to provide a sensible value – that method could then call its referenced objects for their count and everyone is happy, isn’t it? Well, not quite, because that technique creates new problems: Why should a class like “Bungalow” inherit a method like “isLandingPadFree()”? Doesn’t that send deeply confusing messages to the programmer who finds a Bungalow class that suggests it might have a landing pad, because it inherits/offers this method? And what about things like roofs that may have entirely different, incompatible types? What would the common return value’s type be? An “Object” that requires casting? Overriding doesn’t seem to be the best solution here. But there is another way to tackle this problem.

The Visitor

The Visitor pattern is not very popular, because the pattern often looks too complicated and there are a lot of examples on the web that I dislike – usually those that sport a visitor class with several overloaded methods for specific types. Fortunately starting with Java 8 we have the Consumer interface, which describes a very simple visitor and, thanks to Lambda Expressions, looks a lot better now than it did with Java 7 and earlier.

Let me start with some source code. We’ll lay down a basic interface that declares that an object graph can be traversed by a visitor implementation:

public interface ITraversable {
 final BiConsumer<Object, Consumer> acceptAndTraverse = (o, v) -> {
  if (o instanceof ITraversable) {
   ((ITraversable) o).traverseWith(v);
  } else {
   v.accept(o);
  }
 };
 static <T> void traverseWith(final Consumer<Object> visitor, final Optional<T> o) {
  final Consumer<Object> traverseIntoObject = PartialApplication.acceptY(acceptAndTraverse, visitor);
  o.ifPresent(traverseIntoObject);
 }
 static <T> void traverseWith(final Consumer<Object> visitor, final T... objects) {
  traverseWith(visitor, Arrays.asList(objects));
 }
 static <T> void traverseWith(final Consumer<Object> visitor, final Collection<T> collection) {
  final Consumer<Object> traverseIntoObject = PartialApplication.acceptY(acceptAndTraverse, visitor);
  collection.stream().forEach(traverseIntoObject);
 }     
 default void traverseWith(final Consumer<Object> visitor) {
  visitor.accept(this);
 }
}

This is the core interface. It defines a method to traverse an object, which means at least accepting a visitor (default). And it has utility methods to traverse data structures that do not implement the ITraversable interface. Note how I’m reusing the PartialApplication-Utility to reuse the acceptAndTraverse-Lambda expression, I find this utterly elegant. Traversing a collection may look a bit tricky to understand on first sight, but if you think about it for a second you will get how it works.

Let’s continue with the main class to see the Interface in action, before I dive into the model itself:

public class Main {
 static Consumer<Object> countInstancesOf(final Class<T> type, final AtomicInteger i) {
  return o -> {
   if (type.isInstance(o)) {
    i.incrementAndGet();
   }
  }
 };
 public static void main(final String[] args) {//some counts
  final AtomicInteger numberOfFireExtinguishers = new AtomicInteger(0);
  final AtomicInteger numberOfRooms = new AtomicInteger(0);
  final AtomicInteger numberOfFloors = new AtomicInteger(0);

  //visitors that change the counts above:
  final Consumer<Object> fireExtinguisherCounter = countInstancesOf(FireExtinguisher.class, numberOfFireExtinguishers);
  final Consumer<Object> roomCounter = countInstancesOf(Room.class, numberOfRooms);
  final Consumer<Object> floorCounter = countInstancesOf(Floor.class, numberOfFloors);

  //let’s use them on our different models:
  final Building bungalow = new Bungalow();
  bungalow.traverseWith(roomCounter);
  bungalow.traverseWith(fireExtinguisherCounter);

  System.out.println("Number of rooms in Bungalow: " + numberOfRooms);
  System.out.println("Number of fire extinguishers in Bungalow: " + numberOfFireExtinguishers);
  System.out.println();

  numberOfFireExtinguishers.set(0);
  numberOfRooms.set(0);
  numberOfFloors.set(0);

  final Building skyscraper = new Skyscraper(50); //fifty floors
  skyscraper.traverseWith(roomCounter);
  skyscraper.traverseWith(fireExtinguisherCounter);
  skyscraper.traverseWith(floorCounter);

  System.out.println("Number of floors in Skyscraper: " + numberOfFloors);
  System.out.println("Number of rooms in Skyscraper: " + numberOfRooms);
  System.out.println("Number of fire extinguishers in Skyscraper: " + numberOfFireExtinguishers);
 }
}

So this is our end goal: The Bungalow that has just Rooms and the Skyscraper, whose rooms are organized in floors, don’t have the same object graph internally, even though they share the same base class (Building); but they behave the same for the user. The top level object of both models takes a visitor and sends it through its object graph where every object of the graph is accepted by the visitor. So the visitor is the one who collects the needed information that is printed out later. Like planned the Visitor needs minimal information about the building’s object structure, none in this case. It is just sent around to meet (accept) other objects in the graph. For sure our model has to pass the visitor around and this is how that is achieved is pretty simple. Let’s have a look:

public class Building implements ITraversable {
 //common stuff goes here, like owner, name, address, etc
}

This is or very simple base class. All we need is to implement ITraversable. The Interface’s default method will just tell any a given visitor to accept the building object, so the visitor can inspect it. For the base class this doesn’t really make sense, because you could ask it directly, but the magic happens deeper down the object graph. Let’s have a look at the two different types of buildings. First the simple Bungalow:

public class Bungalow extends Building {
 private final List rooms = new ArrayList<>();

 public Bungalow() {
  rooms.add(new Room("Living room", Optional.empty()));
  rooms.add(new Room("Bedroom 1", Optional.empty()));
  rooms.add(new Room("Bedroom 2", Optional.empty()));
  rooms.add(new Room("Kitchen", Optional.of(new FireExtinguisher())));
  rooms.add(new Room("Bathroom", Optional.empty()));
  rooms.add(new Room("Storage", Optional.empty()));
 }
 @Override
 public void traverseWith(final Consumer<Object> visitor) {
  super.traverseWith(visitor);
  ITraversable.traverseWith(visitor, rooms);
 }
}

After calling the superclass implementation, that calls the Interface default ”visitor.accept(this)”, the method progresses with traversing those child objects that any visitor could be interested in and that it can identify by their type: The rooms.
It is no use traversing simple Strings for example, because no visitor could tell a name from a comment, if both were of the same type (String). Wrapping dedicated classes around simple strings like names and comments may look wasteful, but names and comments are not just strings of characters, they are really different things, so that is a good practice and it would help here too. But I won’t follow that practice here to keep the examples as short. I might touch that topic in a later Blog though.

In contrast to the room, here’s a Skyscraper. It doesn’t contain rooms, but floors (that have rooms). It’s not just for the sake of the argument that I did not give the Bungalow a single element list of floors, it’s also cleaner: It doesn’t need a floor with all of its other properties that it might have.

public class Skyscraper extends Building {
 private final List floors = new ArrayList<>();

 public Skyscraper(final int numberOfFloors) {
  for (int f = 1; f <= numberOfFloors; ++f) {
   floors.add(new Floor(Integer.toString(f), 20, Optional.of(new FireExtinguisher()));
  }
 }
 @Override
 public void traverseWith(final Consumer<Object> visitor) {
  super.traverseWith(visitor);
  ITraversable.traverseWith(visitor, floors);
 }
}

The implementation of the traversal algorithm looks almost the same as before. This is handy. We don’t want to learn new things all the time. The Floor resembles our Bungalow class, but of course a floor is no bungalow and while a bungalow might have a garage, a floor might not, obviously! As described in the beginning of this blog, each floor has an optional FireExtinguisher. Additionally some individual rooms have an extra FireExtinguisher (think of machine rooms, labs, whatever):

public class Floor implements ITraversable {
 private final String name;
 private final Optional<FireExtinguisher> fireExtinguisher;
 private final List rooms = new ArrayList<>();

 public Floor(final String name, int numberOfRooms, final Optional<FireExtinguisher> fireExtinguisher) {
  this.name = name;
  this.fireExtinguisher = fireExtinguisher;
  for (int nr = 1; nr <= numberOfRooms; ++nr) {
   rooms.add(new Room(Integer.toString(nr),
Optional.ofNullable(nr % 10 == 0 ? new FireExtinguisher() : null)));
  }
 }
 @Override
 public void traverseWith(final Consumer<Object> visitor) {
  ITraversable.super.traverseWith(visitor); //calls interface default implementation
  ITraversable.traverseWith(visitor, fireExtinguisher);
  ITraversable.traverseWith(visitor, rooms);
 }
}

Note that we need to call the interface’s default method here, because the Floor doesn’t inherit from Building. Same goes for the room:

public class Room implements ITraversable {
 public final String name;
 private final Optional<FireExtinguisher> fireExtinguisher;

 public Room(final String name, final Optional<FireExtinguisher> fireExtinguisher) {
  this.name = name;
  this.fireExtinguisher = fireExtinguisher;
 }
 @Override
 public void traverseWith(final Consumer<Object> visitor) {
  ITraversable.super.traverseWith(visitor); //calls interface default implementation
  ITraversable.traverseWith(visitor, fireExtinguisher);
 }
}

Just for demonstration purposes I did not make the FireExtinguisher class “Traversable”, this is to show that the visitor will get to accept these types also, when we use the utility methods of the ITraversable interface:

public class FireExtinguisher {
 //model number, expiry date, etc goes here
}

Security and access rights

Using this model it is surprisingly easy to implement checking access rights to data. Let me just briefly give you a rough sketch of the idea:

public class SecureRoom extends Room {
 private final Access acs;
 public Room(final String name, final Optional<FireExtinguisher> fireExtinguisher, final Access acs) {
  super(name, fireExtinguisher);
  this.acs = acs;
 }
 @Override
 public void traverseWith(final Consumer<Object> visitor) {
  if(acs.isGrantedTo(visitor)){
   super.traverseWith(visitor);
  }
 }
}

public class Access {
 private final int level;
 //...
 public void isGrantedTo(final Consumer<?> visitor){
  return (visitor instanceof PrivilegedVisitor)
         && level <= ((PrivilegedVisitor)visitor).getAccessLevel();
 }
}

The good thing about doing it this way is that you don’t need to check for access rights on each and every call site that externally iterates the data model. Access security checks come natural, if you think in terms of objects with doors that only let those visitors through who are privileged.

Appendix: LOD pitfalls

There are ways to trick yourself or static code style checkers regarding the Law of Demeter. Here are some common “workarounds” to not get a bad score for your source code:

Pass the parameter own to a new method:
class Myclass {
 void a(final Foo foo){
  final Buzz buzz = getBuzz(foo);
  //...
 }
 Buzz getBuzz(final Foo foo){
  return getBuzz(foo.getBar());
 }
 Buzz getBuzz(final Bar bar){
  return bar.getBuzz();
 }
}
Make your intermediate object a field:
class Myclass {
 private final Bar bar;

 MyClass(final Foo foo){
  bar = foo.getBar();
 }

 void a(){
  final Buzz buzz = bar.getBuzz();
  //...
 }
}

However, even though every method itself now obeys to the LOD on first sight, all you did was to hide the violation, defying the very intention of the LOD, which is: Keeping changes local by not relying on knowledge about an object’s inner structure.
In this case, if you changed the structure of Foo to not return a Bar that contains a Buzz to something like a Bee that contains the Buzz, you’d be equally forced to change Myclass, where Myclass really should not know anything about how Foo was built. So even though your static code style checker might not complain, you’ve not gained anything.

tl;dr

By using a functional approach and a very simple visitor pattern it is possible to easily traverse entirely different objects graphs with minimal knowledge of the object graph itself. This also avoids ripple effects and keeps changes in class implementation local. Delegation and boilerplate code is kept at a minimum, read access rights checks are clean, simple and can’t be missed.

Related resources:

“The Paperboy, The Wallet, and The Law Of Demeter”:
http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf
“Minimizing ripple effects”:
https://brixomatic.wordpress.com/2010/04/06/minimizing-ripple-effects/

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: