ActionScript, RIA and DSL’s part 1
Introduction
For some time now, I have been wanting to take a closer look at Domain Specific Languages (DSL) and their whereabout in Rich Internet Applications. Actually I got interested in the subject at the JAOO conference earlier this year.
Here I got the chance to participate in a full days tutorial in DSL’s held by Martin Fowler and Neal Ford from Thought Works. The tutorial took a deep dive into the general definition of a DSL and looked at the various ways to build and provide DSL’s domain experts. Later at the JAOO I had the great pleasure of being at James Wards session on RIA with Flex and AIR. In this session
James demoed a use case related to the insurance domain. The use case evolved around how to file a car crash with your insurance company. The application showed how an applicant would go about describing the car crash by placing his own car and other implicated cars in an intersection, in a graphical environment.
This depicting of a business case combined with my newly awakening in the world of DSL’s got me thinking about the way many of us use RIA as a way to communicate a limited business domain trough a rich interface.
As I realize this subject might take some time for me to get my head around, therefor I have decided to make it a series. In this first part I’ll try to get around what (I think) a DSL is, and how you could build a internal DSL in ActionScript.
What’s an DSL
The general definition is that an DSL is a language which is specific to a certain problem domain. As opposed to General Purpose Language, a DSL or “special purpose language” as some might call them, is constraint to provide meaning to the business domain and nothing more. It is by default defined to be a Computer Programming Language with limited expressiveness. The wikipedia also includes “visual diagramming language” as part of the definition. So in broad terms a way to communicate a domain to/with a computer.
To put this into a little perspective (though I just stated that an DSL IS in some way related to a Computer) I like to think of a DSL, or at least the way a language is limited to a domain, as the way to order a coffee at Starbucks.
If you are not familiar with the Starbucks jargon, you should check out this wiki explaining how to order by using the Starbucks “DLS”. For instance the order: I’ll have a ‘For Here’, Grande, Non-Fat, No Water, 180 Degrees, Tazo® Chai Tea Latte is an example of an order at Starbucks. Further; this sentence only makes sense to the Starbucks business domain, it has a limited expressiveness and the syntax is human readable, though simplified.
This is of cause a simplification of the DSL explanation (and again, the Starbucks jargon, is just a jargon or “slang” vocabulary), but it gives a relational mapping from our world to the way we need to think of DSL in terms of a domain specific computer language.
Besides the above points and some more specific rules of thumb (like a DSL never should have touring completeness etc.) it is hard to set exact boundaries for a DSL; domains are different and the need for expressiveness or the ability to limit scope varies.
Why even bother
Before we walk further down the DSL road I think it is in good order to motivate why one would even go about spending time and effort on this subject. I see a close connection between Rich Internet Applications and the way we can use DSL as part of solving a problem. We deal with domain users and domain experts on a daily basis, as we both have to capture what the business domain is all about, and create the interface that make the user collaborate with this domain. A lot of the applications we build, is created with an expressive and rich interface. - Interfaces which, in my point of view, can be exactly that visual abstraction on top of a problem domain, the wikipedia calls: “visual diagramming language”. I’ll in the following try to showcase what I think a DSL is, and how it is implemented internally and externally (in code and/or graphically).
In the attempt to get my own (and hopefully your) head around how some thoughts about DLS’s could benefit the way we think about creating (Rich Internet) Applications, we need a little “case” project” This “case” will be the context to which I can refer troughout this post (and in later parts). I’ll try to outline a VERY simplified business domain (so please don’t ask to many clarifying quesitons about this given scenario, I promise I’ll return in a later part with a more “real world” piece of meet).
Our point of entrance case
So lets say we are building an application which is to be used by a big chain of bakeries to control the pipeline of bread being baked every day. The bakers will be using the application to look up recipes, provided trough a graphical step by step user interface, making it easy for even novice bakers to follow along and bake bread.
Our domain clearly evolves around the bakery-domain, where we need to focus especially on the Recipe Model as that is what our application will do a lot of work with. When we start our work with the domain expert; the experienced chief baker. From him we learn that the bakery chain already have a lot of recipes laying around.
All these should be “programmed/stored” in to our system (for instance into a database) at start up, so that the application from day one will be able to show all the recipes used today. Besides that; every day, new and exotic recipes are discovered world wide, and the chief baker, wants an easy way to provide new recipes to the baker system. These new recipes could be found in a news paper or book, send to the chief on a mail, or sometimes the chief baker even receives recipes on a bar napkins (from a fellow bakers stroked by moments of bread-creativity when drinking heavily).
So what options do we have for providing a means for the chief baker to get all the recipes into the system. One option would be to create a form, maybe even just one big text field for the chief to write a recipe into, exactly as it would read in the book, paper or mail. But this solution isn’t good (for various reasons) as we need to remember; the application is suppose to guide the bakers trough the recipe thus having to break the recipe up in to coherent chunks. This will be impossible to say the least, to do with one big string of text. So another option would be to create multiple text fields each representing a step in the recipe, for the chief to fill in. This way the chief as the domain expert would have the ability to chunk the recipe up into coherent steps which would make sense when baking the bread.
Though this solution seams better at first, I think there is a lot to be cautious about in an approach like this. First of all; chunking the recipe up and gathering it up by a series of fields do not give us much more about the recipe besides the chunks them selves. If we want to use the data in the recipes to anything besides just showing the text representing a step, we would have a hard time doing so. In an example, say we wanted to show the process of a baking step in a recipe, by graphically counting down the minutes left the dough had to be in the oven. - how and here would get these informations if they were hidden in some chunk of text saying “now bake the dough for 25 minutes”. We might also want to search for recipes containing certain amounts of certain ingredients; a thing which also would be hard to do, with recipes just saved as chunks of strings.
“So, lets make an actual form, with an ingredient list, an ingredient-mixing step, a rising step, a baking step etc, so that we know more about the actual data being submitted”, I see the point in this approach, but I still think we might come in short by this approach. Recipes can be complex, and some might contain multiple baking steps, no rising step, etc. thus making it hard to limit the chief to a “one form fits all” approach. We could continue making the form more sophisticated and so on, but my point is of cause, that we should/could also consider thinking in terms of a Domain Specific Language; a language limited to the baker and recipe domain, with a limited expressiveness and with concepts familiar to the chief baker.
I’ll leave our bakery for now, the above case was primarily to get us into a solution-thinking-state-of-mind which we can leverage when going trough the following. By not giving my idea (not yet at least) of a solution to how we should solve the bakery application, I hope your own creativity will have more room for thinking of ways to create a fitting solution. - hopefully a solution which will be inspired by the DSL-road trip we are about to take.
I’ll now return to a more concrete talk about what a DSL is, the different types and how they can be implemented.
Different types of DSL’s
Generally DSL’s are defined in two main categories: internal DSL’s and external DSL’s. When talking about the types of DSL’s it is important to understand who the target audience is. Internal DSL’s are in my opinion more targeted technology persons (what an exact and concise definition
). What I mean by this, as you will read in a moment, is that internal DSL’s always will be bound to some sort of development environment element(s) (this being a hosting general purpose language, an IDE or editor, a general purpose language compiler and limited syntax). Therefor I think internal DSL’s are in broad mostly relevant to people knowing their way around a computer, but not necessarily a developer . In comparison to internal, the external DSL is not in a host language, thus being without the constraints related to an internal DSL. An external DSL, is in my opinion very interesting in regard to end-users and non technical people with expertise in a domain. The external DSL category is also where the “visual diagramming languages” fits in.
Internal DSL
In short an internal DSL is a language written in a “host” language. By host you should understand the General Purpose Language being used to write an “abstraction” or DSL in. As an example it would mean an DSL written in ActionScript to provide a higher programming abstraction trough a specific set of domain “objects” (objects as in domain related terms and model interpretations) and limited syntax. The syntax limiting is always limited to the ways to go about in the host language. As you actually is writing ActionScript you are not able to do any new and fancy formatting, as it is to be interpreted by the same compiler as normal ActionScript. Though, often it is possible to use little tweaks to hide the underlying host language, or noise, more or less. As an example the following snippet our Starbucks order from above, written in an Startbucks DSL, written i ActionScript:
var latte:Coffee = new Coffee() .size = CoffeeSize.GRANDE .where = Consumption.FOR_HERE .fat = FatContent.NON_FAT .water = Water.NO_WATER .temperature = 180 .type = CoffeeType.TAZO_CHAI_TEA_LATTE; |
What you should notice is the use of multiple lines, all of them starting with a “.”. This way of chain the syntax together, and not breaking any compiler/language rules while still providing a better readability is called Method Chaining”. Method Chaining can be part of the way of achieving what is know as a Fluent Interface”. Fluent Interfaces is the concept of treating lines of code as sentences, like we just did with the method chaining above. I cant help thinking about how frameworks and API’s in general can benefit from the thoughts related to DSL’s and fluent interfaces. A great example of DSL (if you would argue that testing is a domain) and fluent interfaces is Test Driven Development with JUnit, Hamcrest and JMock, where your are able to create logical, readable constructs when writing your tests, by using method chaining and subsequent calls. See the example below:
public class MyTestCase { ... public void testSomething() { ... context.checking(new Expectations() {{ oneOf (logger).error(with(aStringStartingWith("FATAL"))); }}); ... } } |
In the above we see how we can construct a human-readable string (at least a programmer-readable string) by using the syntax and method naming around the JMock and testing domain.
In regard to the Fluent Interface and Method Chaining there is a little advantage in ActionScript in our ability to write properties as getter/setter methods. This can help us remove a little more noise from our DSL. In practical terms we are able to change the “( )” with a ” = ” which is a more known operator for non developers; assigning a value on the right side to something on the left side. - like we did it in our Coffee example above. The trick in using method chaining and getter/setter, as you properly have figured out, is to let each setter return the containing object itself:
package { public class Coffee { public function Coffee) { //... } public function set size(value:CoffeeSize):Coffee { //... return this; } public function set where(value:Cosumption):Coffee { //... return this } } } |
The Bakery internal DSL
We could argue that we should create an internal recipe DSL to our chief baker. This would of cause not be the best thing to do, as our dear chief baker might not be very familiar with computers when it comes to tasks outside the “normal use”-boundaries. But on the other side, that would just mean that we would have to be even more focused on providing a domain language to the chief that “feels at home” and hides away constraints and noise in our host language.
To remove this “host language noise” we will of cause use what ever tweak we can in our language, to make it more fluent.
The creation of a recipe, in our Bakery DSL could look like something like this:
var r:Recipe = new Recipe ( add(25).grams.of.flour, add(2).oz.of.water, mix(), add(2).kilos.of.sugar, mix(), rise(2).hours, bake(30).minutes.at(200).celcius ); |
As you can see we try to make it very sentence like, by constructing expressions that look as close as possible to the way we actually describe a recipe in the real world; “Add 25 grams of flour”. The way I have achieved the above syntax in a language like ActionScript is by using the Proxy class in AS3, a factory, and a set of package methods.
I’ll in the following show how it is implemeted.
Here is my Bakery App project:

Recipe Class
The Recipe class, which constructor takes an unspecified list of ingredients and actions in the order they should be executed. This is done by using the “…” syntax in AS3. This way the handling of the various elements and steps constituting the recipe can be handled generic. As mentioned above one problem with static forms could be, that some recipes have multiple baking steps, and others none. By pushing a list of n’ in the constructor we are not locked to any order, or any special sequence. The implementation of what to do with the elements when they are received in the constructor is not of interest here, as much as HOW we go about and create the elements we want in a recipe.
package model { public class Recipe { public function Recipe(...args) { //... } } } |
The Ingredient
Inside the constructor call of the recipe, we make use of a set of statements which starts with a “key word” related to an action in our domain. The first line, which will look closer at adds a new ingredient to the recipe:
add(25).grams.of.flour |
What is actually created in this sentence is new instance of an ingredient object with 25 as the amount, grams as the measuring unit and flour as the name of the ingredient. The implementation of the ingredient class is shown below here. It is in it self not very interesting, but the interesting part is how we remove the noise of object creation from the language we want to provide, and make the syntax intuitive:
package model { public class Ingredient { private var _amount:Number; private var _measureUnit:String; private var _name:String; //... public function Ingredient(amount:Number,measureUnit:String,name:String) { _amount = amount; _measureUnit = measureUnit; _name = name; //... } //... } } |
Package Method
So now we know how we should end up; with an ingredient object, with a measuring unit, an amount and an ingredient name. We start this process by calling “add”.
The add “key word” which is actually just a method declared in an ActionScript file in a package, can be used, everywhere as long as it is imported to the current file you are working in. It is like other methods like “navigateToURL” etc. already in the AS3 API. What I like about doing it this way, in stead of having a local add method in the containing class, is the separation. As you can see in the overview of the project, all the add, bake, rise, mix methods is in their own package.
This makes it easy to control what domain actions reside, and you don’t have to clutter the Recipe class or the class where you want to use the DSL by implementing all these methods there. So to say we delegate the responsibility of “catching the domain action” out to a separate method, instead of having this in a class. This also makes it easier to maintain if the implementation of certain method names or “domain actions” changes. And lastly, it gives a great overview, of the domain actions. - also in terms of collaboration with the domain experts, as the extraction and abstraction is very human readable.
The actual implementation of the “add” method (and most of the others for that matter) is a further delegation of control, to an appropriate factory class. Here is the implementation of the “add”:
package actions { import util.IngredientFactory; public function add(amount:Number):IngredientFactory { return new IngredientFactory(amount); } } |
The Factory
As shown above, the “add” method delegates the amount passed in, to an “IngredienFactory” class. If we continue to look at our sentence under investigation, we see that the following is a chained expression of the measuring unit, and the name of the ingredient.
add(25).grams.of.flour
If we look inside our “IngredientFactory” we see that this is implemented by extending the AS3 Proxy, thus making our “IngredientFactory” dynamic, and open for any type of property call (gram, grams, kilo, kilos, oz, pieces, piece, …)
package util { import flash.utils.Proxy; import flash.utils.flash_proxy; import model.Ingredient; dynamic public class IngredientFactory extends Proxy { private var _measureUnit:String; private var _amount:Number; private var _addingName:Boolean = false; public function IngredientFactory(amount:Number) { _amount = amount; } override flash_proxy function getProperty(name:*):* { var result:*; if(_addingName) result = new Ingredient(_amount,_measureUnit,name); else { _measureUnit = name; result = this; } return result; } public function get of():IngredientFactory { _addingName = true; return this; } } } |
As you can see I have made the “getting” of “of” the trigger, that assembles the amount, the measuring unit, and the name of the ingredient, and returns a new instance of an ingredient, with these arguments in the constructor. The is of cause based on the concordance that an “ingredient sentence” is always composed like:
<code>measuringUnit.of.ingredientName</code>
This concordance should of cause be derived from the domain (hence the domain experts). In this example I’ll not go deeper into the domain, but you could try to think about how you would create the ability to say something like “add(2).eggs” where there is no measure unit (or it is at least implicit in the sentence) and no use of the “of” keyword.
Besides the “add” method, I have in my example created methods like “mix”, “bake” and “rise”, and there could be many more. In our bakery domain they make perfect sense in the construction of a recipe. And we would now know when to tell the bakers to mix ingredients, when and how long to rise, and at what temperature the bread should be baked.
So to sum up the implementation pattern used;
- we subsequent the steps and ingredients as arguments to the constructor
- we create domain actions as package methods
- we delegate the creation of domain objects/concepts to a dynamic factory
As mentioned this is example is very staged and the point was not to show how to develop a bakery application, but to show how to abstract an API or Domain concepts inside a programming language, into a higher level DSL.
Outro on part 1
Pheew, boy was that a lot of words. I’m glad I decided to make this a series, otherwise I would never get to close up this blog post ![]()
I hope you have gotten a glimpse of what a DSL is in general, and what a DSL is in terms of an “internal DSL”. I also hope you have gotten the idea of how you could create such an internal DSL in ActionScript by using some of the great dynamic possibilities we have at hand.
In terms of internal DSL’s AS1/2 was actually even more dynamic with its implicit declarations and weak typing. These qualities (though people often do not look at them as qualities) is some of the things people value in Ruby, which is gaining momentum these days, as a language for writing internal DSL’s.
In the next part on the subject I’ll be taking closer a look at external DSL’s and how we with Rich interfaces can create visual DSL’s to use for the domain experts.
Hi Asger,
Its really great to see people from the business getting having time to get down into the more theoretical aspects of our business… and also great to see that you make it relevant with through description.
Good stuff
// Peter
Hi Peter.
Thank you for the kind words. I hope the subject will be of interest to others, and I’m looking forward to get the next part on line.
Thanks
Asger
Hello and thank you for interesting article.
I wonder how you made this compilable:
public function set size(value:CoffeeSize):Coffee
{
//…
return this;
}
Flex (3.1) compiler says:
1054: Return type of a setter definition must be unspecified or void.
Hi Dmitry.
You are absolutely right. You are not able to return a specified datatype from the setter. I did a lot of examples and tests with AS 3, and unfortunately I have posted the wrong example. - I guess this is what you get, when writing on the same post in multiple iterations.
It is possible to return a reference to the object, on which you use the setter, by declaring the return type as arbitrary ” * “.
I’m sorry for any inconvenience you might have had trying to get this to work. Look after my post later to night with the working example.
Thanks for actually reading and trying out the examples
Happy Coding
Cheers
Asger
So as promised, I reviewed the Coffee example code, and re-got-my-head-around-it, and mashed it all in to some sort of context.
So please see the working example here
http://asgerlaursen.com/2009/01/28/actionscript-ria-and-dsl-part-1-%C2%BD/
Cheers
Asger