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.
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
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
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
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)