A framework for cross platform DSL development
One of the
challenges I have experienced when giving talks or blogging about domain
specific languages is that developers are a little reluctant to writing code in
languages they are unfamiliar with. This holds true even if the DSL in question
is an external DSL based on commonly available languages such as Boo, Ruby,
Groovy or Scala.
Since I
also develop using both .NET and Java, another common challenge is that these
languages aren’t generally available on all platforms. This is a concern
because you can easily lock your self to a platform based on how you choose to
implement your DSLs. After having many discussions around this topic with
luminaries in both the Java and .NET communities, I have concluded that unless
we can address the challenges with making our DSLs true cross platform tools,
we are introducing more complexity than we’re doing good.
One of the
reasons I’ve been a bit quite for the last few weeks is that I’ve started a new
project which will be available under the Apache 2.0 license to address these
issues and I’m very glad to introduce the Adaptive Platform Runtime for Interoperable
DSLs – April!
To enable
true interoperability and at the same time make it easy to understand for all
developers April is based on familiar XML concepts. Below is an example of one
of the business rule example from my recent talks on external DSLs expressed
with April.
<?xml version="1.0" encoding="utf-8" ?>
<script>
<statement>
<when>
<expression>
<lhs>
<reference>
<to>
<instance>
<of_type>
<xmlns>http://andersnoras.com/customtypes/customer</xmlns>
</of_type>
</instance>
<named>customer</named>
<reference>
<to>
<property>
<of_type>
<xmlns>http://andersnoras.com/primitivetypes/number</xmlns>
</of_type>
</property>
<named>age</named>
</to>
</reference>
</to>
</reference>
</lhs>
<op><</op>
<rhs>
<constant>
<value>
<of_type>
<xmlns>http://andersnoras.com/primitivetypes/number</xmlns>
</of_type>
<with_value>25</with_value>
</value>
</constant>
</rhs>
</expression>
</when>
<then>
<statement>
<increase>
<reference>
<to>
<instance>
<of_type>
<xmlns>http://andersnoras.com/customtypes/policy</xmlns>
</of_type>
</instance>
<named>policy</named>
<reference>
<to>
<property>
<of_type>
<xmlns>http://andersnoras.com/primitivetypes/number</xmlns>
</of_type>
</property>
<named>premium</named>
</to>
</reference>
</to>
</reference>
<by>
<statement>
<eval>
<expression>
<lhs>
<reference>
<to>
<instance>
<of_type>
<xmlns>http://andersnoras.com/customtypes/policy</xmlns>
</of_type>
</instance>
<named>policy</named>
<reference>
<to>
<property>
<of_type>
<xmlns>http://andersnoras.com/primitivetypes/number</xmlns>
</of_type>
</property>
<named>premium</named>
</to>
</reference>
</to>
</reference>
</lhs>
<op>%</op>
<rhs>
<constant>
<value>
<of_type>
<xmlns>http://andersnoras.com/primitivetypes/number</xmlns>
</of_type>
<with_value>25</with_value>
</value>
</constant>
</rhs>
</expression>
</eval>
</statement>
</by>
</increase>
</statement>
</then>
</statement>
</script>
One key
thing to notice is that April uses its own XSD based type system. This allows
us to achieve platform portability and interoperability by abstracting away the
individual languages own type systems. To allow customized DSLs, April also
lets you redefine and extend the language using common XML representations.
This is how the “When” keyword has been introduced into the language used
above:
<keyword>
<name>when</name>
<is_alias_for>
<keyword>
<name>
<xmlns>urn:apl/core/language/keywords/conditional/if</xmlns>
</name>
</keyword>
</is_alias_for>
<semantics>
<ast>
<keyword>
<name>when</name>
<expression>
<consisting_of>
<parts>
<part>
<order>0</order>
<expression>
<allow_any>true</allow_any>
</expression>
</part>
<part>
<order>1</order>
<operators>
<operator>
<name>
<xmlns>urn:apl/core/language/operator/equals</xmlns>
</name>
</operator>
<operator>
<name>
<xmlns>urn:apl/core/language/operator/greater_than</xmlns>
</name>
</operator>
<operator>
<name>
<xmlns>urn:apl/core/language/operator/less_than</xmlns>
</name>
</operator>
</operators>
</part>
<part>
<order>2</order>
<expression>
<allow_any>true</allow_any>
</expression>
</part>
</parts>
</consisting_of>
</expression>
</keyword>
<keyword>
<name>then</name>
<!-- Eluded for brevety -->
</keyword>
</ast>
</semantics>
</keyword>
Since
everything is XML based you can use your experiences from writing everything
form web.config files to Spring configurations to extend, customize and develop
using April.
April’s
core audience is the domain experts who’ll use the DSLs you develop to
customize the business rules of any April enabled application. To reduce the probability
of bugs occurring within these DSLs, you can easily turn of language features
in the DSL context configuration.
<dsl_context>
<language_features>
<keyword>
<name>new</name>
<enabled>false</enabled>
</keyword>
<keyword>
<name>print</name>
<enabled>true</enabled>
</keyword>
<keyword>
<name>for</name>
<enabled>false</enabled>
</keyword>
</language_features>
</dsl_context>
Because of
its simplicity and the use of common XML knowledge, my vision is that April
will be the killer app that will enable developers to DSL enabling their
applications today.
The source
code will be made available at The Codehaus later today. I encourage everyone
interested in DSLs to start playing around with it, provide feedback or join
the project. Let the DSL revolution begin!