Going with JVM Languages

Posted on October 28, 2014 by Marko Dimjašević
export lang_path=scala:java:aspectj:clojure:${lang_path}

IBM punched card Accounting Machines in 1936

When choosing a programming language to write in, one of the most important concerns is the trade off between the writing abstraction level and computational resources needed to execute the program you’re writing. If we look back to the beginning of the 20th century, we will see that machines were programmed by inserting wire jumpers into removable control panels. Since those days, the program writing abstraction level has been rising. Today we don’t write applications by fiddling with wires, punch cards, or do anything that involves moving physical components around. When programming, we write software that most of the time completely abstracts away the hardware the software will be running on. (Exemptions to this are operating systems, firmware, and other software that has direct access to the underlying hardware.) Applications we write don’t interact with the hardware directly. Instead, there are a few layers of abstractions that take care of concerns such as the type of display device, which processor is running program instructions, etc.

However, with more abstraction comes a price to pay — the demand for computing resources is higher compared to writing a program that uses the underlying hardware in a more direct way. All these abstraction layers mean suboptimal performance. On the other hand, every modern day programming language comes with so called libraries, which are collections of programs written for various purposes and ready to be used in writing an even more abstract software application. This enables us, for example, to write an Android application without worrying how exactly Android will allocate memory for our application, what it takes to draw the application on a device screen, etc.

During my current internship in the NASA Ames Research Center, I’ve seen that some complex software systems are implemented in the Java programming language, and some are implemented in Scala. So for what I do at the internship I am using Java as well. Java was designed with the idea to raise the abstraction level. Unlike in C, when writing a program in Java, a programmer does not manipulate memory addresses. One nice consequence is that the programmer doesn’t need to worry about low-level operations involving computer memory (e.g. garbage collection), thus greatly increasing the programmer’s productivity. A Java program is executed within an abstraction layer called the Java Virtual Machine (JVM), which takes care of the operations when executing Java bytecode, a compiled version of Java programs.

I played a bit with Java in my undergraduate days, and then started using it more around the time I started with my PhD. I never really liked Java and I was always grumbling about its (in)famous class path. I got so frustrated with it that I was saying to myself I’ll never again use Java once I graduate. Instead of trying to learn it, I would always just try to find a quick solution online for whatever I needed to do and immediately forget the solution. That’s also the reason why for my first research project I combined two tools written in Java in — Python.

The internship turned the scales when it comes to me and my view of Java. The reason is Inside the Java Virtual Machine, a book by Bill Venners. Before the internship has started, I’d said to myself I ought to finally understand Java so I was looking for a good learning resource. I’d say I’ve found it and thanks to the book, so many things are finally clear to me when it comes to Java! It’s a good read and I’ve been enjoying going through it. Beside learning a lot about Java and the JVM, I’ve been growing fond with Eclipse, an IDE great for developing Java software. Also, I’ve been learning a few more languages — so called JVM languages because they run on every JVM implementation — that are related to Java; Scala is one of them and I’ve been learning it in my spare time.

Scala is an object-functional language. The “functional” part is what I still have to learn a lot about. Since ever, I’ve been having a gut feeling that “functional” is the way to write programs (though not a feasible one in every occasion). Earlier this year I took a class on functional programming. I was happy to take the class, which was taught by Matthew Flatt, one of the authors of the Racket programming language. Racket is a functional programming language from the Lisp/Scheme fame. No wonder, Racket was the language of choice in the class and I learned a great deal about Racket and functional programming.

Both Scala and Racket are functional programming languages, yet they’re rather different in many ways. One of the reasons why I’ve started to like Scala as well is that it runs on the JVM. That means Scala is able to reuse all the good stuff from the Java platform, including Java libraries, memory management, its type system, and other. This also means that any other JVM language, including Java, can easily use programs written in Scala. While it didn’t use to be the case until 2007, these days the platform is free software, and so is everything Scala-specific. Therefore, Scala seems to be a perfect language of choice.

Just to demonstrate how elegant can Scala code be, consider implementing the Quicksort algorithm. It can be as straightforward as this:

def sort(xs: Array[Int]): Array[Int] = {
  if (xs.length <= 1) xs
  else {
    val pivot = xs(xs.length / 2)
    Array.concat(
      sort(xs filter (pivot >)),
      xs filter (pivot ==),
      sort(xs filter (pivot <)))
  }
}

If you don’t find that really convincing, how about writing Android apps in Scala?

And if you wish to compile Java to native machine code — or for that matter, any other JVM language, including Scala — there is GCJ, a Java compiler from the GCC collection. It can compile both Java source and (Java) bytecode to machine code.

Going back to the blog post introduction, I can say I am not writing performance-critical software, hence I can lean towards the writing abstraction level side of the trade off and write code in JVM languages, e.g. in Scala. Even if I will be writing performance-critical software one day, compiling Scala to machine code might do the trick. (However, I’d like to find some benchmarks first, which would compare running a Scala program in the JVM to running it directly in machine code.) Anyhow, going with a JVM language can boost your productivity because you’ll be leaving many irrelevant details for the JVM to take care of.

All of this makes me think I ought to be using Scala as my main language for upcoming projects. So I will give it a shot!

Because I am a GNU Emacs user, I’ve been exposed to Emacs Lisp. So I’ve seen some Emacs Lisp code, I’ve learned to write Racket code, and lately I’ve been wondering if there is a Lisp language that runs on the JVM. Of course, there is one — it is called Clojure. I’m hoping to learn Clojure as well!

To sum up, I’ve been into the Java platform and I am considering to learn the above mentioned JVM languages — Scala, Java, and Clojure — really well. I just like the idea of having a single platform supporting all these languages. (If you were not aware of it, it’s a well established platform.) There’s another JVM language I haven’t written about, which provides an orthogonal approach to programming compared to the three languages. What to say than all these languages and the Java platform are a helluva drug!