Quite Groovy

In the recent weeks, both of my co-bloggers told me independently of each other about Groovy, the new hipster language which brings the scripting goodness of dynamic languages like Ruby and Smalltalk to the JVM Sweet JVM, so I finally couldn’t resist but take a look at it. To be honest, I didn’t like its Java-like syntax from the beginning, with all the parentheses, lowerCamelCaseIdentifiers and such, but that was just because I prefer Ruby’s very lean syntax. Its concepts are very close to Ruby (modification of objects and classes at runtime, blocks/closures, etc.) and of course it integrates well with the Java platform and its rich libraries, since this is the purpose for which it was created, to add a scripting facility to the Java platform. Groovy scripts are compiled into bytecode before execution and thus run on a normal JVM.

A crucial part for dynamic languages today (at least in my eyes) is the creation of domain-specific language, which Groovy also supports. Gant, for example, is a Groovy DSL for Ant scripts. Another example (take from the Tutorial Domain-Specific Languages in Groovy, PDF) I find very practical is a DSL for creating query criteria for Hibernate in the Grails framework (formerly known as Groovy on Rails, so its purpose should be clear):

def c = Account.createCriteria()
def results = c {
  like("holderFirstName", "Fred%")
  and {
    between("balance", 500, 1000)
    eq("branch", "London")
  }
  maxResults(10)
  order("holderLastName", "desc")
}

A good thing, but looks too java-y for my taste, I miss the feeling I get when using a Ruby DSL, such as SQL-DSL, for example:

statement = Select[:column1, 'book', 10].from[:table1, :table2].where do
  equal :column1, 99
  not_equal :column1, 100
  less_than :column2, 'foo'
  less_than_or_equal :column3, :column4
  greater_than :column1, 0
  greater_than_or_equal :column2, 'bar'
  like :column1, 'any'
  is_not_null :column1
  is_in :column1, [1,2]
  is_not_in :column2, [3, 4]
  exists 0
  not_exists 0
end

But maybe that’s just personal preference.

From a few first glance I get the impression, that Groovy is quite successful as a scripting sidekick to Java and I’m curious to learn more about it.

APIs and DSLs

Today I stumbled upon Josh Bloch’s talk How To Design A Good API and Why it Matters at Google Tech Talks. Its loaded with profound wisdom and advice from one of the masters of API design.

He explains that API design is very similar to language design, and I immediately thought that this particularly holds for APIs which are designed as domain-specific languages, which is one of Ruby’s strengths (read this article from Oreillynet.com to learn more about DSLs).

A few slides later he talks about characteristics of good APIs:

  • Easy to learn
  • Easy to use, even without documentation
  • Hard to misuse
  • Easy to read and maintain code that uses it
  • Sufficiently powerful to satisfy requirements
  • Easy to evolve
  • Appropriate to audience

To achieve all these properties for an API is certainly non-trivial, but at least some of them get easier if you design APIs as a domain-specific languages: As the term says, a DSL provides a language that is tailored for a particular domain, in addition DSLs are generally declarative and hide language aspects that are irrelevant. Such a language is obviously easier to learn, use and to read than a mere API, and is more appropriate to its audience. In the end, these are known strengths of declarative languages. Here’s an example taken from the Capistrano manual (Capistrano is a Ruby DSL for remote software deployment):
[ruby]
desc “Start the spinner daemon”
task :spinner, :roles => :app do
run “#{current_path}/script/spin”
end

desc “Used only for deploying when the spinner isn’t running”
task :cold_deploy do
transaction do
update_code
symlink
end

spinner
end
[/ruby]
Though this doesn’t hide imperative aspects completely, I think it’s a good example of how a DSL feels - just as if it wasn’t Ruby but a different language.

So, is it safe to conclude that DSLs are the better APIs?