Saturday, 17 January 2015

Putting functions to good use

In my previous post I wrote that Java 8 has a new, functional face – and a pretty one. Programming in a functional style is not a theoretical whim of computer scientists, is has immediate practical consequences. Thinking in terms of function composition produces shorter code that is easier to read and, more importantly, more robust.

In this article I will show a few functional little tricks that yield significant benefits.

Efficient assertions

Assertions are a powerful way to create self-verifying code. A programmer who routinely uses assertions writes better code simply because he has to think twice about the invariants of a program.

However, assertions do incur a performance penalty if the asserted expression is complex. This can be addressed in Java 8 by using lazy evaluation via an anonymous function returning a boolean:

Assert.must(() -> 3 == myComplexFunctionThatHasToReturnThree(...));

instead of using the classic assert keyword:

assert 3 == myComplexFunctionThatHasToReturnThree(...);

To do this trick we need a class Assert that contains a method must() which does all the work. Firstly, Assert should be able to detect that assertions are turned on:

public static final boolean ON = true;
private static boolean isEnabled = false;

static {
   
assert isEnabled = true; // side effects intended
}

public static boolean enabled() { return isEnabled; }

The ON flag allows the programmer to remove the asserting code anywhere in his program by leveraging the optimizing capabilities of the Java compiler (the so-called conditional compilation idiom in Java). The isEnabled internal flag is set to true whenever assertions are globally turned on. The enabled() method allows read-only access to isEnabled from anywhere in the program.

The code for the must() method is deceptively trivial:


public static void must(Supplier<Boolean> assertion) {
   
if (ON) {
       
if (enabled()) {
           
assert assertion.get();
       
}
   
}
}

The ON flag eliminates the method altogether when false and the call to enabled() makes sure the evaluation of assertion takes placed only when assertions are turned on. The Appendix contains the full code for the Assert class.

Saturday, 10 January 2015

Being super lazy is (sometimes) good

Iterators are great. Although many times they are derived from a collection with elements known upfront, they can be used to model a potentially infinite collection and, with the help of additional operations, they offer the possibility to work with collections almost declaratively.

Clarifications: what I mean by iterator is not just an instance of a Java interface. It’s more of an abstraction with various incarnations: IEnumerable<T> in C#, iterators in Python, streams in Java 8 and Scala or lazy collections in Haskell.

Iterators have an important quality: they are lazy. They do work only when necessary and they return the results one by one, when asked for. Let’s see an example.

Note: the examples here are in C#. The Java 8 equivalent is summarized at the end (without full implementation).

Iterating over binary trees

Let’s consider a simple Tree data structure:

public class Tree<T>
  {
     
public readonly T Data;
     
public readonly Tree<T> Left;
     
public readonly Tree<T> Right;

     
public Tree(T data, Tree<T> left, Tree<T> right)
     
{
         
this.Data = data;
         
this.Left = left;
         
this.Right = right;
     
}
  }

It is trivial to traverse a tree recursively, it means to traverse the left child, then do work with the data, then traverse the right child:

public static void TraverseInOrder<T>(Tree<T> tree)
  {
     
if (tree != null)
     
{
       
TraverseInOrder(tree.Left);
       
Console.WriteLine(tree.Data);
       
TraverseInOrder(tree.Right);
     
}
  }

There are two problems with this code:

  • The work being done upon each node of the tree (in this case a Console.WriteLine operation) cannot be changed, it is imbedded in the traversing code
  • There is no way to interrupt execution in the middle, to stop on a certain condition or when a certain number of nodes have been processed

The first problem can be resolved in various ways:

  • Replace the call to Console.WriteLine() with a call to an abstract method of the Tree<T> class
  • Externalize the operation and transform the algorithm according to the Visitor pattern
  • Pass the operation as a parameter to the traversing method. In C# that would be an Action<T> instance, in Java 8 the Consumer<T> interface would fit the bill.

The second problem requires a more involved solution and this is where iterators come to the rescue.

Sunday, 4 January 2015

The Inexistent Resolutions

I have never made resolutions. Ever.

I have never made a list of things I plan to do by the next 31st of December. I certainly have a list of things I have not done since the last 31st of December and sad to say, this list grows by the year, its tail gets lost along the way while the tasks in it become irrelevant with time.

But, hey, there is also a smaller (albeit no less important) list of things I have done. So, I will focus on this list – it’s shorter and easier to write about Smile.

Visiting Java

I write “visiting Java” as if it were a place (and it is, in Indonesia) but obviously I am talking about the Java eco-system and – more recently discovered – the community that stands behind it. Yes, I’ve revived my Java blood-stream over the past year, to my great pleasure.

Event #1 : Meet-A-Mentor

Well, this is not really a Java event, but it is organized by the special folks at RecWorks, one of the most interesting recruiting companies on the banks of the Thames, folks who also organize London Java Community. Clear, right?

I’ve taken part to one of the sessions and I am anticipating one in January. Great, uplifting event. Always refreshing to have contact with young, bright minds and a pleasure to liaise a little bit with fellow mentors.

One interesting detail: it seems there is a lot of emphasis on data science out there in the campus land, I think half of the students I’ve talked to were expecting jobs as data scientists. This was quite surprising to me. The interest was so keen that one student asked us “which tool is better for X type of data analysis, Y or Z?”. How would you answer that?

Event #2 : Open Java Conference

The past November, OJC in London at the IBM Centre, close to London Eye and the world famous Tower Bridge. Awesome event - not free, but with a very affordable fee. A wide variety of presentations, from the easy and light (“how to fix Enterprise Software?”1)) to the more hard-core (IBM Watson architecture, optimizing Java by sniffing into the workings of the Hotspot compiler, etc).

Food included in price and mediocre, as it is expected at such a great geeky event. A little bit too much socialising for my taste, the long breaks (for obligatory networking) could have allowed for at least one more round of sessions. But people nice and friendly, knowledgeable of what they were talking about and the event very well organized and definitely something not to miss. Ironically, in 2013 I had purchased tickets for this conference but I didn’t go. I won’t repeat this mistake.

Not to forget, during OJC London 2014 it was quite an emphasis on the Adopt OpenJDK initiative which originated in London (or LJC is an active part of it). This leads to the 3rd event …