Skip to main content

Domain Specific Language for Cloud Computing

Posted by richunger on September 25, 2008 at 8:09 PM PDT

Domain Specific Language for Cloud Computing

When Java programmers first learn about Apex, often their first reaction is, "why build another language?" At first glance, it appears to be a blatant attempt at lock-in. Apex is (dare we say it?) proprietary.

The honest truth is that Apex was developed for purely technical reasons. Salesforce.com could have implemented a Java layer to be its platform, or (*shudder*) as an XML schema. (For the record, that was never even seriously contemplated). Certainly both approaches would have resulted in being perceived as more "open". But, lots of things that Apex takes care of for you at a language level would have to be done in libraries, and with a lot less type checking.

Instead, we went the route that required the least work on the part of our customers to get their work done. We chose to make a DSL.


Apex is a completely different kind of animal.

So, what's the domain? Well, it turns out that, on a cloud platform, you can make all kinds of assumptions that general purpose programming languages can't.

There is only one database in the world.

Database operations don't have to establish a connection (much less manage a connection pool). Also, the object-relational mapping is built into the language. It's even statically typed. Let's say you want the first and last names of all your contacts. In Java, there are many ways to set this up, depending on whether you're using JPA, straight JDBC, entity beans, etc. In general, you must to at least these four things:

  1. Write an entity class, and annotate it or map it to a DB table in an xml file
  2. Configure the DB and connection pool
  3. acquire a connection in the client code
  4. Perform the query

In Apex, you'd do just do #4:

Contact[] mycontacts = [select firstname, lastname from Contact];
for (Contact c : mycontacts) {
    System.debug(c.firstname + ' ' + c.lastname);
}

That's it. You could even shorten this by putting the query right into the for loop. The language knows how to connect to the DB. There's no configuration involved. I'm not hiding any XML files. Contact is a standard data type. If you wanted a custom data type, you'd configure that through the Salesforce.com UI (no coding). Adding the new type to the DB automatically configures the O-R mapping. Furthermore, if you tried:

Account[] myaccounts = [select firstname, lastname from Contact];

...it wouldn't even compile. Static typing right on down to the query. Try that by passing strings into Jdbc!

There is only one way to expose a web service

Java can scope methods to be either public, protected, default, or private. Apex has one additional method scope, called webservice:

global class Dictionary {
  webservice String getDefinition(String word) {
    return "42"; // the meaning of everything
  }
}

Saving this class, and doing nothing else, causes there to be a SOAP service deployed on salesforce.com. We also have a javascript library that makes invoking this webservice as easy as making a function call. Yes, it's really that simple. This just blew me away the first time I saw it. It can be this simple because, in this domain, there's conventions for how and where services are deployed, and how clients are authenticated.

Triggers are functions, not objects

The most common use case for a programming language in our platform is to write database triggers. Triggers are functions, and modeling them as objects just to shoehorn an OO paradigm into this domain is counterproductive. An example of an Apex trigger is:

trigger Foo on Contact(before insert, before update) {
  for (Contact c : Trigger.new) {
    c.bestFriend = 'Rich Unger';
  }
}

In Java, this would have to be something like:
class Foo implements Trigger<Contact> {
  public Set getOperations() {
    return EnumSet.of(DbOperation.beforeInsert, DbOperation.beforeUpdate);
  }

  public void run(List<Contact> triggerOld, List<Contact> triggerNew) {
    for (Contact c : triggerNew) {
      c.setBestFriend("Rich Unger");
    }
  }
}

I repeat, this is the most common use case right now. So, triggers are a high-level concept in Apex, on par with classes. That's the beauty of domain specific languages. You take the most important concepts in the domain, and you give them keywords and top-level constructs.

Circling back to openness

Okay, So having a domain specific language is useful. It makes the user more productive. It's still proprietary, right?

Well, yes. If you decide to use the Force.com platform and Apex, you're making a tradeoff, gaining speed and convenience and losing the ability to port your application to a self-hosted or competing cloud platform easily. However, this is because you're not writing most of the application yourself, anyway. You're really just customizing and adding to Salesforce.com's existing CRM app. It's not a tradeoff that will appeal to everybody, but for an IT department writing custom intranet apps, or a company that needs CRM and has requirements beyond the vanilla install, it seems like a pretty tempting prospect. After all, the truth is that any custom app developement is an investment in your vendor.

You can limit your exposure to lock-in in two ways. You can use only open source software and self host everything. That way, if you change vendors, you just need a new vendor who's familiar with your chosen platform and can learn your code. There will be some cost in bringing that new vendor up to speed, which you attempt to minimize by using as much open, standardized technology as possible.

The other way is just to do as little coding as possible in the first place. So long as you have easy access to your data, you can always reimplement.

Related Topics >>

Comments

I've never really understood the "No Software" logo. I always thought it should be "No Hardware" :)

Well, I think it's important indirectly to the customers in that Apex is not as proprietary as it may seem, or at least not more than let's say Groovy. It seems to fit nicely into Jim Gosling's vision of a family of languages that run on the JVM and can talk to each other. On a higher level it seems the life cycle includes specifying requirements, defining metadata, and writing glue code, instead of writing full fledged custom applications. I'd argue though that metadata equals code and the "No Software" logo is just a marketing gimmick.

Well, Thomas, it does, but behind the scenes. I'm not sure why that's relevant to our customers. Perhaps what you're really asking is, why can't I run Apex against a JVM on my own machine? Well, that's because it's a domain specific language, and that domain is the specific set of servers that make up SFDC's cloud. One would have to replicate a lot of our backend technology for the language to have anything to bind to. Now, there are a couple of valid reasons to want to do that. One is to compete with SFDC. Well, that's fine, but SFDC certainly isn't obligated to assist in that. The other is to provide a testbed for application development. Google AppEngine has gone this route in providing a download of the google-app-engine-django environment. Our runtime is not so encapsulated, so we've opted to go the route of providing sandbox server instances for our customers to develop against.

Good arguments, but does Apex bytecode run on the JVM, and if not, why not? Thanks, Thomas

Very interesting post. I agree with the other commenter, it is depressing how the Java world is so in love with itself that technical and engineering aspects (state of the arts) are ignored completely. I find it harder and harder to be passionate about my daytime work, where more and more has to happen in myriad of API's and type-unsafe embedded DSL's rather than in the core language itself.

Good work Rich. I myself would like to work with OSS technologies, but sometimes, innovation has to come from other quarters to kick start something up in the OSS world too. I am not a whole lot satisfied with how the Java platform is embracing new paradigms, love the platform, but sometimes I wish it would move faster. Good work nonetheless.

For those interested, there's a new article in our developer wiki with more technical details on the language: http://wiki.apexdevnet.com/index.php/An_Introduction_to_Apex

Great post Rich, and thanks for pointing to my article on Apex :-) You hit on some key points: creating a web service is a matter of adding a few keywords (web service stack is all included), and creating an email service (whether to respond to incoming, or send outgoing) is just as easy. Likewise, interacting with the database is straightforward as you illustrate, as Apex supports the database concepts (persisted objects, queries) natively - you don't need a separate object/relational mapping layer tacked on.