Code Jugalbandi

In Indian classical music, we have Jugalbandi, where two musicians or vocalists engage in playful competition.

A typical jugalbandi between a Flutist and a Percussionist plays out like this:

The percussionist listens to the intricate compositions played by the flutist and recreates them symmetrically. Needless to say, this often results in an exhilarating musical experience for the audience.

On a similar metaphor, I am proposing the idea of Code Jugalbandi across multiple programming languages (not just two) and see how the same code is rendered using different languages.

My hope is that a Code Jugalbandi session –

  • Would give people confidence that being polyglot can be within their reach.
  • Can become a source of inspiration to try out a new language.
  • Will promote learning by comparison and contrast – a natural way for human mind to grasp new things.
  • Will let programmers across different paradigms – imperative / functional – see how each language solves the same thing differently.
  • Also, people from one camp can peek at the other camp, be it the .NET or Java camp and tell themselves – “ah look! We’re not that different, after all!”

Mechanics:  During a Code Jugalbandi session, multiple programmers (each using a unique language of their choice) will solve a common problem simultaneously, or in turns.

At the end of this jugalbandi, the audience will be able to see how each language compares with the other on the basis of (…but not limited to…):

  • Signal-to-Noise Ratio
  • Brevity
  • Ceremony

Below, I am showing an example of such a Code Jugalbandi.

The Problem:  Generate multiples of 4 up to 10.

The Contenders:  Scala,  Groovy,  Python,  JavaScript,  C#,  Java 8 (with Lambdas) and our old friend,  Java 7.

———————————————————————————————

Here’s Scala

def times(howMany: Int) = (number: Int) => howMany * number
val fourTimes = times(4)
println(0 to 10 map fourTimes)

Now, that was some Tweetable code! Almost no ceremony (a script would do the job or run it in REPL), and expressing beauty in brevity. Certainly, the above code can be written all in a single line, but the idea here is to show how the times function manifests itself and its subsequent usage in different languages.

———————————————————————————————

Let’s now look at Groovy doing the same thing…

def times(howMany) { { number -> howMany * number } }
def fourTimes = times(4)
println ((0..10).collect { fourTimes it })

Not bad at all, just slightly less Signal-to-Noise ratio in terms of the braces around the closures.

———————————————————————————————

How about rendering this in Python?

def times(howMany):
return lambda number: howMany * number
fourTimes = times(4)
print map(lambda x: fourTimes(x), range(11))

Almost similar, just slightly less Signal-to-Noise ratio in terms of the return and lambda keywords, but Python likes to be readable and explicit and not much can be more said than the beautiful lines in “The Zen of Python” by Tim Peters…

———————————————————————————————

Next, lets look at JavaScript

function times(howMany) {
      return function(number) {
          return howMany * number;
      }
}

Hmm! now we can see how that the function definition getting syntax-heavy by the use of return keyword as compared to the earlier two languages, where return is optional. Last line is taken as return expression in Scala and Groovy.

———————————————————————————————

Let us next take a look at C#

class Multiples
{
      static void Main(string[] args)
      {
           var fourTimes = times(4);
           var tables = Enumerable.Range(0, 11)
                          .Select(fourTimes) //map
                          .ToList(); //force stream to emit
           tables.ForEach(x => Console.Out.Write(x + " "));
      }
      static Func<int, int> times(int howMany)
      {
           return number => howMany * number;
      }
}

———————————————————————————————

And how about the same code in Java 8 with Lambdas?

public class Multiples {
       public static void main(String[] args) {
               List<Integer> multipliers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
               Function<Integer, Integer> fourTimes = times(4);
               multipliers.stream()
               .map(fourTimes).forEach(x -> System.out.print(x + " "));
       }
       static Function<Integer, Integer> times(int howMany) {
               return number -> howMany * number;
       }
}

In both C# and Java 8 with Lambdas, we need the scaffolding of a class (read, high ceremony) to wrap the method times. Further, the dots in the method chaining and the semi-colons decrease the S/N ratio. Both the languages are pretty much at the same level.

———————————————————————————————

Lastly let us look at our old friend, Java 7

interface Function<IN, OUT> {
          OUT apply(IN input);
}
class Times implements Function<Integer, Integer> {
      private final Integer howMany;
      Times(final Integer howMany) {
           this.howMany = howMany;
      }
      public Integer apply(final Integer number) {
           return howMany * number;
      }
}
public class Multiples {
       public static void main(String[] args) {
              List<Integer> multipliers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
              Function<Integer, Integer> fourTimes = new Times(4);
              for(Integer multiplier : multipliers) {
                      System.out.print(fourTimes.apply(multiplier) + " ");
              }
        }
}

I could not have pulled this out without an interface and loops and look how much scaffolding we need to get so little done! Certainly highly ceremonious, quite verbose and little signal embedded in high noise!

Dhaval Dalal

Advertisements

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