James Strachan's keynote speech
Groovy Conference November 2004 (London)
So welcome everybody, it's good to see you all here. I've just hacked together a little presentation just to kind of give the state of play of groovy, what it's all about, what we're trying to do, what are the sucky bits we really need to fix really soon, and some of the things we might do in the future.
First off, why even bother with groovy, why not just use smalltalk, python, ruby and stuff? To me the big thing is platforms, platform is far more important than language syntax. The JVM, the Java platform, the VM rocks, the libraries rock, the platform, the community, the tools, the developers. There is no reason why we can't build whatever languages we want that play nice with the platform.
One of the whole reasons why Groovy came into being was, when you start writing things like porting python and ruby and smalltalk to java, you kind of end up with a leaky abstraction. To support smalltalk semantics, they're quite different to java, or to support python semantics it's really quite different and you end up with... kinda like two worlds, python objects over here, java objects over here, kind of bridges...
The whole aim of Groovy was to try to do something that felt like Ruby and Python and Smalltalk, but where everything was pretty much mapped onto the VM and Java objects, there is no impedence mismatch, there is no abstraction layer, everything works on real Java objects and is built on the Java platform.
It's worth looking back at where Java came from, and what the world was like when Java was invented. I think Sun's done a great job with Java, Java the language I'm talking about, well the platforms great anyways. Java the language, when it was created, one of the main reasons it got adopted was probably Applets, which is kind of funny. But the reason people, geeks like me jumped all over it, is because we wanted a better C++.
C++ was the systems programming language of the day, well there was smalltalk, pretty much people jumped on it as a better C++ . It was cross platform, easy to use, modular so on and so forth. And it was much less 'sucky' than C++
In the Java days, we tended to write everything, there was hardly any reuse, the only thing we reused, was maybe you could rewrite like x, you might have a stream library STL, but pretty much people used to write everything themselves on every project. The world's changed quite a lot now, we are integrating software components more than actually writing them. So the requirement for a systems programming language is kind of decreasing slightly and the need for more of a glue, duct tape kind of thing is increasing with time. Most projects I work on now, we're reusing 80-90% of all the codebases is just reuse, be it spring, hibernate, tapestry, plus the JDK as well.
The main requirements that was set for Groovy, which were never particularly articulated terribly well, or documented, which is the way on lots of open source projects. Was really that, it's an attempt to make something that's pretty much like a high level language, or scripting language, like Ruby or Python or Dylan. Dylan is probably one of the closest. A lisp guy would probably just say we're reinventing lisp again, which is fine as well. The main idea is it's got to map cleanly to Java bytecode. It needs to work with Java APIs and Java Objects. The root of all the object trees is java.lang.Object.
We want it to be a Java friendly syntax, now we can divert from Java, we don't have to be backwards compatible, in fact, we can't be really. There are a few smelly parts in Java, like equals, the == sign means different things depending on whether your using a primitive type or an Object type. So as soon as you go into dynamic typed world, and you've no idea whether it is an int or an Integer, it's pretty hard in a dynamic language to know the difference between the two. So == means comparisons for primitive types, it means identity for Object types. One of the first bugs I hit, and I hit it all the time, is writing x == 3, which we just naturally do without thinking in Java, and expect that to be a comparison. Hardly anybody puts == with Object types, because you hardly ever want to do identity based comparison. I think once in the last ten years, I've done an identity based comparison, it's not something that people really do, it's very rare.
So because we made that change, we pretty much can't be backwards compatible with Java, because we made that little, subtle change. == always means equality, which is what people always really mean anyway. So we can't be completely 100% backwards compatible, but the idea is to be fairly looky likey. The ultimate vision would be to be able to cut and paste Java code in your IDE straight to Groovy script. It can hopefully take out most of the crap you type, be a little bit more concise, but we're trying to be Java like, but not necessarily 100% compatible. And basically just sit on top of J2SE.
So a quick glance, if you wanted to in a very brief way, say what is Groovy. One of the first things, I remember I was going on holiday for a weekend, and the plane was late, so I thought, what shall I do, my wife went shopping, because she loves shopping, so I thought "Oh there's an internet cafe, let me go to browse.' And I couldn't think of much to read, so I thought "hey, I'll learn python". Bit of a geek and it's quite sad, but hey I'll learn python. So I sat there for a couple of hours and thought "you know what, this is kind of nice, I can create, in a tiny amount of text, a collection, a dictionary, I can add stuff to it, sort it, search it, do all that stuff". We work with collections and beans and whatever all the time, and it was kind of embarrassing that Java is so verbose for doing something so trivial as making a List of Objects. The whole difference between arrays and Lists, it makes you feel a bit dirty when you see what it should be like. So that was the first thing to get right, working nicely with beans and collections.
Closures are one of those things that take you a little time to realize why they're good, but once you've seen them you just love them. For me the best bit of closures is working with resources, whether that's files, databases, message brokers. I only really realized this when we started implementing closures, with IO. Doing something as trivial as loading a file, and processing it line by line and making sure you close the file properly if an exception occurs is surprisingly hard to do with one resource.
If you're reading from a file, and writing from a file, and maybe doing something else as well, that's really, really hard. And very few developers are capable of writing the correct try-catch to work with two resources maybe even three. It took me lots of goes just to read a goddamn file properly. Even just the little subtle differences that... you want to throw a close exception if you finish processing, without throwing an exception at that point, but if you finish processing and you've got an error halfway through you want to throw that exception and catch the close. So even just handling close properly on a file is hard.
Closures is a nice little trick from many languages, lisp, smalltalk, squeak and ruby that basically allows you to delegate the processing of collections or resources to a container object, and it calls you back for doing the trivial thing, like processing an object. It makes a massive difference especially in J2EE world, working with databases and closures is a dream. It is interesting the spring project has basically handwritten inner classes to mimic closures, which kind of works, but you end up with millions of these little interfaces which just have one method in, and you just think its... I mean it's a good solution for Java, but we could do a lot better. So closures are huge. To be honest it would be quite easy to add closures to Java, C# has done it with C#2, they've called them delegates. They're a little bit noisier than closures should be...
Operator overloading, anybody from a C++ background tends to get worried when that phrase is mentioned in mixed public. Just because it was the cause of so much issue and tension and bugs. If done correctly and safely, there is no reason why operator overloading can't work nicely, even if that just means arrays and Collections kind of feel the same in the language. Why should an array get a subscript operator, but a Map and a collection doesn't, it's kind of not fair. It's just about being a bit more fair, with the language.
Static and dynamic typing, this is a good pub debate, have a few beers and talk about doing static this and doing that in typing. If you like there are scripty people and anal static typer people.
"So which side are you on?"
I play both sides, I play for both teams. Static typing is great for systems programming languages, it's great for refactoring, it's great for IDE support and so on and so forth. However, just as you'll know with VisualAge and stuff, IDEs can, the first refactoring browser was smalltalk. There's that python refactoring... we met the guy in the pub the other day. You can do refactoring browsers and IDEs totally in dynamic languages, but modern java IDEs are just so good, that even if you just use static typing as extra metadata to make the IDE do great things for you. Due to the IDE kick it gives you I do quite like static typing quite frankly. But then there are sometimes when you just want to hack up a little script, and you just want the typing to get out of your face, and you just want to do something. Dynamic typing is great for verbose concise scripts.
There are also times when you're doing very dynamic things, with more and more networked and message oriented and web service oriented and all this kind of stuff, static typing doesn't really make any sense in those kind of dynamic worlds. For example if I'm processing a SOAP BLOB casting these things to specific types and walking a big object tree is pointless, because everything's getting increasingly dynamic and message oriented. So static typing has lots of value in infrastructure but increasingly in duct tape code there's little value.
I think both have got pros and cons, and it kind of depends what you're writing. If you're writing a library or a framework, static typing is good for refactoring. If you just want a little script to do something, you probably don't really care about static typing. I think there is a middle ground as well, where the language should be clever enough detecting static typing, under the covers, so it looks dynamically typed, but it kind of figures stuff out for you. If you say x = "foo" it should always know that x is always a goddamn String, unless you assign it to something else.
The idea behind Groovy was always to do both, to have static typing and dynamic typing. From an implementation perspective it was really easy to do everything dynamic to start with and actually never get around to doing anything static. But the idea was always that you could put type metadata there, that's mainly so an IDE can do something cool or whatever. One of the first reasons to put any static typing in was... The world's not going to all of a sudden one day turn Groovy and throw all the Java code away, so it's always going to be a partner in the Java platform. And so anything you write in Groovy you want to be able to give it as bytecode to a Java guy, and in Java land things have types, if everything is an Object, it's pretty hard to use.