Thursday, September 25, 2008

Improve Groovy by Removing a Feature

Summer 1962... Nelson Mandela was being arrested, Algeria joined the Arab League, Spider-Man made his first appearance, and a working group convened to shepherd in the next release of ALGOL 60 (behold the milestones!). As C.A.R. Hoare writes of the effort:

"The group's main task was to design a subset of the language which would remove some of its less successful features. Even in those days and even with such a simple language, we recognized that a subset could be an improvement on the original."
Sage words from almost 50 years ago. Simple is better. Less is more. And C.A.R. Hoare is practically the grandfather of the simple language movement(Google for free version).

So what language feature would you remove from Groovy to make it a better language?

Now I realize there are good reasons why all the following features exist. The goal of Groovy is not simplicity; Java interoperability probably trumps simplicity in many cases. But considering the complexity of a language is a useful and fun thought experiment. Just don't take my list too seriously.

this, owner, delegate, self, super, it, huh? - It's hard to keep all the hidden variables straight in a closure. Is the 'it' default variable really needed? Delegate... seriously? You don't need delegate, and I guess you don't even need this, owner, and super. I certainly can't tell you what they'll reference at runtime without running a debugger session, especially since there seems to be a difference between a Script and a Class. Dropping almost all these terms leaves Groovy a simpler language with minimal lost productivity.

curry - I have a new mistress and her name is Functional Programming. I relish slipping away from objects and procedures to spend a few stolen moments with recursion and lambdas. But Groovy isn't a functional language, and curry adds little functionality that you couldn't achieve by simply wrapping a closure in a closure. Plus, many Java developers aren't familiar with the term. Drop it and rip those pages out of the Groovy books, making more room for something better.

Arrays - What a pain arrays are. Can't everything be a list? We all agree that primitive types make the language worse, but why aren't arrays grouped with int, float, and double as something we should just do without? So there'd be no way to invoke a Java method that was overloaded on List and Array. I'd easily trade that ability if I could get better implicit List to Array conversions within the runtime. Those "as Type" and "as []" statements are annoying... let's get rid of them.

GroovyInterceptable - invokeMethod is called for every method invocation. Oh, except sometimes when the object doesn't implement GroovyInterceptable. The flow of method dispatch is complex and ditching GroovyInterceptable would simplify the picture. While we're at it, ditching the weird Expando vs. MetaclassImpl issue would eliminate complexity too, but that seems more a bug fix than a language feature.

Implementing Interfaces with a Map - I'm not kidding about removing one of the best and most useful Groovy features. I love the syntax of creating partial interfaces, but have had issues with how the object is still a Map at runtime. Partial interfaces are a superb idea, and the syntax for creating them is wonderfully concise. But under the covers the thing is still a Map, not the type you are implementing. What happens when you pass it to a method that takes a Map? Have you ever gotten a NullPointerException because of a missing method on your Map-erface? You have to start thinking about the way Groovy is implemented to reason about this, which is a sign of edge cases and complexity. To make the language simple, I would keep the syntax for easy partial interface creation, but I'd use ASM to generate an actual object of the correct type under the covers.

Stack Traces - For application developers, Groovy stack traces contain a bunch of meaningless junk. I've held several team member's hands through their first foray into Groovy and apologize profusely on Groovy's behalf when the first stack trace is encountered. I'll almost claim that the excessive stack trace noise makes test driven development harder for newcomers, as they try to parse and diagnose what their failures are. This isn't a language feature though, just more of a complaint. Sorry!

So what would you remove from Groovy to make it a better language? And it's fine to argue against one of my items, but please suggest an alternative removal if you don't like one of mine!


graham said...

i'd like to see anonymous classes supported and the current replacement removed in reverse order of importance ;-)

Hamlet D'Arcy said...

Discussion on

Marcos Silva Pereira said...

Hum... delegate is useful when you are doing some metaprogramming:

String.metaClass.reverse = { -> new StringBuilder(delegate).reverse() }

How to achieve it without delegate?