Typ-sichere DSLs
Mit Xtext/TS, Xtend, Groovy und anderen Sprachen
Werner Keil
Eclipse DemoCamp Berlin
20. Juni 2012
ARITHMETISCHE ODER DATENTYP FEHLER BEI DSL NUTZUNG VERMEIDEN
Zielsetzung
2 © 2007-2012 Creative Arts & Technologies
Überblick
•Einleitung• Was ist eine DSL?• Interne und Externe DSLs• Type-Sicherheit
•Einheiten im Gesundheitswesen• Unit-API, UOMo
• UCUM, HL7, Groovy in der Gesundheitsbranche
•Andere Sprachen• Jython/WLST• Xtext/Xbase/Xtend• Scala, Fantom, F#
•Demo•Q&A3 © 2007-2012 Creative Arts & Technologies
Was bin Ich?
4 © 2007-2012 Creative Arts & Technologies
Werner Keil
• Consultant – Coach
• Creative Cosmopolitan
• Open Source Evangelist
• Software Architect
• Java Godfather
• UOMo Lead
• …
Twitter @wernerkeil
Was ist eine DSL?
•Eine DSL ist eine Computersprache (Spezification, Modellierung, Programmierung,…) angepasst an eine bestimmte Domäne. Doch was ist eine Domäne? (siehe nächste Seite;-)
•DSL Beispiele: SQL, CSS, Sawzall (Google)•Gewinn von Aussagekraft und Benutzerfreundlichkeit (kann u.U. Bis zur Entwicklung durch Endbenutzer führen)
•Gewinn von Produktivität•Geringerer Wartungsaufwand und -kosten
5 © 2007-2012 Creative Arts & Technologies
Was ist eine Domäne?
6 © 2007-2012 Creative Arts & Technologies
Implementation
Specification
Requirements
Deployment
Business
SystemsReal-Time
Systems
Aircraft
control
systems
Patient Management
Systems
Insurance
Management
Systems
Internal Domain Specific Languages
•Sprachen mit Hilfe syntaktischer Elemente der darunter liegenden Sprache/Umgebung
• Im Fall von Java, eine DSL verwendet Java Klassen und Methoden
•Bei anderen JVM-basierenden Sprachen ist es in der Regel ähnlich, meist wird Java Code oder Klassen generiert
7 © 2007-2012 Creative Arts & Technologies
External Domain Specific Languages•Externe DSLs
• Geschriebern in einer eigenen Sprache als der darunterliegenden (Host) Sprache der Anwendung
• Umgewandelt mit Hilfe eines Compilers, Parsers oder Interpreters
•Kann auch enthalten• XML Konfigurationsdateien• Textdateien zur Konfiguration• Eigene Sprachen (Meta-DSLs)
8 © 2007-2012 Creative Arts & Technologies
Typ-Sicherheit
•Java hat keine stark typisierten Primitiven Datentypen (wie etwa Ada).
•Zwecks Performance nutzen die meisten Entwickler Primitive Datentypen an Stelle der entsprechenden Objekt-Typen.
•Primitive Datentypen in Argumenten führen oft zu Namensverwirrung (Methoden mit ident wirkender Signatur)
9 © 2007-2012 Creative Arts & Technologies
Was haben diese Vorfälle gemeinsam?•Patriot MissileUngenaue Berechnung der Zeit, die seit dem Start verging verursachte den Absturz.
•Ariane 5 ExplosionFloating point Zahl die in einen Wert umgewandelt wurde, der den verfügbaren 16 bit signed integer überstieg.
10 © 2007-2012 Creative Arts & Technologies
• Gimli Glider (Beinahe Disaster)Treibstoffmenge falsch berechnet wegen Fehlinterpretation des gerade eingeführten Metrischen Systems in Kanada, statt des Britischen Imperial System of Units
• Mars Orbiter Vorläufige Erkenntnisse deuten darauf hin, dass ein Team Englische Einheiten (e.g. inches, feet and pounds) benutzte, während andere Teams Metrische Einheiten zur Steuerung der Raumsonde nutzten.
• 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
• A credible source disclosed, there was a manual step with an outsourced person to convert these calculations between the different teams, and NASA budget cuts caused them to fire him and have the wrong, unpatched data transmitted!!!
• This also underlines the added risk when 3rd party contractors are involved or projects are developed Offshore
Was haben diese Vorfälle gemeinsam?
11 © 2007-2012 Creative Arts & Technologies
Unit Tests helfen hier selten…
•Alle Beispiele illustrieren 3 Kategorien von Fehlern, die man mit Unit Tests nur schwer aufspüren kann:
• Schnittstellen-Fehler (z.B. millisecond/second, radian/degree, meters/feet).
• Arithmetische Fehler (z.B. overflow).
• Konvertierungsfehler.
Dem Namen zum Trotz
17 © 2007-2012 Creative Arts & Technologies
SQL Beispiel mit FehlernStringBuilder 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
Typ-sicheres SQL BeispielPerson 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
Ergebnis mit
Gleicher Dimension Anderer Dimension
Binäre Operationen Binäre Operationen
add(double) od. (long) root(int)
multiply(double) od. (long) power(int)
divide(double) od. (long) multiply(Unit)
compound(Unit) divide(Unit)
Unäre Operationen
inverse()
Unit-API | Operationen
Unified Code for Units of Measure
Unified Code for Units of Measure ist inspiriert und starkbeeinflusst von
• ISO 2955-1983
• ANSI X3.50-1986
• HL7's Erweiterungen namens ISO+
UOMo UCUM
25 © 2007-2012 Creative Arts & Technologies
HL7 DSL
26 © 2007-2012 Creative Arts & Technologies
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
DEMO
Healthcare DSL mit Groovy
Jython
28 © 2007-2012 Creative Arts & Technologies
/** * 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;
}
}
Jython (2)
29 © 2007-2012 Creative Arts & Technologies
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))
Jython (3)
30 © 2007-2012 Creative Arts & Technologies
Starting Cost: 23.75
Tip Percentage: 0.15
Tax Percentage: 0.07
29
Result
DEMO
Xtext Examples
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
DEMO
Scala und Fantom Beispiele
Eclipse – Project UOMo
http://www.eclipse.org/uomo/
Units of Measurement API
http://www.unitsofmeasurement.org
UCUM
http://www.unitsofmeasure.org
Links
OpenHealth Project
http://www.openhealth.org
Groovy DSL Example
http://groovy.dzone.com/news/domain-specific-language-unit-
Jython
http://www.jython.org
Links (2)
Xtext
http://www.eclipse.org/xtext
Scala DSLs
http://www.scala-lang.org/node/1403
Fantom
http://fantom.org/
Links (3)
Q & AFragen
Kontakt
oder
Twitter: @wernerkeil
Hashtag #EclipseUOMo