Saturday, September 15, 2012

Groovy Day 2 : Differences in term of readability between Java and Groovy

For this article, we will see the differences of readability between an "old" language (Java) and a dynamic language (Groovy). You will see at first the evolution of Java to try to become more readable for the novice (and less tiring for the advance developper). The second part is the Groovy version of the same code and you will see the difference very easily.
I decided to use a simple example of a creation of HashMap and store in it the names of the seasons and the related adjectives.

First code snippet is a Java 1.4 code.
class HashMapJavaShow {
   public static void main(String[] args) {
      // creation of the hashmap
      HashMap<String, String> seasons = new HashMap<String, String>();
      
      // insertion of data, key => value
      // in this example we take the name of the season as key
      // and the related adjective as value
      seasons.put("spring", "vernal");
      seasons.put("summer", "estival");
      seasons.put("automn", "autumnal");
      seasons.put("winter", "hibernal");
      
      // before 1.5 we were forced to use an iterator
      Iterator iter = seasons.iterator();
      // loop until the iterator has not more element
      while(iter.hasNext()){
         // retrieve the current element and display it
         // using its default method toString()
         System.out.println(iter.next());
      }
   }
}

As you can see, there is a lot of things that are used and must be understand before knowing the use of this code. I mean, for a novice, of course an advanced developper directly knows where he must look at to see the meaning of the code. In this case the only line really important is the last one where the elements are printed. You can see the Iterator class that actually does not help understanding the code but just complicate it a bit more.
Second example, still in Java, but this time with 1.5.
class HashMapJava5Show {
   public static void main(String[] args) {
      HashMap<String, String> seasons = new HashMap<String, String>();
      seasons.put("spring", "vernal");
      seasons.put("summer", "estival");
      seasons.put("automn", "autumnal");
      seasons.put("winter", "hibernal");
      
      // with java 1.5 we could use a foreach loop
      for(Map.Entry<String, String> entry : seasons){
         System.out.println(entry);
      }
   }
}
With this version, we have a facility to iterate on the different entries. But at this point we still have information that are not really useful like
Map.Entry<String, String>
that is an inner interface inside Map. This is just disturbing and bring nothing interesting to understand the code.
You could ask why he's always complaining about useless information etc. You could think this is interesting to have the possibilities to modify thoses things if necessary. But I would reply very easily to that with the main concept behind Grails (that will have at least an article on it in the future), 'convention over configuration'. In this context, we can explain it like that: the language provides a default way to resolve a common problem that is very simple. But the day you have a more complex problem, you can simply dive a bit more in the code and use a bit more tools. You could make the link Pareto principle, 80% of the code use 20% of the features, so why should we have complex code when we simply want to solve very simple and common problem ?
Let's see the Groovy version:
class HashMapGroovyShow {
   static main(args) {
      // def = no user-defined type
      // we let the compilator know that we want a hashmap
      // [:] means we want a new hashmap, [] for array
      def seasons = [:]

      // << operator overload
      // syntactic sugar to the method add(Object)
      // [key: value]
      seasons << [spring: "vernal"]
      seasons << [summer: "estival"]
      seasons << [automn: "autumnal"]
      seasons << [winter: "hibernal"]

      // each is a meta method added to Object to loop on the properties
      // in case of collection, replace the looping on elements
      seasons.each{
         // "it" default variable when no one passed as argument
         // to the closure
         // println = System.out.println
         println it
      }
   }
}
In this example you can see multiple principle of Groovy that we will have time to learn in future tutorials. The main reason to show you all this new stuff is simply to show you the idea: KISS, keep it simple stupid. And if you want to see what can be done if we remove the different information that are not stricly used in this example:
class HashMapGroovyCondensedShow {
   static main(args) {
      [spring: "vernal", summer: "estival", automn: "autumnal", winter: "hibernal"].each{
         println it
      }
   }
}
I hope this article will motivate you to learn Groovy instead of this good old Java ;-)

No comments:

Post a Comment