Saturday 16 July 2011

The new kids: Go, Scala and Clojure

Somehow I managed to sleep through a generation of programming languages. Blame a career diversion and the kids, but the whole Python and Ruby thing passed me by. And why bother with them anyway? What did they have that Perl didn't?

Now I find another generation has arrived in the form of Scala, Go and Clojure. And very promising they look too, inheriting a lot of the best features from their parents (or, more correctly in Scala's case, from its gene donors and, in Clojure's case, from its parent organism).

So where did they come from? What are their lineages? Which one should we be following?

Let's start with Go. Go was born in a New Jersey resort town after a drunken hook-up between C and JavaScript at a Bell Labs party. The father, C, is the archetypal taciturn systems guy. Wears black. Slightly unstable. The mother, JavaScript, is much younger and is fun in a kooky way. Go was raised in poverty by its grandparents, who had to move from Jersey to the West Coast in search of work. Being poor, Go make everything it owns from scratch. Despite its hard start, Go grew into a quite a fun adult – like his mom – and, even with a few noticeable quirks, is remarkably easy to get along with.

Scala – at the other end of the social spectrum – wasn't even conceived in the usual way. Scala was created by splicing genes together in a (German) Swiss laboratory. SML and Java had tried to conceive naturally, but they couldn't get over SML's religious mania and Java's bizarre XML fetishism. Their genetic material was padded out by a rogue lab technician with a whole load of other crazy stuff that happened to be lying around from past experiments. The resulting wunderkind was then sent to all the right schools. It inherited amazing riches from its parents. As an adult, Scala is refined company with an encyclopaedic knowledge, though it is – if one were to be critical – a bit too preachy and up itself on occasion.

Clojure is the daughter organism of the infamous Lisp bacterium. Lisp has once again budded, as it has many times since its inception in the 1950s. This time is has incorporated new genetic material from its hosts allowing it to survive on the JVM. Typical of a Lisp-family bacterium, it retains the quirks of its parents while adding a few random mutations of its own. People infected by Clojure tend to lose the ability to use grammar. Carriers also tend to suffer from religious manias of an all-things-are-one sort.

So what does this diverse lot have in common? What trends can we see in this generation?

As with all generations, we see two effects. We see the reaction against their parents' values. And we see adaptation to a changed environment.

With Go and Clojure we see the reaction against their parents values most clearly. The reaction is against their parents' love of hierarchy. In the Java generation, hierarchy was everything. Scala, the rich-kid institutional product, respects the tradition, though it makes concessions to its peers. Go and Clojure reject tradition completely. Go inherited its mother's distaste of hierarchy (but its father's love of structure). Clojure inherits the amorphous nature of its parent.

Go, Scala and Clojure all reject their parents verbosity. Why did they have to use so many words? Couldn't they just get to the damn point without rambling and repeating themselves? First sign of senility, dude.

On to the environment. The new generation exists in a different, faster, less forgiving environment than its parents. The new generation has had to adapt to keep up. While their parents would get themselves into trouble trying to do more than one thing at once, the new generation excels at it. Go can keep hundreds of thousands of plates spinning where Java would have had a heart attack keeping up just a few hundred.

So who is likely to be the star of the new generation?

Rich-kid Scala certainly has the best pedigree and is the one least likely to upset the parents when brought home. Expect to see it around the more respectable and more academic districts.

Clojure's forbears have been around forever and proved hard to shift from their hosts. No doubt Clojure will show the same epidemiology.

Go has a nice internship with a big company, which could be its launchpad to better things. Who knows?

Whatever, good luck to them all. May they go forth and prosper. And of course sire the next next generation.

Friday 1 July 2011

Scala: coming to a course near you very soon

Java has been the default teaching language in computer science now for over a decade, and it served its purpose. But times have move on. Java is looking increasingly dated, but what is there to replace it? The answer is most likely Scala.

Why Scala? Because it ticks all the computer science boxes. Higher-order functions? Tick. Consistent object model? Tick. The static type system to end all static type systems? Tick. Call by name? Tick. Enough functional gloss to shut up the refugee mathematicians pure computer scientists? Tick.

Fair play to Martin Odersky. He's taken all the good bits from the last fifty-odd years of programming language design and – the hubris of it – managed to shoe-horn them into one surprisingly neat language.

And who could possible resist a language in which you can code infinitely long lists without having to resort to Haskell? Call by name, for heaven sake! How, since the passing of Algol, did we live without it? How cool is this:

class LazyList[T](h: T, t: => LazyList[T]) {
  def head = h
  def tail = t
}

implicit def lazyCons[T](h: T) =
  new {
    def :=> (t: => LazyList[T]): LazyList[T] =
      new LazyList(h, t)
  }

def zip[T, S](l1: LazyList[T], l2: LazyList[S]): LazyList[(T, S)] =
  (l1.head, l2.head) :=> zip(l1.tail, l2.tail)

def map[T, S](f: T => S, l: LazyList[T]): LazyList[S] =
  f(l.head) :=> map(f, l.tail)

def addPair(t: (Int, Int)) = t._1 + t._2

def fib: LazyList[Int] =
  1 :=> (1 :=> map(addPair, zip(fib, fib.tail)))

var l = fib
for (i <- 1 to 20) {
  println(l.head)
  l = l.tail 
} 
  
From a teaching angle Scala looks good too. No more semicolons to forget. Type inference to hide a lot of nastiness that comes with static typing. The interpreter to make println("Hello, World") work without the embarrassment of scaffolding needed in Java. The return of thin-end-first learning. But with a production ready language. Sweet.

So, Scala. Coming to a programming course near you soon. No bad thing.