Domain Specific Languages in CoffeeScript![]() One of the great features of the CoffeeScript language is the great expressiveness that allows easy creation of Domain Specific Languages (DSLs). In this post I'll explore this aspect of CoffeeScript more with a reflection on how DSLs are done in Ruby. Why bother with DSLs?If you are a programmer then you have worked with a lot of DSLs, some of these are:
DSLs should not be unknown for you, at least not "external DSLs" like those listed above. Internal DSLs are another form of DSLs where you use a host language to emulate DSLs. These internal DSLs are only found in languages that are very expressive and that don't have very strict rules. Some host languages include Lisp and Ruby. In Martin Fowler's FAQ on DSLs he states the most common benefit of using DSLs:
So why should you bother with DSLs? Because they can make you more productive :-) Examples of DSLs in the Ruby languageRuby programmers are well known for their usage of DSLs. Let's take a look at how different DSLs look like in the Ruby language. Ruby On Rails has a lot of DSLs spread around and one of these is in ActiveRecord. The ActiveRecord DSL lets you easily express relationships between model classes: class Post < ActiveRecord::Base
has_many :comments
...
end
class Comment < ActiveRecord::Base
belongs_to :post
...
end
Sinatra is another Ruby web-framework that includes a DSL for writing request handlers, an example: get '/', :provides => 'html' do
haml :index
end
Rake is Ruby's version of make. It includes a DSL which looks like this: task :i_am_a_task do
puts "Just a silly task"
end
jQuery: JavaScript's most popular DSLWhile JavaScript does not promote creation of DSLs they are still possible. The most popular JavaScript library jQuery can be seen as an internal DSL for selection and manipulation of DOM nodes: $('.mydiv').addClass('flash').draggable().css('color', 'blue')
So DSLs are possible in JavaScript, but creating them isn't that easy due to JavaScript's strict syntax. Luckily we have CoffeeScript that compiles to JavaScript :-) zappa: Example of a working DSL in CoffeeScriptzappa is a CoffeeScript DSL for writing node.js web-applications. Here is an example of how a zappa application looks like: get '/:foo': ->
@foo += '!'
render 'index'
view index: ->
h1 'You said:'
p @foo
layout ->
html ->
head -> title "You said: #{@foo}"
body -> @content
As you see above CoffeeScript allows a lot and with this it's possible to build very powerful DSLs. Let's now take a look at different stuff we can do in CoffeeScript. ActiveRecord's DSL in CoffeeScriptIf we need to do an ORM for CoffeeScript we could create one that looks similar to Rails ActiveRecord: class Post extends ActiveRecord
has_many: 'comments'
class Comment extends ActiveRecord
belongs_to: 'post'
Sinatra DSL in CoffeeScriptIf we need to handle requests we could emulate Sinatra's DSL: get '/helloWorld/:name', (name) ->
"Hello #{ name }"
Rake DSL in CoffeeScriptIf we are creating a make system we could emulate rake's DSL: task "kill_hal", ->
alert "I am sorry Dave, I'm afraid I can't do that"
DSL for doing Ajax requestsOn the client side we could have a DSL for doing Ajax requests, it could look similar to this: ajaxRequest '/Projects/getProject'
data:
project_id: 1
callback: (response) ->
alert response
Just for the record, the above code will look like this when compiled to JavaScript: ajaxRequest('/Projects/getProject', {
data: {
project_id: 1
},
callback: function(response) {
return alert(response);
}
});
ConclusionAs you have seen in this post CoffeeScript makes it trivial to create DSLs and you can easily emulate Ruby's most popular DSLs. I can only imagine what people are going to do with all this expressive power. Further readingArticles:
I also recommend reading Martin Fowler's book on the subject:
Code
·
Code improvement
·
Code rewrite
·
Design
·
JavaScript
•
12. Mar 2011
|
|