Showing posts with label groovy. Show all posts
Showing posts with label groovy. Show all posts

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.

Friday, June 5, 2009

Grails script runner featuring dependency on other projects

One of my favorite uses for Grails is scripting, as I've stated before. However, I stumbled over re-using code from other Grails projects in Eclipse.

With Java projects I'm used to interdependencies - for example larger projects are split up into sub-projects. All external libraries are put into the 'Lib' sub-project and can be used from the others, which makes the other projects look cleaner in Eclipse. To do this you simply use the Eclipse build path for the Eclipse compiler, and build.xml for Ant-driven build and deployment.

With Grails this isn't so straight-forward. In particular because running scripts does not go through build.xml at all. To influence the Eclipse compiler you can still use the build path, and include other Eclipse projects there. To influence what happens when you run a script from the command line you have to use a custom script runner. This isn't so bad because for some other features (enabling GORM) you have to use a custom script runner anyway.

An example is available here: ScriptRunner.groovy. Put it in your project scripts folder together with the scripts you want to run, and invoke it as grails [env] script-runner OtherScript [parameters..]

The magic for this particular purpose is in overrideCompilerPaths, which is mostly copied from _GrailsCompile.groovy in the Grails distribution but has the added line:

src(path: "${basedir}/../OtherProject/src/groovy") // added path

You'll have to add a line for each folder of each project you want to use code from. It isn't very elegant, so please let me know if you've found a better way to do this.

NB If you also use the Grails web app in this project, you'll also have to create a script like this: RunXApp.groovy, and instead of grails run-app use grails run-x-app.

It's a bit of a hassle, but once it's smoothed out you have a scripting environment where:
  • You can map domain classes to the database using only a few lines of code (using GORM and the data source provided by Grails you only have to add domain classes yourself).
  • You can use all the power of Grails, Groovy, Hibernate and Java from your scripts with zero extra setup.
  • You have a dynamically generated web app to view and edit your domain classes at virtually zero extra cost (you only have to run create-controller for each domain class and replace the controller body with def scaffold = default).
Neat.

Monday, May 11, 2009

Groovy/Grails versus Perl continued

I've had some critical feedback about my previous post, where I compared a lot of programming languages with the Groovy/Grails combination and claimed G/G was the clear winner.

It struck a particular nerve with Perl people, who claimed I had omitted some important developments in their language in the past years. (I hope the PHP people won't find out what I wrote about their language or I'll have to go find my asbestos suit).

Before I go into the details of that discussion, first a brief remark about C#.Net. One of the commenters pointed out that I hadn't really demonstrated G/G's superiority there, merely used some tricks of logical reasoning. While I wouldn't want to discount logic, I have to admit that carey was right. .Net is a very broad platform, and there are some situations where Grails and Groovy cannot replace it. One example is that .Net can be used to make Windows DLLs. Of course no sensible G/G developer would want to make Windows DLLs anyway, but still.

Then Perl. Some people claimed I really needed to take a look at Moose and Mouse, two OO extensions for Perl 5 that can complement/replace the default Perl 5 OO abilities. I said previously that Perl 'lacks elegant OO' and I still stand by that remark. Three different OO subsystems? In one language? It's certainly an accomplishment, but in my view not a positive one. Think of all the subtle errors and maintenance issues that can be created when those subsystems are mixed in a single program.

Others claimed I should have said something about Catalyst. Catalyst is a web framework for Perl that is vaguely Ruby on Rails-like. At first glance it looks good - with a solid set of features on offer. An immense set of features. In facts the developers have managed to support practically every single Perl technology known to man. All kinds of persistence libraries. A broad selection of view/templating modules. No wonder that users complain of its complicated syntax. Like with the three OO frameworks, it shows that developers couldn't agree, couldn't make up their mind on what they really wanted. So instead they added everything in and hoped for the best. In Perl it's even an official language philosophy (There's more than one way to do it, aka Tim Toady). Java also suffers from this 'feature creep', with frameworks such as Spring and AppFuse, that try to support so many different ways of doing things that they lose sight of what developers want: simplicity and productivity.

So - how do I say this tactfully to Perl fans? You're sitting on a cooling body guys. A quickly cooling body. And instead of simply running away you're trying to cover up the evidence, waving Perl's arms and saying: 'see, it still moves!'.

To make real progress sometimes you have to select only the best parts of what you have, and jettison the rest. Groovy and Grails have done that for Java and its jungle of web frameworks. I hope Perl 6 will do the same for Perl, soon.

Update: please see here for Chromatic's well-written response. It's obvious that we don't agree 100% but I hope the combination of viewpoints makes for an interesting read.

Friday, May 8, 2009

Groovy is the new Perl / Java / ...

The past weeks I've been doing some programming with Groovy and Grails, a relatively new programming language/web application framework, and I'm starting to like it a lot. It's not perfect, but I think it can beats it competitors, with one hand behind its back.

In the past I've done a lot of Java. It's a very good language, but it has some downsides:
  • It's not suitable for scripting. Its syntax is simply too verbose, it's strictly Object-Oriented, it has to be compiled, etc.
  • It doesn't have a single best web application framework. There are so many of those in the Java space that is practically impossible to keep up with them, all have pros and cons. If you pick one now you can be sure that it's hopelessly outdated in 3 years. It's getting to be a big mess.
  • It doesn't have a single best Rapid Application Development environment. This is related to the previous point - in my view programming is all about productivity and maintainability. Maintainability of Java programs is mostly good, but productivity is mostly not so hot. The JSF framework is very promising in this area, but because of all the fragmentation and FUD it's gaining traction slowly.
On the other hand Java has one big plus: It's powerful. With all it's standard libraries, myriads of Open Source frameworks and support from all the big vendors (except Microsoft) it's everywhere.

So now we have Groovy/Grails. Let me show you how it beats all its competitors and predecessors:
  • Java. This one's easy. Instead of fighting Java it simply stands on its shoulders. Groovy can do everything Java can do because it's Java-based. You can use all those libraries, if you want all the frameworks too (even though Grails is the way to go). And Groovy is good for scripting. Matched with Grails you get a scripting language with an excellent ORM and dynamically generated web interface thrown in for free.
  • C#.Net. Groovy and Grails are Open Source. Besides C#.Net is mostly a Java wannabe, so if our new favorite can beat Java it can surely beat .Net.
  • Ruby on Rails. Conceptually and feature-wise Ruby/RoR and Groovy/Grails are closely matched. However the fact that Groovy is Java-based is such a strong advantage that it makes Ruby/RoR irrelevant. Grails also offers better run-time performance.
  • Delphi. Even though Delphi has fallen out of fashion it is probably still one of the best RAD environments ever. It is only recently that JSF and Swing-based tools come close in terms of productivity. Grails takes this RAD ability one step further in RoR fashion: an Object-Relational Mapper that is 100% to the point, dynamically generated web interfaces and the ability to fall back to custom coding wherever you want, with full Groovy and Java power available.
  • PHP. PHP is all about hacking together a web interface quickly, without thinking about maintainability, re-using code etc. If requirements change a lot PHP code will quickly become spaghetti. Security is weak. Let's face it: 1995 called and wants its language back.
  • Perl. I've used Perl a lot in the past - it used to be the king of scripting languages. Unfortunately in 2000 the Perl developers lost touch with the real world and started to develop the perfect scripting language, Perl 6. They're still at it, apparently. Meanwhile Perl 5 has become hopelessly outdated. It lacks elegant OO and a good web framework, to name only a few downsides. Its syntax is so compact (there is some truth in the joke that every randomly typed string of characters is a valid Perl program) that maintainability suffers. Groovy has none of these downsides, and - as far as I can see - doesn't miss any of Perl's major features.
Nothing's perfect. So what are some of the things that could push this winner to even greater heights?
  • Documentation. Groovy/Grails have a lot of power, but some of it is very hard to find. There isn't a single place where it's all described in full. Often you have to make do with some basic examples and a lot of Googling.
  • IDE support. It's clear that one of the main concepts behind Grails has been to make an IDE unnecessary to a large extent. Don't Repeat Yourself and all that. You can get by with just a text editor. Also, Eclipse and Netbeans have basic support. Still, it would be nice to have better debugging and real-time syntax checking/refactoring. Here Java still has a clear advantage.
  • Spring-based. I was a bit disappointed when I found out that Grails is Spring-based, because it adds an extra layer of complexity that is (in my view) often not really needed. In practice Spring stays out of the way when you work with Grails so this isn't really a major issue. It does add to the very very long stack traces that you get when something goes wrong though..
  • Grails views are not component-based. Some effective tag library magic is used to give a first impression that is JSF-like, but the full power of JSF with its drop-in visual component libraries, data binding and IDE drag&drop visual design are missing. It's likely that JSF support will be added to a future version of Grails. I'm not yet sure if that will be an improvement (worst-case it will take away a lot of Grail's simplicity and push it back into the shark-invested waters that make up Java's web application framework landscape).
Anyway. If you do a lot of web programming and /or scripting, then you really owe it to yourself to take Groovy and Grails for a spin.