Creating DSLs in Java, Part 4: Where metaprogramming matters

Experience the power of dynamic methods with Scala and Groovy

In this final article in the Creating DSLs in Java series, Venkat Subramaniam lets you see for yourself why JVM-compatible languages such as Scala, Groovy, and JRuby are better suited to creating internal DSLs than the Java language. As you'll learn, dynamic typing has very little to do with why these languages are ideal for internal DSLs. So what's the special ingredient in the secret sauce? Read on to find out.

You learned in the last article in this series why the Java language is a better fit for creating external DSLs than internal ones, which are more dependent on the host language syntax. As I demonstrated, Java lacks key characteristics found in newer Java platform languages such as Groovy and JRuby. While both of these languages feature dynamic typing, it isn't key to creating internal DSLs. In fact, Scala, which is statically typed, is also a popular choice for creating internal DSLs.

So, what do these three languages have in common? Two characteristics you've probably heard about lately are essence over ceremony and metaprogramming.

All three of these languages allow programmers to accomplish goals with less ceremony than you'll find in older languages like Java and C++. Moreover, they all allow you to add and call methods dynamically, which is one of the hallmarks of metaprogramming. Let's look at some examples that demonstrate the power of essence over ceremony and metaprogramming.

Essence over ceremony

The Java language syntax is heavy on ceremony, which is one of the characteristics that lends itself to the writing of tomorrow's legacy code. Ceremony in this case means excess verbosity and irrelevant detail -- the Olde English of the Java platform. For example, in order to define an ArrayList of Integer in Java, you would type

ArrayList<Integer> list = new ArrayList<Integer>();

Further, even though you repeated the type Integer, the program still might send something other than Integer to the list and fail at runtime.

Some might blame static typing for this particular example of verbosity. In fact, Scala (which is statically typed) gets around the ArrayList example just fine by using type inference. For instance, when you write

var lst = new ArrayList[int]

Scala knows what type lst is.

Similarly, the following Java code

//Java
String str = "hello";
int length = str.length();
System.out.println(length);

can be more concisely written in Scala as

//Scala with essence
val str = "hello"
val length = str length
Console println length

Scala is statically typed, but infers the type of str as String and length as Int. Of course, if you want to add ceremony you can:

//Scala with ceremony
val str : String = "hello"
val length : Int = str.length()
Console.println(length)
1 2 3 4 5 Page 1
Page 1 of 5
InfoWorld Technology of the Year Awards 2023. Now open for entries!