Epic codefest: 7 programming languages in 7 days
- 04 March, 2013 14:59
Much of today's buzz is about alternative programming languages, and the pitch often emphasizes "increased developer productivity" (IMHO, a sham on multideveloper projects). As long as the language has garbage collection, strings, real types, and so on, it shouldn't matter. This means nearly anything at a higher level than C or its mangled Neanderthal cousin C++ should reap the same productivity out of your developers.
That said, a shiny new hammer will always be tempting to those who get infatuated with their tools. But to pitch a switch to another programming language, you need to prove to your boss that the transition costs aren't ridiculously high. Here I would agree with the proselytizers for change. It doesn't take much to train good developers to learn a new language -- so I decided to prove it.
Most business apps are just big versions of what I like to call "Granny's Addressbook," a simple CRUD application that doesn't need to scale or be protected against cross-site scripting attacks because it lives on GrannyLAN. These apps take requests and write them to the database. They read from the database and display the results on a Web page. There's not much more to them.
So what better way to get a first look at the cost of switching programming languages than to turn Granny loose on a bunch of developers and break them in on a language and tools they've never used before?
These aren't necessarily "best practices," and with a 24-hour deadline, there are bound to be mistakes. Still, the code is a good idea of comparative implementations in the various languages, as you'll see.
Most developers implemented Granny first in Java and Spring, according to our staff dev guide for a comparable experience. Then after many moons, they implemented it in their assigned "new" language. Aside from the overall guidance above (be "quintessential" and "conventional"), nothing was dictated, like "use higher order functions" or "declare your types." Then each developer was asked some basic questions.
What makes this language special?
What did you like about it?
What frameworks and runtimes did you use?
What IDE, editor, and so on did you use?
How did you build Granny?
Now that you're done, would you find it easier to implement Granny again in Java (or whatever language you are most skilled in) or in the new language we assigned you?
What things did you learn that you will take back to your "day job"?
Where did you get your questions answered?
Would you recommend using this language on a project; if so, where/when?
What was the biggest drawback (besides lack of familiarity)?
Following you will find the takeaways from this experiment in programming language transition, as told by each Granny's Addressbook developer.
Day one: Java Granny
Java is obviously a well-established language with a substantial community behind it and abundant documentation.
I used the Spring MVC framework and the Spring Tool Suite IDE. Having no experience setting up back-end frameworks, I relied on the suggestions of my colleagues in making this decision. Jackson with Jersey was another option, but we decided Spring would be easier to work with in the end, albeit more complicated to set up.
As a front-end developer, I've never had the occasion to get familier with REST Services or controllers, let alone try to implement them. Now when my back-end colleagues talk about database connections and POJOs (Plain Old Java Objects), I can nod knowingly instead of letting my eyes gloss over. Fortunately, my programmer colleagues were all very helpful in pointing me in the right directions. Deep Mistry (yes, that's his real name) was especially helpful getting me through the Spring setup.
Day two: Kotlin Granny
Developer: Lifford Pinto, Java/Spring guy with his head in the clouds
Given that Kotlin is a fairly young language, it wins coolness points. A new language is a programmer's turn-on.
I don't think it would be fair to say that I liked or disliked it, considering the fact that I spent only a day working with it. It does have enough appeal to make me want to revisit this exercise without the constraint of the do-it-in-a-day deadline. It was easy to set up, and the documentation has several examples to help you get familiar with the language. I appreciated that the Kotlin team was willing to provide us with mentor support even on short notice.
I do most of my development work on Eclipse-based IDEs, but the obvious choice of IDE for Kotlin was JetBrains IntelliJ. I used the Kara Framework to quickly set up an MVC application. It's hard to say if this was "quintessential" or not -- Kotlin hasn't been around long enough. Regardless, this was easy to work with and set up. I couldn't easily figure out how to communicate to the front end via JSON, so I quickly switched to hack string manipulation to get 'er done. Talking to the database was easy via Kotlin's JDBC library.
Day three: Ruby Granny
Developer: Brian Crucitti, "The New Guy"
What makes Ruby special for this particular type of development is Rails, a framework for Ruby that I'm sure most people have heard of. Once I had a basic grasp of Rails, putting this application together was incredibly easy.
I didn't have many questions or trip-ups making the app. In preparation, I studied the Rails tutorial. The first few chapters were enough for me to set up almost all of the Ruby aspects of Granny's Addressbook.
I would definitely recommend using Ruby for all sorts of projects. It's a language that's very easy to read and write. I would definitely recommend using Ruby and Rails for Web applications, especially small ones.
If I had to write a similar application again, I would definitely choose to write it in Ruby over just about any other option, especially with Rails. It was so easy to set up the basic outline of the app, which is all a Granny-level app really needs.
The one drawback to this project is that I don't feel like I learned very much Ruby. I learned several Rails commands, which did all the work in creating the Ruby files for me. As I've stated before, this project was very simple to achieve using Ruby and Rails. I'm sure there's a wealth of powerful abilities in Rails and Ruby, but it wasn't called for here. I'd like to study them more.
For development, I used TextWrangler for the Mac because I like text highlighting and it has a convenient method of switching between files in a directory tree. I ordinarily use Notepad++ for Windows, and TextWrangler had a similar feel.
Developer: Deep Mistry, Java/Spring guy hell-bent on a NoSQL future, and yes, that is his real name
I used Node.js and Express framework. I also used a node-postgres client for Node.js to work with PostgreSQL as a back-end database. I used JetBrains WebStorm IDE, which I found very easy to work with, especially since I'm already familiar with IntelliJ IDEA. WebStorm has extensive support for Node.js and Express. In fact, it includes the option to create a Node.js Express project out of the box. (WebStorm is proprietary, but I used the 30-day trial version.)
To create Granny, all I needed to do was to create a right run configuration using the app.js file (which WebStorm auto-generated), and I was good to go. One thing that I did struggle with was the lack of an option for plain-old HTML views. Instead, I was offered .jade and .jshtml views, which I was completely unfamiliar with. I did find a simple work-around, however; instead of configuring the IDE to use HTML, I let it use Jade and simply performed import <foo.html> -- and I was done.
The other drawback is that there doesn't seem to be any extensive, easy support for databases. Yes, I was lucky enough to find a Postgres client, but that was an open source project written by someone who used the framework before. Let's say I wanted to switch to MongoDB, Neo4j, MySQL, Couchbase -- there's support for a few of these, but the switch wouldn't be easy. We basically would need to rewrite almost all the code.
Day five: Go Granny
Developer: Brian Crucitti, "The New Guy"
Google Go was a rather frustrating language to work with, both in terms of documentation and in looking for solutions to problems. "Google" and "Go" are such common words in Internet articles that searching for, say, "Google Go as a server-side language" or "Google Go tutorials" is almost useless. And searching with the two words together in double quotes eliminates many of the articles that refer to the language simply as Go or Golang. Searches using "Golang" eliminated a lot of pertinent articles as well, including quite a bit of Stack Overflow, which refers to the language as "Go."
The home site for Go actually provides a brief tutorial on how to write your own wiki page, which I worked through with plans to refactor it into the back end of my Granny Addressbook application. Unfortunately, the tutorial ended after giving out some code snippets that were not fully explained, leaving me high and dry with no other option than to dive into the documentation to try to find out what exactly was happening in the bits of code I had received.
I think I was expecting something along the lines of the Android developer documentation; what I got was short descriptions and a lot of search-bar use. A search for http.request, an unexplained object that seemed to be very important in the tutorial, resulted in a brief description and some code. This code showed it was a structure made of primitives and other structures. If I actually wanted to know what it did and what I could do with it, I would have to spend time searching out all those underlying structures.
I can see the advantages of using Google Go for certain projects. It is C-like, but not quite as rigid, and the lack of .h files and makefiles is a definite plus. I imagine that anyone skilled in Go could definitely create some amazing programs. There are, however, easier (and more search-friendly) languages that can accomplish the same tasks.
If I had to do this application again with the choice of Go or Java, I would definitely choose Java.
Day six: Scala Granny
Developer: Michael Brush, "like a hairbrush," Java/Spring guy
What makes Scala with the Play framework special is that it seems to be trying to make Java simpler.
Scala is similar to Groovy in that it is almost a scripting language on top of Java. Play is the equivalent of Grails as the Web framework that sits on top of Scala, and it seems to be the community's standard way of working with Scala. Scala/Play compiles all of its code into Java, and developers can use any Java class in the Scala language. Of course, Scala and Play themselves have a lot of classes that are intended to be used for the simplification and scalability of Java.
Scala/Play was easy to set up and use. I liked the way that you define the URLs for the application. There is a separate file that feels like a hosts file. This makes it easy to see all of your URLs in one location. It was also easy to understand what you were returning to the Web page. For instance, to return a 200 success, you just use the Ok() method with the contents of what you'd like to return.
I did my coding in Eclipse using a Scala plug-in that installed with no issues. There is not a plug-in for Play, so I also kept a console window open when I needed to do things specific to Play.
The build was done from the command window. Play has a console that you use. You browse to the root directory of your project and type play. This runs a few items, then you're in a command-prompt window specific to Play.
To build the project, I just ran run (and used clean if I needed to clean the project). This builds the project and starts it running on an internal Web server. After it is started, you can switch back over to Eclipse and develop; you don't have to touch it again. It compiles each time you go to the website that is set up.
I'd have to become more familiar with Scala/Play to know whether I would recommend it for a larger project. I don't know yet how models interact, but for something along the lines of Granny, I'd definitely use Scala/Play again.
One reason is simplicity. Sometimes I overcomplicate a problem, and I did just that with one of the issues I was having with this project. I was dead-set that if I didn't code the project a certain way, you could not have an address with blank fields. I finally decided to let that hang-up be, and it turned out what I was trying to do wasn't necessary and the framework took care of allowing the blank fields on its own.
James Iry at Typesafe was a big help with the project, especially with getting my big issues resolved.
I would recommend Scala on a project. For now, I'd start on small Web-based projects, but I can see that with some more knowledge, Scala could be useful for big projects as well. It's flexible and simple.
Documentation was the biggest issue with Play. It's a young framework (1.0 was released October 2009), and they are still improving and simplifying it. Specifically, I had problems marshaling and unmarshaling JSON. It appears that this has gone through a few iterations. I think this is a good and bad thing. The developers of Play appear to be listening to the community and are improving Play based on what the community wants, but this means a lot of changes between versions. As a result, it's harder to find information for the version you are currently working on. At some point as the framework gets more mature, this will slow down, and the documentation and answers on Google and the like will get more consistent.
Day seven: Clojure Granny
Developer: Shameem Mohamed Ali, who floats like a Java butterfly and stings like a Spring bee
A descendant of functional programming languages like Lisp, Clojure provides all the advantages of functional programming such as lazy initialization, dynamic binding, and macros. It also allows for integration with Java libraries, which could come in handy for operations such as date-based calculations. In addition, Clojure allows you to alter running code, making it a highly dynamic language.
I used the open source Web framework Compojure and wrote my code in Eclipse. I tried installing the Counterclockwise plug-in to run the project in Eclipse, but I had issues with the installation. The plug-in from the website seems broken, in my opinion, as it did not let me create the project in the standard directory structure that was expected for Clojure projects.
I also used Leiningen to compile and run the project, as it is the preferred way to run Clojure projects, according to users in the Clojure community. It took a while to figure out how to build a Web app using Leiningen; I had hoped to find a plug-in to build the app inside Eclipse itself. I would still prefer implementing the Web app in Java over Clojure as I feel it is easier to return dirty and impure objects from Web app coded quickly in Clojure.
I haven't done a lot of functional programming, but did learn a bit about it during the one-day exercise. I also learned about the various frameworks available for developing a Web app using Clojure before choosing Compojure.
Clojure does not have a monolithic framework analogous to Java's Spring. In fact, the Clojure community upholds a motto of "not tying components together to form a monolithic framework." Instead it provides smaller frameworks for specific functionalities, allowing users to mix and match based on their requirements. This might be a boon, but the pitfall is increased development time meshing together various frameworks.
My Clojure mentor Alan Dipert was of great help in directing me toward Leiningen over the problematic Eclipse plug-in Counterclockwise. He was also great in answering my questions along the way.
I would recommend using Clojure for functional programming rather than whipping up a Web app. Clojure has a higher learning curve for those of us more versed in object-oriented languages, which was probably the biggest drawback I saw. They are few tutorials on the Web, and the ones I was able to find seemed less informative than tutorials for other languages. There are a number of frameworks for developing Web apps in Clojure, such as Compojure, Noir, and Hiccup, but there aren't a lot of detailed tutorials aimed at using the frameworks, adding more to the learning curve.
As with any experiment, it's probably a good idea to reflect on the methodology in practice before drawing any quick conclusions about the results.
What we found was that a day was probably too aggressive. Some folks took closer to two days to deliver Granny in their respective language by the time all was said and done. Most delays were simply hitting a "snag" like a typo in a connection string parameter.
Having different people work on each language probably skews the results in terms of gauging which language would provide the "easiest" transition. Was Ruby done really quickly (matter of hours) because Brian is fast or because Rails generates most of the scaffolding for you?
Of course, people learn at different paces and have different skills. Still, it was really neat to watch this come together. I hope to follow up in the near future with more highlights on each language, especially some of the less mature ones.
Are the transition costs between two languages as difficult for a developer as people make them out to be? No. For new projects, knowing that the transition costs between two high-level languages aren't really that high might make it an easier sell to your management. Of course, "It's Monday so let's rewrite everything in Erlang" will make you seem like a Hipster Hacker at best and a clown at worst. That said, maybe your boss is open to allowing the next project be built in Ruby or Scala because you promise to at least learn the basics in a day.