Saturday, August 8, 2009

Grails and Groovy - too dynamic for the real world

After using Groovy and Grails on some bigger projects for months I've come to reconsider some of the advantages of this platform. In particular the fact that it's a dynamically typed language.

If you come from a statically typed Java background like I did, it might not even be very obvious in the beginning what dynamic typing implies here. In particular because Groovy is mostly a super-set of Java. In Groovy you can still type "Map map=new HashMap();" and it will work. A bit later you will get lazy and start typing "def map=[:]", which means the same, works the same and is a bit shorter to type. At that point I simply thought "score one for Groovy against Java" and continued.

The downside is that there is almost no compile-time checking in Groovy. This follows directly from some of its features:
  • Methods and fields can be added to objects at run time
  • The type of variables can change at run time
  • Groovy is very forgiving of null values and exceptions, in many cases continuing silently instead of aborting
This means that many of the compile-time checks of statically typed languages are impossible, but also that IDEs like Eclipse cannot provide many of the context-sensitive completion features that we're used to, and that many errors are flagged only at run-time when that particular line of code is reached.

For small single-developer projects with a prototyping/scripting nature this is likely not an issue, in particular when the developer has a lot of experience with Groovy and/or other scripting languages. For larger multi-developer projects the picture changes, even more so when developer experience level varies. In longer-running multi-developer projects maintainability can become a huge issue. Unit tests can help, but are notoriously difficult and time-consuming to create for web applications and applications that interact with many external systems.

When unit tests are lacking and compile-time checks are absent, the result can be trial-and-error programming and a very fragile code base. One example is refactoring, an important part of agile programming. In Java it's normal to refactor constantly, e.g. moving and renaming classes. The IDE will do all the grunt work of renaming corresponding references, and the compiler will help catch any resulting bugs. In Groovy this is not possible; the IDE cannot do the grunt work, so refactoring will be a manual process. Any missed references will not be found at that time, but only when that particular line of code is reached at run-time. I recently started realizing that Groovy offers a very bad trade-off for larger projects.

That you can type "def map=[:]" instead of "Map map=new HashMap();" is nice, and saves maybe 10 seconds at code-writing time. But if that means that hours are lost hunting bugs that would simply not occur in statically typed languages, hours lost searching for what are basically syntactic errors, then the downside becomes obvious in a very painful way.

Luckily this sad tale has a happy ending. For the particular projects that we're running we will simply continue using Grails - its advantages still stand. We will also still use Groovy for simple code snippets and scripting. For anything more complicated we will create Java classes and call them from Groovy. This is fully supported by Grails, and offers a best-of-both worlds escape.

2 comments:

  1. Have a look at Scala. The much-lauded dynamic typing is thrown overboard and thereby you get back all the advantages of compile-time checks. Ie, you do not have to create unit tests to be a substitute for compile-time checks. Furthermore, it's a first class citizen of the JVM as well and there is a Rails-like framework (Lift).

    ReplyDelete
  2. Interesting write up and I like some of the points made. The only issue I take with articles like these is the way people talk as if their problems are everyones problems. Just because one person can't make a dynamic language work on a large project doesn't mean that everyone can't. Some people do it quite fine. I know you mention that it may be fine for people that understand it well or have come from a dynamic background. Well many people do so its not impossible. There are plenty of developers out there that feel you can't build a good project with Java, or ColdFusion or whatever you want to name. Yet its done everyday. Everybody is going to have their favorite way to work efficiently.

    ReplyDelete