Friday, February 17, 2012

Language-in-Language and Extensible Literal Types

It is a pretty common scenario these days to create an application using a general purpose programming language (like java or Dart). And then sprinkle in more specialized languages like sql or html as needed.
Martin Fowler uses the terms host language and domain specific language (or DSL). He wrote a whole book on this topic.

DSLs are a fascinating topic, and much has been written on the subject. But what interests me is the question of how we integrate all of these DSLs into our application. That's was this post is about.

DSL as String Literal

Probably the most common way to embed a DSLs into a Java app is with string literals, where the stuff inside the quotes is the DSL. Here are a few examples:
sql
String q = "SELECT id,firstName from person";
html
String h = "<div>Hello</div>");
regex
Pattern.compile("[dD]ave");
jpa
String q = "SELECT p.id,p.firstName from Person p";
css in html
String h = "<div style='color:red'>Hello</div>");
The problem with putting a language inside of a string is that the IDE (or other tools) cannot help you very much, particularly in terms of:
  1. catching your errors
  2. refactoring
  3. auto-completion
  4. syntax highlighting
  5. debugging
Now, if your host language has no types (like JavaScript) or you don't use an IDE then you are probably accustomed to not getting help in these areas.
But my primary host language does have types (Java) and I do use an IDE (Intellij). So I aways try to code in a way that maximizes the IDEs ability to help me.  But for string literal DSLs this is difficult.

DSL as API

Another solution is to replace the string literal DSL with an api. This is what jooq does:

This addresses some of the problems mentioned above with "DSL in String Literal". But it is usually more verbose.

APIs that look like a DSL

In some languages (particularly Ruby) there is great latitude in the way api's can be defined and called. So much so that a Ruby API can very much look like a a DSL. And its not in a string literal. It's actually part of the language. And the distinction between API and DSL starts to become blurry. Martin Fowler calls these internal DSLs. Here is an sql select statement in a Ruby internal DSL:
statement = Select[:id, :firstName, :age].from[:people].where do
    equal :lastName, 'Ford'
    greater_than :age, 21
end
An Internal DSL is really just an API that looks like a DSL.

IDEs and DSL String Literals

Some modern IDEs are smart enough to figure out that a string literal is actually a DSL - and provide some extra help. This is a really cool feature! Below are screen shots of Intellij's awesomeness with string literal DSLs:
sql
jpa
regex
css/html
I can't overstate how useful this functionality is. It is so useful that, in my opinion, this should be a major consideration in any new general purpose programming (GPL) language. That is: how well does the GPL (and it's tooling) deal with language-in-language.

Multi-line String Literals

Many languages allow string literals to span multiple lines. For example, in Dart you can use the triple quote:
String html = '''
  <table>
    <tr><td>First Name</td></tr>
    <tr><td>Last Name</td></tr>
    </tr>
  </table>
'''

String Templates/Interpolation

Most languages that support multi-line string literals also support string interpolation. For example, in the Dart multi-line string example above, you can embed a Dart expression inside the HTML using the ${  } syntax:
Person p = getPersonFromSomewhere();
String html = '''
  <table>
    <tr><td>First Name</td><td>${p.firstName}</td></tr>
    <tr><td>Last Name</td><td>${p.larstName}</td></tr>
    </tr>
  </table>
'''
In this case, what we really have is a String template.

DSL Inversion

Another solution to this problem is to flip it. For example, instead of embedding html in java,  embed java in html. This is what JSP is all about. HTML is the host language and java is the embedded language.

DSL Literals

Java Literal

In JSP, java is not embedded like this:
'''
int x = 4;
int y = 2;
int z = x + y;
'''

Rather, JSP supports a java literal:
<% 
int x = 4;
int y = 2;
int z = x + y;
%>

Reg Ex Literal

JavaScript supports the regular expression literal:
var r = /[dD]ave/;

Extensible Literal Types

Given the prevalence of language-in-language, I think any new language should have some mechanism for supporting this. I propose a modifier to the triple quote syntax that adds some suggestion (to tooling and readers) as to the type of string contained:
Sql q = sql'''
  SELECT id,firstName 
  from person 
  where id = 7
'''
Html h = html'''<div>Hello</div>'''
Regex r = regex'''[dD]ave [fF]ord'''
Jpa q = jpa'''
  SELECT p.id,p.firstName 
  from Person p
  where p.age > 21
'''
Html h = html'''<div style='color:red'>Hello</div>'''

Templating

I want the above mentioned extensible literals. But i also want to use embedded ${} expressions:

Sql q = sql'''
  SELECT id,firstName 
  from person 
  where id=${p.id}'''
Html h = html'''<div>Hello ${msg}</div>'''
Regex r = regex'''[dD]ave ${lastName}'''

Jpa q = jpa'''
  SELECT p.id,p.firstName 
  from Person p
  where p.age > ${p.id}
'''
Html h = html'''<div style='color:${color}'>${msg}</div>'''


This creates some extra complexities. For example, should the string be parsable before the embedded Dart expressions are evaluated? I think so. Otherwise, IDEs and tools would not be able to help much, defeating the whole point. Therefore, there must be some restrictions placed on where in the string, ${} expressions are allowed. And this would be different for each DSL.    

For example, the following would not be a valid template, even though it evaluates to a valid SQL statement:

var s = 'ECT';
var q = sql'''
  SEL${S} id,firstName 
  from person

Bottom Line

A few things are certain:
  • Language-in-language will always be needed, especially on the web. Whether is called templates or DSL or polyglot programming. Its here to stay.
  • We need something more than just a multi-line string with interpolation for these embedded DSL's. We want our tools to help us find errors early, refactor, auto-completion, syntax highlighting, debugging. We want self documenting code.
The two possible solutions i can think of are:
  1. Extensible literals as proposed above
  2. Internal DSL's
I prefer the extensible literal approach, primarily based on how awesome this is in IntelliJ with Java. And that's without any special language support at all. 


Saturday, February 11, 2012

Dart's noSuchMethod Feature

In Dart, a call to a non-existent method on an object will be routed to a special method named noSuchMethod(..) which all objects inherit from Object. For example, if you run this code:

p1.jump();

and p1 doesn't have a method named jump then Dart will instead call:

p1.noSuchMethod(..)

The default implementation of noSuchMethod (the one from Object) just throws a NoSuchMethodException, which is typically what you want. But you can override noSuchMethod to some useful things. First, I'll show you a trivial example, to illustrate the basic mechanics then I'll show a slightly more practical use-case.

Here is the simplest possible example:

class Box{
  noSuchMethod(InvocationMirror invocation) {
    print(invocation.memberName);
  }
}

main(){
  var b = new Box();
  b.foo(); //prints foo, the method name
}

Since b does not have a foo method, it calls our noSuchMethod method. This is obviously not very useful. Below is a more practical example.

A more realistic use-case
Many developers like to access and update database records as objects. This is what Java's Hibernate and Rail's Active Record and Django's Object-relational mapper do. One way to do this is to wrap a generic map or database record with a class as in the example below:

class Person{
  
  DbRecord record;
  
  String get firstName() => record.getFieldValue("firstName"); 
  String get lastName() => record.getFieldValue("lastName"); 
  String get age() => record.getFieldValue("age"); 
  String get fullName() => firstName + " " + lastName; 
  
}

The thing to notice here is that 3 of the 4 getter methods are completely generic. Here is how this could be made easier using noSuchMethod:

class Person{

  DbRecord record;

  String get fullName() => firstName + " " + lastName; 

  noSuchMethod(InvocationMirror invocation) => record.getFieldValue(invocation.memberName);
}

By extracting this into a generic base class it become a bit more useful.

Like many of Dart's features, this is not something ground breaking. Dart's nosuchMethod capability is similar to Ruby's method_missing and Python's __setattr__.



Sunday, February 05, 2012

Run Anywhere

A key bullet point in the evaluation of a new general-purpose programming language is this: does it execute where my client's need it to execute?

Two key trends influence this point:
  1. Web apps are moving from server-heavy to browser-heavy. There is no getting around it. In order to create modern web apps with the features user's want, much of the code must move from the server to the browser.
  2. Mobile phones.
So, for any new programming language: it may have the most elegant syntax in the world, but if it doesn't run in a browser (or translate into something that runs in the browser) and/or doesn't run on a mobile device then i don't want it.

Only 2 languages (that I know of) run on the server (window/linux/unix), the browser and mobile devices:
  1. Java. Runs on browser via GWT. Runs on phone via Android. And, of course, runs on the server.
  2. JavaScript. Runs on browser (duh), server (node.js) and phone (assuming browser apps).

Surface Area to Functionality Ratio

The Surface Area to Functionality Ratio is my formula for evaluating APIs and computer languages - both general purpose programming languages and special purpose languages (AKA DSLs), where:

Surface Area = how many new concepts, syntax, keywords, etc. to learn. IOW, what is the learning curve.

Functionality = how many cool things can you do with the language. How general is it. How many problems does it solve.

The best way to illustrate this concept is with a few counter examples. The two all time losers based on this principal are XSLT and JavaFX.

XSLT:
  • Surface area: about the same as Haskell or C++. I read a 1300 page book in order to learn XSLT.
  • Functionality: transform one xml document into another
JavaFX:
  • Surface area: about 30% greater than Java. JavaFX is mostly a superset of Java.
  • Functionality: Build Swing UI's

Wednesday, November 10, 2010

GWT 2.1: data-binding and client-side JPA

GWT 2.1 was finally released. And as usual, it's brilliant. I am generally annoyed by technology fan-boys, but each time they do a release i am amazed by how smart these guys are. There is an amazing amount of new and useful stuff.

One of things i particularly admire is that they tend to focus on the GWT core, that is, the kind of things that would be difficult for 3rd parties or developers to do themselves. Everything that is added to GWT is extremely well thought out.

There are two productivity enhancements that I miss from the days of server-side MVC (i.e. Struts, Grails, JSF, Wicket, etc.) are:

  1. Data binding (i.e. bound controls)
  2. JPA's EntityManager. A client-side entity manager would really be useful. Much of Hibernates beauty (like lazy loading) is lost in client-heavy GWT apps. You sometime end up having a PersonEntity (for JPA) and a PersonDto (for sending to GWT client) - yuck!
GWT 2.1 addresses both of these. Data Binding is addressed with the new Editor Framework. And the client-side JPA-like thing is addressed with their new Request Factory.

Thursday, June 11, 2009

Google Wave is written in GWT

In case you haven't checked out Google Wave yet, it's a cool communications application that demonstrates what is possible in browser based applications. It's by the same guys who wrote Google Maps. And it's written in GWT.

Here is a link to Google Wave:

http://wave.google.com/

Monday, May 25, 2009

SBT: Simple Build Tool

I have been complaining about Ant and Maven for years. I don't use these tools because I like them. I use them because there haven't been many alternatives. But that is changing with a new tool called Simple Build Tool: SBT.

SBT is written in Scala (my favorite language of the week). But it can build Scala apps or Java apps. I don't have time to go into all that I like about it. But here are a few highlights:
  1. The language used for build scripts is the same as the language being built: Scala
  2. It is completely and easily extensible - using Scala. The key here is the easy part.
  3. Great docs! The project is fairly new, but already the documentation is better than that from Ant or Maven
  4. It is compatible with Maven repositories and POM files
  5. It is compatible with Ivy
  6. SBT eliminates most of the unnecessary boilerplate and noise code required with Ant and Maven
  7. The project owner, Mark Harrah, is very talented and committed to this project
  8. Support is excellent. Mark personally replies to all messages on Google Groups
  9. Bugs and feature requests are addressed quickly
  10. It's fast. Building my project in SBT is much faster then Maven - I'm not sure why, but it is.
For more info:

Project Home: http://code.google.com/p/simple-build-tool/
Google Groups: http://groups.google.com/group/simple-build-tool