Saturday, March 04, 2006

Groovy & BeanShell: Dynamic vs Scripting Languages

In my previous post I talked about the fundamental difference between Groovy and BeanShell and in one of the comments I was asked to elaborate on why exactly Groovy is dynamic and BeanShell is not. So here it, BeanShell is a scripting language, it is to Java what VBScript is to VB, the syntax is near identical, you can copy and paste Java code into BeanShell and vica versa. This makes it highly useful for doing things like testing Java code in isolation, or trying out a Java API through an interactive BeanShell console.

It is 'dynamic' in the sense that it uses reflection to achieve a lot of these goals, but beyond the aformentioned use cases I would not choose BeanShell over Java to implement say a build system, or a my web actions, or do text processing, advanced regex, output templates, as a view technology, this list can go on...

The reality is that BeanShell does not provide any productivity gain so to choose to use it for a task over Java (rather than use it to script Java) has no real benefit and this is because it does not have any of the true features of a dynamic language like Ruby or Groovy. I'm a big fan of WebWork and I've been using Groovy to write XWork actions because the advantages are clear, I can save/reload changes, I can use closures to manipulate and sort my data model:

projects.findAll { it.status == 'open' }.sort { }

I can use GStrings, a concept known as string interpolation in languages like Perl and Ruby, and multi-line string support to easily manipulate strings:

def user = User.get(1)

def message = '''
Dear ${},

Thank you for registering with xxx site,

Your password is: ${user.password}.

See you soon!
The Site

There are many more examples of the kind of expressiveness mentioned above that Groovy allows in its syntax, but more importantly than all these syntatic niceties and what makes Groovy truely 'dynamic' is how methods (as well as constructors, properties etc.) are dispatched. Groovy has the concept of a MetaClass and it contains the methods that a class 'really' has as well those added dynamically at runtime, allowing new behaviours to be attached to new and existing classes. This is a feature Grails uses extensively to add behaviours to controllers, domain classes, tag libraries etc. all while still retaining the ability to use inheritence.

The reality is that Groovy and BeanShell are not really competing with each other at all, and address different problems entirely: BeanShell the scripting language for Java and Groovy the dynamic, agile language for the JVM. That is why I hope that instead of seeing articles like those written recently, we'll see some from the same people entitled "Using BeanShell to Prototype Java Code" or "Using Groovy to Power your Build System" as writing "Groovy is rubbish, and BeanShell is great" or vica versa is really not helping any newcomer who is interested in this space make an informed decision on which is the appropriate language for their use case.


Anonymous said...

Very good summary.

Anonymous said...

You're kidding yourself if you think there's a fundamental difference between BeanShell and Groovy. They solve the same problems. Labeling one "scripting" and the other "dynamic" (dynamically typed?) doesn't change the fact that they really only differ in what syntax sugar they support.

BeanShell supports scripting language like functions (i.e. working with files, etc.), but that's a feature, not a definition of the framework. Any other differences boil down to implementation details.

I personally prefer BeanShell's conservative evolution approach to Groovy's attempt to include everything including the kitchen sink. I seriously doubt Groovy's long term viability and ability to evolve and maintain backward compatibility.

The fact that you haven't provided any examples of BeanShell syntax sugar leads me to believe you don't know much about it. If I didn't know better I'd think that BeanShell was little more than a Java interpretter after reading your post.

Graeme Rocher said...

They solve very different problems Bob, as I said before I use both, for very different purposes if you can't see that you need to have a closure look at what a real dynamic language is. BeanShell will never compete with languages like Ruby, because it doesn't have the necessary feature set to do so.

I am very familier with BeanShell and yes it adds a small number of convenience methods (called commands in BeanShell speak), but they are nothing more than that: convenience methods. The only other 'suger' that beanshell provides is easy access to bean properties, and a for loop that doesn't require jdk1.5. And that is the sole productivity gain you get.

As I said before it would be pointless to use BeanShell as a substitute for Java to say write you web actions, because there is little productivity gain. I'm sorry if you can't see that Bob. BeanShell is great and shines when used for what it is meant for, prototyping java code, trying out APIs, as a small embedddable scripting component for server components etc.

Anyway I hate to see this degenerate into an argument about 'my tool is bigger than your tool'. Instead why don't BeanShell developers provide these examples, and promote their language rather than feeling the best way to do so is to spread FUD about another language. There is place in the world for both as as i said before they solve very different problems.

Anonymous said...

You're missing the point. I'm not pushing BeanShell over Groovy; I said why I'd choose one over the other, but choose whichever you like. Also, I'm not a BeanShell devloper; I'll let them speak for themselves. Are you a Groovy developer?

My problem is with your argument, not Groovy. Your argument makes no sense. Now closures define a "dynamic language?" What is a dynamic language? Do you mean dynamically typed language? BeanShell can and very well may support closures in the future. Will it be a dynamic language then?

You're trying to say Groovy and BeanShell solve different problems, but the reality is both are general purpose languages. The fact that you use two (actually three counting Java) languages to solve different problems doesn't change anything.

Graeme Rocher said...

I'm not a Groovy developer no, but I am project lead on the Groovy on Rails (Grails) project which clearly means I have ties to Groovy.

I understand what you're saying and no closures don't make groovy dynamic, as I mentioned in my post what makes Groovy dynamic is the way it dispatches methods through its MetaClass and in combination with closures and builders it allows the creation of DSLs which is not possible (at the moment) in BeanShell. And if it was to be made possible in BeanShell you would see BeanShell becoming a larger jar and more complex architecture as is the case with Groovy.

Yes all 3 (including java that is) are general purpose languages, but each excel in different areas. Personally, I use Java to implement my business interfaces, BeanShell to prototype java code, and try out APIs, and I use Groovy to write web actions, power my build system, output templates etc.

Each excels at each task, I would not use Java to power a build system (hence why we have ant), I would not use Groovy to write business logic or prototype java code (as the syntax is not exactly the same), and I would not use BeanShell to write a build system, implement controllers in an MVC pattern etc. Its all about the best tool for the job.

Anonymous said...

Actually, BeanShell does support meta methods which can be used to implement DSLs:

Anonymous said...

Hmmmmm... the URL got cut off. Search that page for "User Defined Commands with invoke()".

Anonymous said...

Darn it:

Graeme Rocher said...

Indeed, but Groovy's MetaClass facility covers instance methods, static methods, constructors, properties, fields, everything you can shake a stick at ;)

In addition the breadth of DSLs possible is highly limited without support for closures or builders.

Anonymous said...

Bobs usually switched on, but in this case he's missed the boat.

According to him, Ruby has as much in common with C++ as Python...

Graeme Rocher said...

Thank you for seeing the light Lyndon ;)

Bob, maybe its a case of we need a new definition that describes languages such as perl, ruby, python and groovy that doesn't conflict with the 'dynamically typed' terminology.

The fact remains these languages are vastly different to what a scripting language such as BeanShell or VBScript offers to their respective target languages (Java and VB).

Anonymous said...

Lyndon, Graeme keeps trying to steer the debate to "Groovy vs. BeanShell" when it's really about his flawed language categorization. I do differentiate C++ from Python and Ruby (and BeanShell).

Graeme, we don't need another category. There's nothing to stop BeanShell from adding any of those features whereas you can't say the same for a statically typed language like Java.

There is no such thing as a "dynamic language." "Scripting language" has always been synonymous with "dynamically typed language."

Debate Groovy and BeanShell on their features and other merits. Don't try to confuse users with false categorizations.

Graeme Rocher said...

*Sigh* I give up, we shall agree to disagree. In no way was a steering the debate to Groovy vs BeanShell I value the merits of both and encourage use of both as each has its advantages over the other (I'm not going to go over them again I already have done several times).

If I need to explain to you why BeanShell doesn't have the necessary features to compete (in the areas where these languages are strong I might add, true scripting of Java is not one of them) with languages like Ruby, Python and Groovy then what can I say, go and read a few books.

And yes BeanShell "could" implement these features, but as of today, as of this writing it doesn't have these features and hence can't be anything more than a scripting language for Java.

Anonymous said...

*I* give up. You're arguing feature sets. I'm arguing nomenclature (and correcting your factual mistakes, i.e. meta methods). Whether BeanShell is as powerful as Groovy or not has nothing to do with the classification of languages.

"Dynamic language" doesn't mean anything; it's not a word. Ruby, Groovy, Python, and BeanShell are all "dynamically typed languages." They are all "scripting languages."

I should read a book? That jab sounds asinine coming from someone who can't even bother to learn the correct terminology for his domain.

Graeme Rocher said...

Calm down Bob, I'm arguing that you can't say that BeanShell is the same type of language like Groovy, Ruby and Python. Maybe I have got the terminology wrong, but then I'm not the first one as many differentiate them with this terminology.

If you have a problem with this as it clearly does conflict with the term 'dynamically typed' as you say. Then fine, between you and me we'll call Groovy, Ruby, Python etc. Agile languages. Or does that conflict with something else? Hmm probably it does ;)

Anonymous said...

Calm down? I think you have a reading comprehension problem; you're detecting emotion where there is none.

"Agile languages?" Enough already!

Graeme Rocher said...

btw Bob, just as a side. I've appreciated this conversation, a bit of healthy debate is good and I do think we do actually agree (after having read the comments from top to bottom) we're just coming at it from different angles.

Whatever the culmination of the debate, my main point still remains and that is that there is space for both Groovy and BeanShell and its healthier all round if each promotes itself and more constructive articles are posted on blogs as to what is an appropriate use for each.

Graeme Rocher said...

read comprehension problem? Possibly ;)

The thing about agile languages was a joke btw, but you can't deny that different languages excel at certain things otherwise we'd also still be using CGI modules written in C :P

Graeme Rocher said...

Hmm seems like I have a spelling problem too.. that should read:

A reading comprehension problem?


Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...

Hows crap is bloggers formatting!


Graeme Rocher said...

Yeh Lyndon, as I said it is not just me that refers to these languages as such. The fact that it conflicts with the terminology 'dynamically typed' ain't my fault! ;)

For Bob this group of languages is clearly nameless, and every general purpose language is the same. Fair enough, everyone is entitled to an opinion.

Anonymous said...

Here's another (unrelated) article that touches on this debate :- article link

Graeme Rocher said...

An interesting read, note how the phrases 'dynamic' languages and 'scripting' languages were used by some seamingly intelligent people.

Clearly this phraseology is not limited to those who follow these languages as Bob seems to believe and there clearly is a differencce between a 'scripting' language and a 'dynamic' language according to many.

Gosling even went as far as to say that Ruby is a 'scripting' language (ie it is only applicable in certain domains, with the web given in Gosling's example), our dear creator of Java itself, though I can't say I agree with him myself, but it is nice to see someone actually seeing this differenciation.

Regardless, my point of view on this remains the same: BeanShell is a 'scripting' language that is limited in its use beyond a certain domain (i.e. scripting the Java language). Needless to say let the debate rage.

Anonymous said...

Any chance of getting some clues on groovy / webwork integration possibilities? I want to roll the dynamic capabilities of groovy into an existing webwork app...

Anonymous said...

Or even more interesting, integrating Grails into a current Webwork app. *grin*

Graeme Rocher said...

Christian Parker wrote a very good article on how to do this here:

I did alter his implementation slightly so that I didn't have to put .groovy on the end of my actions and it just worked out at runtime whether it was written in java or groovy.

In terms of Grails, well Grails is essentially deployed as a servlet so you can run it side-by-side WebWork if you want a migration path.