In Indian classical music, we have Jugalbandi, where two lead musicians or vocalist engage in a playful competition. Lets say there is jugalbandi between Flutist and a Percussionist (say using Tabla as the instrument). Compositions rendered by flutist will be heard by the percussionist and will replay the same notes, but now on Tabla and vice-versa is also possible. You can find additional information on http://en.wikipedia.org/wiki/Jugalbandi and to get an idea here is the Youtube video

On a similar metaphor, I am proposing the idea of Code Jugalbandi, but now across multiple 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.
  • It can also become a source of inspiration to try out a new language.
  • Promote learning by comparison and contrast – a natural way for human mind to grasp new things.
  • People programming in different paradigms – imperative or functional, can see how each language solves the same thing differently.
  • Also, people from one camp can peek at the other camp, be it the .NET and Java camp and tell themselves – “ah look! We are not all that different, afterall!”

Mechanics
During a Code Jugalbandi session, say 2-3 presenters with each one taking to a particular language of their choice and take turns at coding the same problem.

  • Prelude – Show some Syntax. Here they can start with simple syntactical differences language. This could be repeated for say about 2 rounds to just do some warm-up.
  • Interlude – Show small problems. In here, say in about 2-3 rounds, presenters can take to small problem that can be quickly solved by each one in turns.
  • Grand Finale – In the final round all the presenters take the same problem and solve it simultaneously and end with a grand finale.

After the grand finale, one can then show the audience, how each language compares with the other on the basis of, but not limited to:

  • Signal-to-Noise Ratio
  • Brevity
  • Ceremony

I’ll be trying this in a small group and then extend it to doing it at my current workplace.

Below I am showing an example of generating multiples of 4 up to 10 in Scala, Groovy, Python, JavaScript, C#, Java8 with Lambdas and our old friend Java7.

Here is the Scala code.

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.

Lets now look at Groovy code to do 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, just type in ‘this’ on the Python ‘help’ prompt and view it.

Next, lets look at JavaScript.

function times(howMany) {
  return function(number) {
    return howMany * number;
  }
}
var fourTimes = times(4)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(fourTimes)

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 Java8 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 Java8 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 Java7.

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 pull 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!

Advertisements