More Related Content Similar to Type-safe DSLs (20) More from Werner Keil (20) Type-safe DSLs2. Our Goal
AVOIDING ARITHMETIC OR
TYPE ERRORS IN A DSL
2 © 2007-2012 Creative Arts & Technologies
3. Overview
• Introduction
• What is a DSL?
• Internal and External DSLS
• Type-Safety
• Units and Healthcare
• Unit-API, UOMo
• UCUM, HL7, Groovy used by Healthcare
• Other Languages
• Jython/WLST
• Xtext/Xbase/Xtend
• Scala, Fantom, F#
• Demo
• Q&A
3 © 2007-2012 Creative Arts & Technologies
4. Who am I?
Werner Keil
• Consultant – Coach
• Creative Cosmopolitan
• Open Source Evangelist
• Software Architect
• Java Godfather
• …
Twitter @wernerkeil
4 © 2007-2012 Creative Arts & Technologies
5. What is a DSL?
• A DSL is a computer language
(specification, modeling, programming) tailored to
a particular domain. But, what is a domain?
• DSL examples: SQL, CSS, Sawzall (Google)
• Gains in expressiveness and ease of use (the
future could be end-user programming)
• Gains in productivity
• Reduced maintenance costs
5 © 2007-2012 Creative Arts & Technologies
6. What is a Domain?
Real-Time Business
Systems Systems
Requirements
Specification
Aircraft Patient Insurance
control Management Management Implementation
systems Systems Systems
Deployment
6 © 2007-2012 Creative Arts & Technologies
7. Internal Domain Specific Languages
• These are languages built using the syntactic
elements of the underlying language
• In the case of Java, building a DSL using Java
classes and methods
• With other JVM-based languages, that’s usually
similar, Java code generated in many cases
7 © 2007-2012 Creative Arts & Technologies
8. External Domain Specific Languages
• External DSLs
• Written in a different language than the main (host) language of the
application
• Transformed into it using some form of compiler or interpreter
• May include
• XML configuration files
• Plain text configuration files
• Full-blown languages
8 © 2007-2012 Creative Arts & Technologies
9. Type-Safety
• Java does not have strongly typed primitive types
(like e.g. Ada language).
• For performance reasons most developer prefer
primitive types over objects in their interface.
• Primitives type arguments often lead to name
clashes (methods with the same signature)
9 © 2007-2012 Creative Arts & Technologies
10. What do these disasters have in common?
• Patriot Missile
The cause was an inaccurate calculation of the
time since boot due to a computer arithmetic error.
• Ariane 5 Explosion
The floating point number which a value was
converted from had a value greater than what
would be represented by a 16 bit signed integer.
10 © 2007-2012 Creative Arts & Technologies
11. What do these disasters have in common?
• Gimli Glider (near disaster)
Fuel loading was miscalculated through misunderstanding of the
recently adopted Metric System, replacing the Imperial System
• Mars Orbiter
Preliminary findings indicate that one team used English units (e.g. inches,
feet and pounds) while the other used metric units for a key spacecraft
operation.
• NASA lost a $125 million Mars orbiter because a Lockheed Martin engineering team used
English units of measurement while the agency's team used the more conventional metric
system for a key spacecraft operation
• This also underlines the added risk when 3 rd party contractors are involved or projects are
developed Offshore
11 © 2007-2012 Creative Arts & Technologies
12. Unit Tests wouldn‘t find these…
Despite their name
• All previous example illustrate three categories of
errors difficult to find through Unit Testing:
• Interface Errors (e.g. millisecond/second, radian/degree, meters/feet).
• Arithmetic Errors (e.g. overflow).
• Conversion Errors.
17 © 2007-2012 Creative Arts & Technologies
13. SQL Example with Errors
StringBuilder sql = new StringBuilder();
sql.append("SELECT o.sum,(SELECT first_name,last_name");
sql.append(" FROM person p");
sql.append(" WHERE o.person_id=p.id) AS
client");
sql.append(" FROM order o");
sql.append("WHERE o.id = "+orderId);
sql.append(" AND o.status_code IN (?,?)");
PreparedStatement stmt =
conn.prepareStatement(sql.toString());
stmt.setString(1, "PAID");
//...
19 © 2007-2012 Creative Arts & Technologies
14. Typesafe SQL Example
Person p = new Person();
List<Tuple<String, Integer, Date>> rows =
new QueryBuilder(datasource)
.from(p)
.where(gt(p.height, 170))
.select(p.name, p.height, p.birthday)
.list();
for (Tuple<String, Integer, Date> row : rows) {
String name = row.v1;
Integer height = row.v2;
Date birthday = row.v3;
System.out.println(
name + " " + height + " " + birthday);
}
20 © 2007-2012 Creative Arts & Technologies
15. Unit-API | Operations
Results with
Same Dimension Different Dimension
Binary Operations Binary Operations
add(double) or (long) root(int)
multiply(double) or (long) power(int)
divide(double) or (long) multiply(Unit)
compound(Unit) divide(Unit)
Unary Operations
inverse()
16. UOMo UCUM
Unified Code for Units of Measure
The Unified Code for Units of Measure is inspired by
and heavily based on
• ISO 2955-1983
• ANSI X3.50-1986
• HL7's extensions called ISO+
25 © 2007-2012 Creative Arts & Technologies
17. HL7 DSL
def mySegment = ... // assignment to another
NK1 segment instance
def group = message.PATIENT_RESULT(0).PATIENT
group.NK1(0) = 'abc' // syntax error!
msg1.NK1(0) = mySegment // syntax error!
msg1.NK1(0).from(mySegment) // works!
def nk1 = message.PATIENT_RESULT(0).PATIENT.NK1(0)
def otherNk1 = message.PATIENT_RESULT(0).PATIENT.NK1(0)
nk1[4] = otherNk1[4] // copy address
nk1[4][4] = otherNk1[4][4] // copy state or province
only
nk1[4][4].from(otherNk1[4][4])// equivalent
nk1[4][4] = 'NY' // set state or province directly
26 © 2007-2012 Creative Arts & Technologies
19. Jython
/** * Java calculator class that contains two simple
methods */
public class Calculator {
public Calculator(){ }
public double calculateTip(double cost, double
tipPercentage) {
return cost * tipPercentage;
}
public double calculateTax(double cost, double
taxPercentage) {
return cost * taxPercentage;
}
}
28 © 2007-2012 Creative Arts & Technologies
20. Jython (2)
import Calculator
from java.lang import Math
class JythonCalc(Calculator):
def __init__(self):
pass
def calculateTotal(self, cost, tip, tax):
return cost + self.calculateTip(tip) + self.calculateTax(tax)
if __name__ == "__main__":
calc = JythonCalc()
cost = 23.75
tip = .15
tax = .07
print "Starting Cost: ", cost
print "Tip Percentage: ", tip
print "Tax Percentage: ", tax
print Math.round(calc.calculateTotal(cost, tip, tax))
29 © 2007-2012 Creative Arts & Technologies
21. Jython (3)
Result
Starting Cost: 23.75
Tip Percentage: 0.15
Tax Percentage: 0.07
29
30 © 2007-2012 Creative Arts & Technologies
23. Scala, Fantom, F#
• Scala
• Functional programming language. Type-safe, as the company driving it was
called.
• Very popular for DSLs
• Fantom
• Functional programming language
• Units of Measurement support built in.
• Runs on both JVM and CLR
• F#
• Functional programming language
• Units of Measurement support built in.
33 © 2007-2012 Creative Arts & Technologies
25. Links
Eclipse – Project UOMo
http://www.eclipse.org/uomo/
Units of Measurement API
http://www.unitsofmeasurement.org
UCUM
http://www.unitsofmeasure.org
26. Links (2)
OpenHealth Project
http://www.openhealth.org
Groovy DSL Example
http://groovy.dzone.com/news/domain-
specific-language-unit-
Jython
http://www.jython.org
27. Links (3)
Xtext
http://www.eclipse.org/xtext
Scala DSLs
http://www.scala-lang.org/node/1403
Fantom
http://fantom.org/
29. Contact
werner@catmedia.us
or
uomo@catmedia.us
Twitter: @wernerkeil
Hashtag #EclipseUOMo