Software has two ingredients: opinions and logic (=programming). The second ingredient is rare and is typically replaced by the first.
I blog about code correctness, maintainability, testability, and functional programming.
This blog does not represent views or opinions of my employer.
Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Thursday, July 5, 2012

Imperative curlies 9: Haskell


If you read any of my posts about bashing curly braces and you worked with Haskell then I am sure you have thought: wait until someone shows Haskell to this guy. Well you have been right.

I am reading Learn Youa Haskell for Great Good! by Miran Lipovaca. My pride got bruised because of the book subtitle: Beginners Guide. The guy showing me Haskell is a university student from Slovenia. I may have been a bit skeptical when buying a copy but I am more than happy. If only any of the semantic web writers knew how to write as well as Miran (my semantic web reading or struggling through it is another story).

Haskell learning in many ways revalidates my opinions.  The concept sitting behind curly braces in Java practically does not exist in Haskell. 
If you see curly braces {} in Haskell you probably reading record syntax.  The underlying dislike of the imperative code simply permeates throughout the language.

I think learning Haskell is a must do exercise for every imperative programmer like myself. It is an eye opening experience to see a language where if-else statement (even though unpopular in Haskell) is really a function (well so it is in SCALA, but it is more in Haskell ;). You will start thinking of Java if statements as ugly conditional side-effects.  You will think of Java for-loops as ordered collections of side-effects. You will because, well, they are.

So go get the book and enjoy it as much as I do.

Sunday, May 27, 2012

Imperative curlies 7: switch statements


My programming is changing.  One of the visible aspects of this change is fewer if statements and more switch statements.  During work hours I program in Groovy and GRAILS, but I think the changes in my coding style are more motivated by reading about functional/declarative programming and SCALA than any reading on Groovy.  Still, I am happy with Groovy,  the language fits my coding evolution very well.
(Side Note:  if Groovy was more functional I might have still liked if statements, ifs are a different beast in functional languages.)

The functional programming concept of pattern matching is something I have learned from SCALA.  Groovy has a great support for switch statements so pattern matching can be implemented in Groovy quite well.
 Here is how I might have coded a year ago  (Test is a class representing a test or an exam, it knows a test score):
01: float score = test.getScore();//some object representing an exam or
                                    a test with a score
02: String grade = null;
03: 
04: if(score >= 90) {
05:   grade = "A";
06: } else if(score >= 80) {
07:   grade = "B";
08: } else if(score >= 70) {
09:   grade = "C";
10: } else if (score >=60) {
11:   grade = "D";
12: } else {
13:   grade = "F";
14: }
This might have been my Java code, C# code, or my first Groovy code.  Today I would prefer this code: (The rest of the post is in Groovy.)

01: Closure scoreForA = { Test t->
02:  t.score >= 90;
03: }
04: Closure scoreForB = { Test t->
05:  t.score >=80 && t.score < 90
06: }
07: Closure scoreForC = { Test t->
08:  t.score >=70 && t.score < 80
09: }
10: Closure scoreForD = { Test t->
11:  t.score >=60 && t.score < 70
12: }
13: Closure scoreForF = { Test t->
14:  t.score < 60
15: }

16: Test test = . . .
17: String grade

18: switch(test) {
19:  case scoreForA: grade = 'A'; break
20:  case scoreForB: grade = 'B'; break
21:  case scoreForC: grade = 'C'; break
22:  case scoreForD: grade = 'D'; break
23:  case scoreForF: grade = 'F'; break
24: }
As per my previous posts, one liner functions do not contribute to the curly count. 
So yes, I have a significant reduction in the number of curly braces. So what are the benefits?
One obvious difference is that I have separated the declaration of test score conditions for different grades from the conditional logic which calculates the grade.   This allows me to manage these independently.  Think of scoreForX closures as instance fields on my grade assignment class, think of them as something that can be set/dependency injected/configured without any changes to the test grade assignment logic itself.

So, to have some fun with this lets define the following:
01: //class defining rages 
02:class Curve {
03: ObjectRange rangeForA 
04: ObjectRange rangeForB
05: ObjectRange rangeForC
06: ObjectRange rangeForD
07: ObjectRange rangeForF
08:}
and
01: //generic function defining score to grade conversion
02:Closure gradeAssignment = {Curve curve, String testgrade, Test t ->
03:   curve."rangeFor$testgrade".containsWithinBounds(t.score)
04:}
This code should illustrate the power of the declarative programming (note my conditional grade calculation logic has not changed):
01: def curve = new Curve(rangeForA: (89.0..100.0),
                          rangeForB: (79.0..<89.0), 
                          rangeForC: (70.0..<79.0), 
                          rangeForD: (60.0..<70.0), 
                          rangeForF: (0.0..<60.0))


02: Closure scoreForA = gradeAssignment.curry(curve, "A")
03: Closure scoreForB = gradeAssignment.curry(curve, "B")
04: Closure scoreForC = gradeAssignment.curry(curve, "C")
05: Closure scoreForD = gradeAssignment.curry(curve, "D")
06: Closure scoreForF = gradeAssignment.curry(curve, "F")

07: Test test = . . .
08: String grade
09: 
10: switch(test) {
11:   case scoreForA: grade = 'A'; break
12:   case scoreForB: grade = 'B'; break
13:   case scoreForC: grade = 'C'; break
14:   case scoreForD: grade = 'D'; break
15:   case scoreForF: grade = 'F'; break
16: }
I probably should have added a default: handler in my switch statement, but I omitted it for simplicity.

Except for incorrect use of functional terminology (curry) Groovy has done OK in this example.
Groovy gets lots of credit for being less verbose than Java.  I look at this differently:  I like when the language rewards me for doing the right thing.  Groovy has done just that with its cool switch statement. It awarded me with more compact and more readable code, it awarded me for thinking in more functional pattern matching terms.

Friday, April 13, 2012

Imperative curlies 5: good conditionals

Continuation of my previous bashing of curlies.

In the previous posts I have proposed 2 rules: eliminated the curiels for better code and shorten the distance between curlies for better code. This post adds the following rule (3): go an extra mile in eliminating the curlies and cool stuff will happen.

If and switch statements are examples of curlies. I still have hard time wrapping my mind around conditional statements in programming. When are they bad and when they are OK?

Side Note:  Conditional statements in imperative and functional worlds are very different beasts.  For example, Java if-else statement is all about conditional side-effects.  In pure functional programming, if-else statement cannot have side-effects and it is really a function returning values. Clearly, functional ifs are more likable.

If statements have been considered villains for a very, very long time. For example, the Visitor Design Pattern has been advocated as an OO alternative to if/switch statements. The worst offenders are the pieces of code with nested if statements which split imperative logic into logical branches and smaller branches and smaller branches… Code like this is where bugs like to thrive, good test coverage is hard or impossible to achieve, the interaction between different conditions is hard to analyze. Code like this typically implies bad design. We used to call such design procedural and lacking Object Orientation. I believe it is this type of code that gave if/switch statements bad name. But are conditional statements evil PERIOD, or is it how we use them that makes them the bad guys?

Many conditional statements are declarative in nature. The concept of pattern matching is fundamental to functional programming. Similarly to for loops they are sometimes simply unavoidable. A good example is specifying boundary conditions: think of differential equations in math, or a typical recursive function definition. Here is an example, Fibonacci sequence is de-facto the hello-world of recursive functions:

fib(0) = 0
fib(1) = 1
fib(n) = fib(n-1) + fib(n-2) for n=2,3,…

If you wanted to define this sequence in Java you would write something like this (Java):
1: int fib(int n){
2:      switch(n) {
3:          case 0: 
4:          case 1: return n;
5:          default: return fib(n-1) + fib(n-2);
6:      }
7: }     
Who cares about Fibonacci numbers? Will I use it on my next programming project? I doubt that I will. The point is, however, that problems in real life have boundary conditions, is handling nulls a boundary condition? Fibonacci numbers are just a good example of boundary condition and recursion all in one.

Instead of looking at memorization or numeric optimization aspects, I will approach the fib sequence from the point of view of curlies: I will try to remove them.

So how can this be done? Is there a way to define fibs without the boundary conditions? One way is to try to replace the recursive definition with a formula (a closed form expression) (if there is one). In the case of fibs there is the Binet formula and more. So if you go this route you will rub your elbows with things like golden ratio end up studying Da Vinci’s work, ancient philosophy and look at flowers. All very cool stuff! Replacing declarative definition of fib with Binet formula (maybe not super computer friendly, but still) gets rid of the curlies and introduces some cool albeit old science!

I came across another way of approaching fib sequence (or similar recursive) problems. Imagine the impossible: computer program understanding the concept of an infinite sequence. Let’s make it even better, in this utopia world you can define infinite sequences recursively! You may want to define fib sequence by saying that it is a sequence which starts with 0 and it is followed by 1 and it is followed by sequence composed by adding corresponding elements of shifted fib sequence (recursive itself) to the left by 2 positions to shifted fib sequence (recursive itself) to the left by one position. So before the impossible dream evaporates in a puff of smoke let me write the SCALA code (example found in Wampler/Payne Programming Scala book):
1: val fib: Stream[Int] = 
2:     Stream.cons(0, 
3:        Stream.cons(1, 
4:           fib.zip(fib.tail).map(pair => pair._1 + pair._2)))
5:
6: fib.take(7).print  //prints: 0, 1, 1, 2, 3, 5, 8, empty
Notice that the conditional statements and curlies have disappeared and we have introduced some deep programming concepts at the same time. It seems like cool stuff happens when curlies disappear!

Short explanation of what this code does: lazy evaluated Streams are infinite sequences in SCALA. The infinity does not come into play because the sequence is not evaluated until needed (take() call). Sequences are like linked lists so they have head and tail. Stream.cons(a, b) returns a stream starting at a and b being a tail. Zip is a functional concept of combining 2 sequences into one sequence of pairs (2 first elements, 2 second elements, etc). SCALA can be even less verbose (from SCALADoc):
1: val fib: Stream[Int] = 0 #:: 1 #:: 
2:        fib.zip(fib.tail).map(pair => pair._1 + pair._2)
There is also a quick ‘Am I an imperative programmer’ self-test here: 
We have defined fib(n: Int) without using ‘n’. Test question: Do you have a problem with this?

The point of all of this nonsense if that conditional statements are part of life and have to be a part of my programs. This does not mean I will not try to avoid them. Only, there is no universal solution, no magic pill. Binet’s formula works for Fibonacci numbers but will not help me in writing null pointer exception free code without if statements. For this I may end up using other tricks like SCALAs Options concept, JavaScript && or Groovy ? or maybe even decide to learn what a monad is. Going extra mile in removing the curlies will force a deeper understating of how to write beautiful programs into me.

Friday, March 30, 2012

Imperative curlies 4: shorten the distance.

Continuation of my previous bashing of curlies.
My previous posts can be summarized by stating the following rule: Look at curly brackets surrounding imperative code and redesign your code so they disappear. There are obviously various tricks for disappearing the curlies and I will write more as I keep discovering them.

Here is a somewhat relaxed version of this rule:  If you cannot get rid of curlies, redesign your code so the distance between curlies is as short as possible. (Redesign your code so the imperative part between curly brackets does as little as possible). Let me clarify my postion: It is not about squeezing as much as possible into one line, the goal is to simply isolate reusable code, create reusable utilities, and keep the client imperative code to minimum. If you cannot be declarative, at least make sure that the imperative code is reduced to minimum. The distance between curlies is simply a guide to measure the progress.

We have seen in the previous post that SCALA let’s you treat one-liner functions in declarative fashion by removing curly brackets. This allows you to define functions in a math formula-like style. Examples without type inference and without much syntactic sugar of using ‘_’:
1:  def doubleIt(d: Double): Double = 2*d  
2:  def halfIt(d: Double): Double = 0.5 *d  
3:  def sortOfIdentity(d: Double): Double = halfIt _ andThen doubleIt 
//Note current SCALA compiler needs ugly _ with andThen  
Language like Groovy will not let you be as elegant. Here are the Groovy equivalents (also without using much syntax sugar):
1:  def composition = {f, g, x -> return f(g(x))}//composition helper  
2:  Closure doubleIt = {Double d -> 2* d}  
3:  Closure half = {Double d -> 0.5 * d}  
4:  Closure sortOfIdentity = composition.curry(halfIt, doubleIt)     
(I am repeating myself here , but note that the term curry in not used correctly in Groovy.)
The point is that the above code snapshots are equivalent. What is important is that the benefits on testablility and maintainability are the same.

Example of Java code from an open source ArrayUtil found here: http://www.java2s.com/Code/Java/Collections-Data-Structure/Sumallelementsinthearray.htm
1:  public class ArrayUtils {  
2:  ...  
3:   public static long sum(  
4:     int[] source  
5:    )  
6:    {  
7:     int iReturn = 0;  
8:       
9:     if ((source != null) && (source.length > 0))  
10:     {    
11:       int iIndex;  
12:         
13:       for (iIndex = 0; iIndex < source.length; iIndex++)  
14:       {  
15:        iReturn += source[iIndex];  
16:       }  
17:     }  
18:     return iReturn;  
19:    }  
20:  }       
Big distance between curlies in the implementation of the sum method. How reusable is this method code? What if we wanted to create ArrayUtil.multiply(int[] source) or ArrayUtil.max(int[] source), or ArrayUtil.min(…)?

So how can I shorten the distance between the curlies? Let us move to Groovy to get some ideas. The fact that we have a for loop suggests that we can try use one of the reusable pieces of logic available to us as a replacement for explicit for loops (see my previous post).

(Note: Functional programming uses the term folding, for some reason Groovy calls the equivalent method inject.)   Compare reusability of the above Java code with the following code in Groovy:
1:  def myInts = [1,2,3,4,5];  
2:    
3:  def multipliedInts = myInts.inject(1) {acc, val-> acc * val}  
4:  def addedInts = myInts.inject(0) {acc, val -> acc + val}  
5:  def minFromInts = myInts.inject(Integer.MAX_VALUE) {acc, val ->
6.                                    Math.min(acc, val) }  
7:  def maxFromInts = myInts.inject(Integer.MIN_VALUE) {acc, val ->
8.                                    Math.max(acc, val) }  
(Side Note: There is a problem here: what is the value of minFromInts if myInts was an empty array?  Functional programming introduces concepts of monads, SCALA has Option Some and Option None concepts, but these are not in the scope for this post.)

Note that the distance between curlies in the above Groovy example is as close as one can get to defining functions using plain math like formulas. However, personally I tend to prefer a more declarative style shown below:
>1:  class MathFormulas {  
2:   def add = {acc, val -> acc + val}  
3:   def multiply = {acc, val -> acc + val}  
4:  }   
5:    
6:  def multipliedInts = myInts.inject(1, MathFormulas.multiply)  
7:  def addedInts = myInts.inject(0, MathFormulas.add)   
8:  def minFromInts = myInts.inject(Integer.MAX_VALUE, Math.&min)  
9:  def maxFromInts = myInts.inject(Integer.MIN_VALUE, Math.&max)  
You can find specialized methods in Groovy for all of these tasks, however, the point here is the code reuse aspect. The Groovy's inject method is clearly reusable, while the for loop in Java is clearly not. How would you change the Java code above following these Groovy examples?

Is this Groovy magic? Not really, sure having closures helps, in Java we can work with reusable interfaces (similar to some that can be found in Functional Java ). We can write simple Collection Utility with fold method (it will be more verbose) :
1:  //direct from Functional Java project ...  
2:  public interface F2<A, B, R> {  
3:    R f(A a, B b);  
4:  }  
5:    
6:  //our own utility to see what needs to be done ...  
7:  public class MyCollectionUtils {  
8:   static <T, L> T fold(Iterable<L> list, 
9:                       T iniValue, 
10:                      F2<? super L, ? super T, ? extends T> fun){  
11:    T res = iniValue;   
12:    for(L l: list){  
13:       res = fun.f(l, res);  
14:    }   
15:    return res;   
16:   }  
17:  }  
18:    
19:  F2<Integer, Long, Long> multiply = new F2<Integer, Long, Long>() {  
20:   public Long f(Integer a, Long b) {  
21:     return b * a;  
22:   }  
23:  };  
24:    
15:  List<Integer> list = ...  
26:  long multipliedInts = MyCollectionUtils.
27.                <Long, Integer>fold(list, 1l, multiply);    
The difference is largely in how programmers think. New book title idea: Unlearn Java in 24 days?

Let me sum up what happened to Java code: we went from no code reuse to high code reuse. The measure of distance between culries is about 10 lines for the original code and 1 line for a function interface F2 we would need to implement in the final code:  
return a + b;

I hope to continue the curlies bashing soon.

Thursday, March 29, 2012

Imperative curlies 3: for comprehensions and powder skiing

Continuation of Previous Bashing of Curlies
Over the many year of my involvement in Java I have seen very little code reuse around loops. For loops (and other loops) in Java are yet another category of hard to test, hard to maintain code. By now we know they are no good: they are surrounded by the curlies ; ).

Functional programmers have for loops too, only they call them comprehensions! Functional programming often deals with collections of data so loops are unavoidable. So what is the difference?

The difference is really in the attitude. It is like powder skiing. I am a developer and a ski bum. I am very much into safe (inbounds) powder skiing. Like many other skiers I had hard time to learn how to ski powder at first. Frustrated, I decided that what I need to do is to start pretending. So I started pretending that I am really good: with posture and everything else making sure it appears to look like I know what I am doing. (Side note: this technique is very effective in a very deep powder because no one will see what I am doing anyway ; ) Obviously I sucked big time, I only appeared to be a good powder skier. (Think of this as writing a for loop which looks very pretty.) After some years of pretending I learned that my skiing consists of simple reusable elements such as tipping, retracting, pulling back my feet, etc . So for typical everyday tasks on the snow I now can stop pretending and just do these elemental tasks and ski! (Think of this as not using for loops any more: code reuse). When I need to do something new on skis (like trying teles), I will go back to pretending (or to writing a for loop).

The first step is the acknowledgement that what my for loop is doing should have a single purpose: comprehending a collection. (I also think of this step as admittance of being guilty of using the curlies.) The second step is the code reuse for the tasks we perform often, what kind of comprehensions will we be typically doing?: how about: joining, reducing, folding, mapping, finding (any), finding all, etc.

Assume that we need to produce a custom version of toString().  Let’s look at some old Java first:
1:  public class PackRat { 
2:    private List<String> stuff = new ArrayList<String>(); 

3:    public void addToStuff() { ... }
 
4:    public String toString() { 
5:     StringBuffer res = new StringBuffer(); 
6:     res.append("PackRat: "); 
7:     for(int i=0; i<stuff.size(); i++) { 
8:       res.append(stuff.get(i); 
9:       if(i<stuff.size() -1) { 
10:        res.append(";"); 
11:       }  
12:     } 
13:     return res.toString(); 
14:    } 
15:  } 
Same thing done in Groovy, which adds some reusable methods to avoid writing explicit for loops:
1:  class ParckRat { 
2:    List stuff = [] 
3:    def addToStuff … 
4:    String toString() { 
5:     "PackRat "+ stuff.join(";") 
6:    } 
7:  } 
Note: Libraries like Guava or Apache Commons provide you with join() method as external utility, sadly Java List interface does not have a join method.

The Groovy code looks much better . But still 2 curlies we should be able to get rid of. Unfortunately, we are trying to override a Java method in Groovy so we are stuck with the limitations the methods have (methods are not closures). So what could we do if method where closures? Let’s look as SCALA where functions are functions, not methods or closures: I want to my code to simply state that my toString function is really the same as a prefixed stuff.join(“;”). I should be able to declare it, not implement it!

So here is the more declarative and curlyless version done in SCALA:
1:  class PackRat {  
2:    private var stuff: List[String] = List[String]() 
3:    def addToStuff = … 
4:    override def toString = "PackRat: " + stuff.mkString(";") 
5:  } 
(SCALA glossary: var makes stuff a mutable instance variable, def keyword indicates function definition. List[String] is somewhat different than java List, for example, it is immutable: Note that Java/Groovy code above is not thread safe, SCALAs version does not have such problem.)

Here is yet another proof of the curly count being a good measure of code quality. On one end of the spectrum there is the imperative code with loop spelled out in Java (please count curlies in that code), on the other end there is SCALAs beautiful code where a particular kind of comprehension logic is simply declared!

Many developers think of the fact that SCALA allows you to drop curly brackets from one-liner functions as just a syntactic sugar and find the syntax iffy. My view is the opposite. The curlyless functions support the declarative style of coding and allows developer to define functions using expressions supported by SCALA language (contrast this with implementing all the methods in Java).

Obviously, there are other kinds of reusable comprehensions. For example reducing is far more general than joining. Here is SCALAs version of the above toString function using reduce:


override def toString = "PackRat: " + stuff.reduceLeft(_ + ";" + _)

Might look like compiler sugar (and again conceptually a deep stuff not iffy stuff), here is a spelled out version which is still purely declarative with no curlies:

def myConcatenateStrings(s1: String, s2: String):  String = s1 + ";" + s2
override def toString = "PackRat: " + stuff.reduceLeft(myConcatenateStrings)

Groovy code can be designed with more closures and fewer methods. This could facilitate much more declarative type of coding than methods allow. We have seen some of it in our previous post (Post on Curlies and GORM). The same declarative approach can be used to get rid of many for loops and make Groovy code closer to SCALA.

So what is the point of all of this? First, the obvious, code reuse and testability should be a good thing no matter what is the language; using reusable for loop logic can be done in Java too. It will look like someone is trying hard to be functional in Java (you can always say you are doing fluent coding and no one will know ;) Second, the idea of one-liners being closer to declarative programming warrants more thought and is more that a coding style no matter what is your language.

I hope to write more about it in the future.

Side Note: To all Java programmers (that would include me) I want to point out the obvious big difference between imperative for loops and functional comprehensions:  Imperative for loop is really a sequence of side-effects executed in order,  pure functional programming cannot have side-effects so comprehensions always return a new collection. 

Next Bashing of Curlies.