SlideShare uma empresa Scribd logo
1 de 85
Baixar para ler offline
[1]

                                         Scala




                                                 Scala


present DSLs in Scala for MSI at HSMA
   Marcus Körner (@atla_)   Johannes Wachter (@jow85)
2



  Grande
  Cinnamon Dolce
  Latte with tripple
  shot with non-fat
  milk topped with
  whipped cream
[2]
3



                                          [3]
place orders (
 new Order to buy(100 sharesOf ”IBM”)
   limitPrice 300
   allOrNone
   using premiumPricing,

 new Order to sell(200 bondsOf ”CISCO”)
   limitPrice 300
   allOrNone
   using {
     (qty, unit) => qty * unit - 500
   }
 )




Beispiel aus [DSLSINACTION]
4
Agenda


           Was sind       Warum
            DSLs          Scala?


         DSL Beispiele
                         DB4O DSL
           in Scala
[4]




Was sind DSLs?
6
DSL
Allgemeine Definition

˃ Domain Specific Language
    • Oder auch Fluent API
˃ Domain – [Domäne]
    • Problemorientiert
    • „Fachsprache“
˃ Specific – [Speziell]
    • Konkret entworfen für einen spezifischen
      Einsatzzweck
    • Abgrenzung zur General Purpose Language
7
Domäne
… oder auch Anwendungsdomäne

˃ Sammlung an Abläufen, Objekten und
  Rahmenbedingungen die Teil der Fachdomäne
  sind
˃ Brücke zwischen realen Objekten aus der Welt
  des Anwenders und Objekten eines
  Softwaresystems
˃ Domain-Driven-Design
   • Schwerpunkt ist die Fachlichkeit und Fachlogik
   • Ideales Einsatzgebiet für DSLs!
8
Ausdrucksschwäche von GPLs
Ocean ocean = new Ocean ();
Fish fish1 = new Fish ();
fish1.setSize(Size.TINY);
fish1.setColor(Color.RED);
Fish fish2 = new Fish ();
fish2.setSize(Size.MIDSIZE);
fish2.setColor(Color.BLUE);
Shark shark = new Shark ();
shark.setSize(Size.HUGE);
shark.setColor(Color.WHITE);
Jellyfish jellyfish = new Jellyfish ();
jellyfish.setSize(Size.SMALL);
Turtle turtle = new Turtle ();
turtle.setSize (Size.SMALL);
ocean.add (fish1);
ocean.add (fish2);
ocean.add (shark);
ocean.add (jellyfish);
ocean.add (turtle);
9
Ausdrucksschwäche von GPLs
Ocean ocean = new Ocean ();        Wenn man eigentlich meint…
Fish fish1 = new Fish ();
                                   ocean (
fish1.setSize(Size.TINY);

?
fish1.setColor(Color.RED);
Fish fish2 = new Fish ();
fish2.setSize(Size.MIDSIZE);
                                           fish (TINY, RED),
                                           fish (SMALL, BLUE),
                                           shark (HUGE, WHITE),


                ?
fish2.setColor(Color.BLUE);                jellyfish (SMALL),
Shark shark = new Shark ();                turtle (SMALL)
shark.setSize(Size.HUGE);                  )
shark.setColor(Color.WHITE);


     ?
Jellyfish jellyfish = new Jellyfish ();
jellyfish.setSize(Size.SMALL);
Turtle turtle = new Turtle ();
turtle.setSize (Size.SMALL);

            ?
ocean.add (fish1);
ocean.add (fish2);
ocean.add (shark);
ocean.add (jellyfish);
ocean.add (turtle);
10
Ausdrucksschwäche von GPLs
Ocean ocean = new Ocean ();        Mit Scala 2.8: Named Parameters
Fish fish1 = new Fish ();
                                   ocean (
fish1.setSize(Size.TINY);

?
fish1.setColor(Color.RED);
Fish fish2 = new Fish ();
fish2.setSize(Size.MIDSIZE);       )
                                    fish (size=TINY, color=RED),
                                    jellyfish (size=SMALL)




                ?
fish2.setColor(Color.BLUE);
Shark shark = new Shark ();
shark.setSize(Size.HUGE);
shark.setColor(Color.WHITE);


     ?
Jellyfish jellyfish = new Jellyfish ();
jellyfish.setSize(Size.SMALL);
Turtle turtle = new Turtle ();
turtle.setSize (Size.SMALL);

            ?
ocean.add (fish1);
ocean.add (fish2);
ocean.add (shark);
ocean.add (jellyfish);
ocean.add (turtle);
11



                           [5]




Klassifizierung von DSLs
12
Klassifizierung

˃ Es gibt zwei wesentliche Unterschiede bei DSLs
   • Interne DSLs
   • Externe DSLs


˃ Es gibt allerdings auch einige graphische DSLs
13
Interne DSLs

˃ Eingebettet in eine Host-Sprache
   • z. B. in Java, Groovy, Scala, Python, C# …
˃ Beeinflusst und limitiert von den Sprachmitteln
  der Host-Sprache
˃ Einige Vertreter
   • LINQ (C#), Grails (Groovy), Lift (Scala), WebDSL
     (Scala)
14
Externe DSLs

˃ Liegen meist in Form von Skripten oder
  interpretierbaren Text-Dateien vor
   • Graphviz, (X)HTML
˃ Werden entweder
   • interpretiert
   • compiliert in eine andere Sprache (Xtext)
˃ Kennen wir alle nur zu gut…
   • SQL, Ant-Skripte, Makefiles, XML Konfigurationen
15
Graphische DSLs

˃ Graphische Modellierung einer Domäne
   • UML, BPM
˃ Meist verbunden mit einem spezifischen Tool
   • Bsp. Microsoft Oslo, JetBrains MPS, Intentional
     Domain Workbench
˃ Gut geeignet zum Dokumentieren
˃ Schlecht geeignet zum eigentlichen Entwickeln!
16



                  [6]




Stand der Dinge
17
Naive API
… ohne wirkliches Design

Cream c = new WhippedCream ();
Coffee coffee = new              [7]
Coffee(”CinnamonDolce”,
 TYPE_LATTE);
coffee.sized(4);
coffee.setDecaf
(”decaf none”);
coffee.addCream(c);
18
Query API
… am Starbucks Beispiel

Coffee coffee = new Coffee();
coffee.setSize(Size.Grande);
coffee.setType(Type.CinnamonDolceLatte);
coffee.setDecaf(DecafLimit.Full);
coffee.setMilk(Milk.NonFat);
coffee.setCream(Cream.WhippedCream);
19
Query API
… am Starbucks Beispiel

Coffee coffee = new Coffee();
coffee.setSize(Size.Grande);
coffee.setType(Type.CinnamonDolceLatte);
coffee.setDecaf(DecafLimit.Full);
coffee.setMilk(Milk.NonFat);
coffee.setCream(Cream.WhippedCream);

˃ Das geht doch schöner, oder?
[8]




Builder-Pattern
21
Das Builder-Pattern
… Expression-Builder
˃ Grundlage
   • Mittels Method-Chaining Lesbarkeit von Query APIs
     erhöhen
˃ Umsetzung
   • Ein oder mehrere Objekte die ein Fluent Interface
     anbieten und in eine darunterliegende Query-API
     transformieren.
˃ Ziel
   • Soll ähnlich lesbar wie eine interne DSL sein
   • Gutes Design für moderne APIs: Builder für die
     wichtigsten Objekte
22
Allgemeine Umsetzung
… In Java

    Object o = new Object.Builder(General)
                       .configureA (A)
                       .configureB (B)
                       .configureC (C)
                       .build ();

                       [9]
23
Fluent-APIs (mit dem Builder-Pattern)
… am Starbucks Beispiel

Coffee coffee = new Coffee.Builder
(Size.Grande, Type.CinnamonDolceLatte)   [10]

.with (DecafLimit.Half)
.with (Milk.Soy)
.with (Cream.WhippedCream)
.build();
24
Fluent-APIs (mit dem Builder-Pattern)
… am Starbucks Beispiel

Coffee coffee = new Coffee.Builder
(Size.Grande, Type.CinnamonDolceLatte)   [10]

.with (DecafLimit.Half)
.with (Milk.Soy)
.with (Cream.WhippedCream)
.build();

˃ Nicht schlecht, aber warum soviel
  Overhead?
25

Code is written for people
    … and only then for computers!




                 [11]
26




                 [12]




Ziele für DSLs
27
Ziele
Im Vordergrund

˃ Klare Wiedergabe der Absicht eines Systems
   • Im Bezug auf die Domäne
˃ Einfachere Lesbarkeit
   • flüssig
   • Hin zu natürlicher Sprache
˃ Bessere Modellierung der Domäne
˃ Domänenexperten sollten DSL verstehen und
  lesen können
   • Nicht zwingend selbst damit arbeiten (Wunschdenken)
28
Ziele
… langfristig

 ˃ Abstraktionsebene von Software erhöhen
 ˃ Software-Entwicklung erleichtern
 ˃ Zeit einsparen
    • Bei der Kommunikation mit Domänen-Experten
    • Beim Umsetzen von fachlichen Anforderungen
29
Ziele
… langfristig

 ˃ Abstraktionsebene von Software erhöhen
 ˃ Software-Entwicklung erleichtern
 ˃ Zeit einsparen
    • Bei der Kommunikation mit Domänen-Experten
    • Beim Umsetzen von fachlichen Anforderungen
 ˃ Und nein, Entwickler wollen wir nicht
   abschaffen
    • Hat bei COBOL auch nicht geklappt ;)
30
Schwierigkeiten
… bei der Umsetzung

˃ Korrekte Abbildung einer Domäne in einer
  gegebenen Sprache oftmals schwierig
˃ Anpassung an die Host-Sprache notwendig
˃ DSL fühlt sich „fremd“ an in der Host-Sprache
˃ Warum passt sich die Sprache nicht der
  Domäne an?
31
Roadmap für den Einsatz von DSLs
… am Beispiel Scala
˃ Schritt 1
    • Tests von Java Objekten mit Scala DSL
˃ Schritt 2
    • Scala DSL als Smart-Wrapper
      um Java Objekte herum
˃ Schritt 3
    • Nicht-kritische Funktionalität mit Hilfe
      einer Scala DSL modellieren
˃ Man muss nicht gleich Produktionscode auf
  Scala umstellen…
32




               [13]




Warum Scala?
33
Warum Scala
… einsetzen für Domain Specific Languages?

˃ Weniger „Noise“
   •   Optionale Punkte beim Methodenaufruf
   •   Semikolon-Inferenz
   •   Typ-Inferenz
   •   Operatoren als Methoden und Infix-Operatoren
   •   Optionale Klammern (an manchen Stellen)
˃ Funktionale Aspekte
   • Gleich mehr dazu
˃ Combinator Parsing (für externe DSLs)
34
„Fluent“-ness von Scala
Ohne
val s : Int = new Palm().get (new
Banana(3)).size;
35
„Fluent“-ness von Scala
mit Companion-Object und Type-Inference
val s : Int = new Palm().get (new
Banana(3)).size;

val s = Palm().get
(Banana(3)).size;
36
„Fluent“-ness von Scala
mit Punkt- und Semicolon-Inferenz
val s : Int = new Palm().get (new
Banana(3)).size;

val s = Palm().get
(Banana(3)).size;

val s = Palm() get (Banana(3)) size
[14]




CLOSURES & FUNCTIONS
38
CLOSURES & FUNCTIONS
Closures

˃ Anonyme Funktionen
˃ Verwendung von Variablen aus dem aktuellen
  Scope möglich

     val greeting = "Welcome"

     val greet : String => String = s => {
        greeting + " " + s
     }

     println greet("MSI Course") // Welcome MSI Course
39
CLOSURES & FUNCTIONS
Currying (1/2)




     def uncurried(s:String, i:Int):String = {
          s + i
     }

     println(uncurried("foo -> ", 1)) // foo -> 1
40
CLOSURES & FUNCTIONS
Currying (2/2)

           def curried(s:String)(i:Int):String = {
                s + " " + i
           }


           val prefill = curried("foo") _      Currying ermöglicht

           val execute = prefill(1)            - Partially Applied
                                                 Functions
           println(execute) // foo 1           - „Neue“
                                                 Kontrollstrukturen

             val control = curried("foo"){
                   1 + 10 - 12
             }

             println(control) // foo -1
41
CLOSURES & FUNCTIONS
Implicit Conversions                        Best Practice

                                            Implicit Conversions in
˃ „Magische Konvertierung“                  Singleton Objects
                                            kapseln.
˃ Vorhandene APIs erweitern
                                            import some.Object.*
     class EnhancedInt(val int:Int){
          def toBinaryString():String = {
            // ...
          }
     }

     implicit def intToEnhancedInt(i:Int):EnhancedInt={
           new EnhancedInt(i)
     }

     println(12 toBinaryString) // 1100
[15]




CASE CLASSES
43
CASE CLASSES
Idee

˃ Normale Klassen mit Modifier case
˃ Erhalten implizit erweiterte Funktionen
   • Verwendbarkeit in Pattern Matching
   • Implizites Companion Object
   • Automatische Vergleichbarkeit
44
CASE CLASSES
Definition und Verwendung

    abstract class TrainWaggon

    case class StandardWaggon(seats : Int)
           extends TrainWaggon

    case class BistroWaggon(seats : Int, bar : Boolean)
           extends TrainWaggon

    case class BaggageWaggon(capacity : Int)
           extends TrainWaggon



               StandardWaggon(50)
               BistroWaggon(20, true)
               BaggageWaggon(200)
45
CASE CLASSES
Beispiel „Option“


 val result : Option[String] = ... // Ergebnis einer
                                         anderen Funktion

 Some("Inhalt") // Es wurde ein Ergebnis erstellt und
                     zurückgeliefert

 None // Es wurde kein Ergebnis erstellt
[17]




PATTERN MATCHING
47
PATTERN MATCHING
Matching auf Werte



  val input : String = "..." // Aus Eingaben, Dateien, ...

  val choice   = input match {
        case   "xml" => exportToXML
        case   "json" => exportToJSON
        case   "doc" => exportToWord
        case   "docx" if isDocxEnabled => exportToWord
        case   _ => invalidExport // Weitere Eingabenwerte
  }
48
PATTERN MATCHING
Matching mit Objekten

˃ Case Classes optimal verwendbar
˃ Elegante Steuerung des Kontrollflusses
  val input : Option[String] = ... // Some("test"), None

  input match {
     case Some("foobar") => false
     case Some("test") => true
     case None => false
  }
[18]




PARTIAL FUNCTIONS
50
PARTIAL FUNCTIONS

    val match1 : PartialFunction[String, String] = {
          case "pictures" => displayPictureGallery
          case "about" => displayAboutInformation
    }

    val match2 : PartialFunction[String, String] = {
          case "users" => displayUserList
          case "news" => displayNews
    }


match1("users")                match1 isDefinedAt "users"
// scala.MatchError            // false

match2("users")                match2 isDefinedAt "users„
// führt displayUserList aus   // true
[19]




PARSER COMBINATORS
52
PARSER COMBINATORS [MAGIC]
object SimpleScala extends RegexpParsers {

  val ID = """[a-zA-Z]([a-zA-Z0-9]|_[a-zA-Z0-9])*"""r

  val NUM = """[1-9][0-9]*"""r

  def program = clazz*

// ...

  def classPrefix = "class" ~ ID ~ "(" ~ formals ~ ")"

// ...                                       Parser direkt in Scala
                                             anhand einer DSL
  def expr: Parser[Expr] = factor ~ (        definieren.
       "+" ~ factor
     | "-" ~ factor                          Beispiele:
  )*                                         - JSON
                                             - SimpleScala
// ...                                       - WebDSL
[20]




Beispiele für DSLs in Scala
[21]




Finance DSL in Scala
55
Finance DSL in Scala
aus DSLsinAction


 val fixedIncomeTrade =
             200.discount_bonds(IBM)
                         .for_client(NOMURA)
                         .on(NYSE)
                         .at(72.ccy(USD))



Beispiel aus [DSLSINACTION]
56
Finance DSL in Scala
aus DSLsinAction


 val fixedIncomeTrade =
             200 discount_bonds IBM
                         for_client NOMURA on NYSE at
                           72.ccy(USD)




Beispiel aus [DSLSINACTION]
[22]




Starbucks DSL in Scala
58
Starbucks Scala DSL
Beispiel für die Verwendung

val o = order (
    Tall (CinnamonDolceLatte decaf
    None withMilk NonFat withCream
    WhippedCream),
    Grande (ConPanna decaf Half),
    Venti (FlavoredLatte decaf None
    withMilk Soy withCream
    NoWhippedCream)
)
59
Starbucks Scala DSL
Schade ist…

val o = order (
    Tall (CinnamonDolceLatte decaf
    None withMilk NonFat withCream
    WhippedCream),
    Grande (ConPanna decaf Half),
    Venti (FlavoredLatte decaf None
    withMilk Soy withCream
    NoWhippedCream)
)
60
Starbucks Scala DSL
Verwendete Konzepte

˃ Companion + apply () für order (…)
˃ Case Objects um „new“ zu entgehen
   • Kaffeesorten (CinnamonDolceLatte, ConPanna…)
   • Milchsorten (NonFat, Soy…)
   • Größen (Tall, Venti, Grande…)
[23]




ScalaTest DSL
62
ScalaTest DSL
http://www.scalatest.org
class StackSpec extends FlatSpec with ShouldMatchers {

  "A Stack" should "pop values in last-in-first-out order"
in {
     val stack = new Stack[Int]
     stack.push(1)
     stack.push(2)
     stack.pop() should equal (2)
     stack.pop() should equal (1)
  }

  it should "throw NoSuchElementException if an empty stack
is popped" in {
    val emptyStack = new Stack[String]
    evaluating { emptyStack.pop() } should produce
[NoSuchElementException]
  }
}
                                                 Beispiel von [SCALATEST]
63
Und mehr
… weitere Scala DSLs

˃ ScalaModules [SCALAMODULES]
    • Konfiguration von OSGi Bundles
˃ Squeryl [SQUERYL]
    • Scala ORM und DSL für SQL-Datenbanken
˃ Baysick [BAYSICK]
    • Scala DSL die BASIC implementiert
˃ Apache Camel DSL      [CAMELDSL]

    • DSL zur Integration von ESB Komponenten
[24]




DB4O


       [LOGOS]
65
DB4O
Native Queries

˃ Interfaces: Predicate<T>, Comparator<T>

   final ObjectSet<User> nativeQuery = database.query(new
  Predicate<User>() {

     @Override
     public boolean match(final User o) {
         final User user = o;
         return user.getLastName().equals("Flanders")
                 && user.getFirstName().endsWith("od");
     }
  });
66
DB4O [SCADB4O] [SCADB4O2]
Offensichtliche Vereinfachung für Native Queries
  final ObjectSet<User> nativeQuery = database.query(new
  Predicate<User>() { … });

 ˃ Anonyme Klasse ersetzen durch Closure
 ˃ Transformation mit Implicit Conversions
  db query { user : User => user.name.contains("t") }


  implicit def toPredicate[T](predicate: T => Boolean) = {
     new Predicate[T]() {
        def `match`(entry: T): Boolean = {
          predicate(entry)                    Durch fehlende
        }                                     Kompatibilität mit
     }                                        Query Optimizer nicht
  }                                           „Production ready“
67
DB4O
SODA Queries

˃ Builder-Pattern
   final Query query = database.query();

   query.constrain(User.class);

   query.descend("firstName").constrain("Johannes");

   query.descend("lastName").constrain("Wachter");
   query.descend("birthday").constrain("1985").like();

   query.descend("age").constrain("19").smaller();

   final ObjectSet<User> execute = query.execute();
68
DB4O
Komplexere DSL für SODA Queries (1/8)



                        Idee

    DB4O Abfragen SQL-ähnlich modellieren!
69
DB4O
Komplexere DSL für SODA Queries (2/8)




db select User.getClass where(„name := “Bart“) and('age < 20)
70
 DB4O
 Komplexere DSL für SODA Queries (3/8)

          ObjectContainer



 db select User.getClass where(„name := “Bart“) and('age < 20)




implicit def oCToDSLOC(c : ObjectContainer):DSLObjectContainer =
             DSLObjectContainer(c)


case class DSLObjectContainer(val c : ObjectContainer){…}
71
DB4O
Komplexere DSL für SODA Queries (4/8)




db select User.getClass where(„name := “Bart“) and('age < 20)



case class DSLQuery[T](query : Query, clazz : Class[T])
extends QueryUtil{
    def where(constr : DSLConstraint):ExtendedDSLQuery[T]={…}
    def order(order : DSLOrdering):DSLQuery[T]{…}
    def execute()={…}
}
72
DB4O
Komplexere DSL für SODA Queries (5/8)
                          def :=(obj:Any):DSLConstraint={…}


                             Symbol

db select User.getClass where(„name := “Bart“) and('age < 20)



            implicit def sToConstr(s: Symbol):DSLConstraint={
                   DSLConstraint(symbol)
            }
73
DB4O
Komplexere DSL für SODA Queries (6/8)


                   abstract class Operator
„name := “Bart“    case object SMALLER extends Operator
                   case object SMALLER_EQUAL extends Operator


case class DSLConstraint(s : Symbol,
                         var b : Any = 0,
                         var op : Operator = EQUALS){

      def :=(obj:Any):DSLConstraint={…}
      def ~|(obj:String):DSLConstraint={…}
}
74
DB4O
Komplexere DSL für SODA Queries (7/8)
val res = c.operator match {


case EQUALS => q.descend(c.symbol.name)
                    .constrain(c.bound).equal
case SMALLER => q.descend(c.symbol.name)
                    .constrain(c.bound).smaller
case SMALLER_EQUAL =>
       q.descend(c.symbol.name).constrain(c.bound).smaller()
       .or(q.descend(c.symbol.name).constrain(c.bound).equal)
}

def or(c : DSLConstraint):ExtendedDSLQuery[T]={
       q.constraints().or(constrain(q, c))
       this
}
75
DB4O
Komplexere DSL für SODA Queries (8/8)

 ˃ Verwendete Scala Features
    •   Implicit Conversions
    •   Builder Pattern
    •   Case Objects
    •   Pattern Matching


 ˃ Typisches Beispiel: Wrapper für Bibliothek
 ˃ Viele Möglichkeiten APIs „lesbar“ abzubilden
[25]




THE DAWN OF DSLs
                   [LOGOS]
77




       [26]




DEMO
SOURCECODE

http://github.com/jwachter/scala-db4o-dsl
79




               [27]




NOCH FRAGEN?
80
Werbung




     http://scala-southerngermany.mixxt.de/
81
Quellen

[BAYSICK]
http://blog.fogus.me/2009/03/26/baysick-a-scala-dsl-implementing-basic/
[STIME]
http://github.com/jorgeortiz85/scala-time
[SCADB4O]
http://matlik.net/blog/2007/11/28/scala-and-db4o-native-queries/
[SCADB4O2]
http://www.matthewtodd.info/?p=68
[SQUERYL]
http://squeryl.org/
[SCALATEST]
http://www.scalatest.org
[DSLSINACTION]
Debashish Ghosh – DSLs In Action (MEAP) (http://manning.com/ghosh/)
[MAGIC]
Daniel Spiewak, http://www.codecommit.com/blog/scala/the-magic-behind-parser-combinators
[FOWLER]
Martin Fowler, http://martinfowler.com/dslwip
(News zum Buch unter http://martinfowler.com/snips/201005261418.html)
[SCALAMODULES]
http://wiki.github.com/weiglewilczek/scalamodules/
[CAMELDSL]
http://camel.apache.org/scala-dsl.html
82
Quellen
Bilder (1/3)
 [1] XKCD, http://xkcd.com/353/
 [2] http://www.flickr.com/photos/stephenccwu/3035854901/
 [3] http://www.flickr.com/photos/travel_aficionado/2396814840/
 [4] http://www.flickr.com/photos/leonardlow/340763653/
 [5] http://www.flickr.com/photos/13698839@N00/3001363490/
 [6] http://www.flickr.com/photos/spherical_perceptions/4634722058/
 [7] http://www.flickr.com/photos/7202153@N03/4623364964/
 [8] http://www.flickr.com/photos/v1ctory_1s_m1ne/3416173688/
 [9] http://www.flickr.com/photos/gorbould/3083371867/
 [10] http://www.flickr.com/photos/jpdaigle/4221047282/
 [11] http://www.flickr.com/photos/trinity-of-one/20562069/
 [12] http://www.flickr.com/photos/bogdansuditu/2377844553/
 [13] http://www.flickr.com/photos/stuartmckenna/3104554689/
 [14] http://www.flickr.com/photos/erikcharlton/421678891/
83
Quellen
Bilder (2/3)
 [15] http://www.flickr.com/photos/zkorb/1592677291/
 [17] http://www.flickr.com/photos/mortimer/221051561/
 [18] http://www.flickr.com/photos/flying_cloud/2666399483/
 [19] http://www.flickr.com/photos/fattytuna/8586848/
 [20] selbst fotografiert (Buch: Programming in Scala)
 [21] http://www.flickr.com/photos/travel_aficionado/2396824478/
 [22] http://www.flickr.com/photos/webel/2406479887/
 [23] http://www.flickr.com/photos/whisperwolf/3487084290/
 [24] http://www.flickr.com/photos/adesigna/3237575990/
 [25] http://www.flickr.com/photos/mugley/4207122005/
 [26] http://www.flickr.com/photos/jof/263652571/
 [27] http://www.flickr.com/photos/themonnie/2500388784/
84
Quellen
Bilder(3/3)
 [LOGOS]
 DB4O - http://www.db4o.com
 LIFT - http://www.liftweb.net
 WEBDSL - http://www.webdsl.org
 Squeryl - http://max-l.github.com/Squeryl
 ScalaTest - http://scalatest.org
 Grails - http://www.grails.org
 Scala - http://www.scala-lang.org
 Groovy - http://groovy.codehaus.org
 Ruby - http://ruby-lang.org
 Python – http://www.python.org
85
License
Präsentation




            http://creativecommons.org/licenses/by-nc-nd/3.0/de/


Quelltext



               http://www.apache.org/licenses/LICENSE-2.0.html

Mais conteúdo relacionado

Destaque

Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...
Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...
Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...Guenter K. Schlamp
 
Ligne Saumur Angers - Tours au 11 décembre 2011
Ligne Saumur  Angers - Tours au 11 décembre 2011Ligne Saumur  Angers - Tours au 11 décembre 2011
Ligne Saumur Angers - Tours au 11 décembre 2011Jean-Charles Taugourdeau
 
10 idées de cadeaux incontournables pour accueillir bébé
10 idées de cadeaux incontournables pour accueillir bébé10 idées de cadeaux incontournables pour accueillir bébé
10 idées de cadeaux incontournables pour accueillir bébéRomu
 
2010 04 01 Lock Schuppen Co Working
2010 04 01 Lock Schuppen Co Working2010 04 01 Lock Schuppen Co Working
2010 04 01 Lock Schuppen Co WorkingRalf Lippold
 
Pau1 2012
Pau1 2012Pau1 2012
Pau1 2012peppadu
 
Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...
Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...
Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...Austrian Red Cross
 
Ciclo de vida de un producto
Ciclo de vida de un productoCiclo de vida de un producto
Ciclo de vida de un productoRafael Abreu
 
La patrouille verte 4 этап
La patrouille verte 4 этапLa patrouille verte 4 этап
La patrouille verte 4 этапHelen
 
Made In Herve : présentation socio-économique (SPI)
Made In Herve : présentation socio-économique (SPI)Made In Herve : présentation socio-économique (SPI)
Made In Herve : présentation socio-économique (SPI)CCICONNECT
 
Curso de administracion de empresas
Curso de administracion de empresasCurso de administracion de empresas
Curso de administracion de empresasCristian Gomez
 

Destaque (15)

Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...
Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...
Die Schulbibliothek - Klassenzimmer des 21. Jahrhunderts. Praesentation fuer ...
 
Luciernaga humilde (no soportan verte brillar)
Luciernaga humilde (no soportan verte brillar)Luciernaga humilde (no soportan verte brillar)
Luciernaga humilde (no soportan verte brillar)
 
Ligne Saumur Angers - Tours au 11 décembre 2011
Ligne Saumur  Angers - Tours au 11 décembre 2011Ligne Saumur  Angers - Tours au 11 décembre 2011
Ligne Saumur Angers - Tours au 11 décembre 2011
 
Practica 2 tics
Practica 2 ticsPractica 2 tics
Practica 2 tics
 
10 idées de cadeaux incontournables pour accueillir bébé
10 idées de cadeaux incontournables pour accueillir bébé10 idées de cadeaux incontournables pour accueillir bébé
10 idées de cadeaux incontournables pour accueillir bébé
 
2010 04 01 Lock Schuppen Co Working
2010 04 01 Lock Schuppen Co Working2010 04 01 Lock Schuppen Co Working
2010 04 01 Lock Schuppen Co Working
 
Pau1 2012
Pau1 2012Pau1 2012
Pau1 2012
 
4 int court
4 int court4 int court
4 int court
 
Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...
Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...
Freiwilligenarbeit in der Langzeitpflege: Freiwilligenarbeit in der Langzeitp...
 
Ciclo de vida de un producto
Ciclo de vida de un productoCiclo de vida de un producto
Ciclo de vida de un producto
 
La patrouille verte 4 этап
La patrouille verte 4 этапLa patrouille verte 4 этап
La patrouille verte 4 этап
 
Lengua castellana
Lengua castellanaLengua castellana
Lengua castellana
 
Sesión sexta
Sesión sextaSesión sexta
Sesión sexta
 
Made In Herve : présentation socio-économique (SPI)
Made In Herve : présentation socio-économique (SPI)Made In Herve : présentation socio-économique (SPI)
Made In Herve : présentation socio-économique (SPI)
 
Curso de administracion de empresas
Curso de administracion de empresasCurso de administracion de empresas
Curso de administracion de empresas
 

Semelhante a DSLs in Scala & DB4O

Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!OPEN KNOWLEDGE GmbH
 
Supersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: QuarkusSupersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: QuarkusOPEN KNOWLEDGE GmbH
 
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, OehmichenJFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, OehmichenOdilo Oehmichen
 
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, OehmichenJFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, OehmichenPatrick Baumgartner
 
Big Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im Überblick
Big Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im ÜberblickBig Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im Überblick
Big Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im ÜberblickKarin Patenge
 
Language Workbench
Language WorkbenchLanguage Workbench
Language Workbenchzensor
 
mongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - GrundlagenmongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - Grundlageninovex GmbH
 
BED-Con - Tools für den täglichen Kampf als Entwickler
BED-Con - Tools für den täglichen Kampf als EntwicklerBED-Con - Tools für den täglichen Kampf als Entwickler
BED-Con - Tools für den täglichen Kampf als EntwicklerPatrick Baumgartner
 
DevOps der Triple-E Klasse - Eclipse DemoCamp
DevOps der Triple-E Klasse - Eclipse DemoCampDevOps der Triple-E Klasse - Eclipse DemoCamp
DevOps der Triple-E Klasse - Eclipse DemoCampWerner Keil
 
Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?
Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?
Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?Trivadis
 
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatengeKarin Patenge
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsJosef Adersberger
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsQAware GmbH
 
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...NETWAYS
 
Grails im Überblick und in der Praxis
Grails im Überblick und in der PraxisGrails im Überblick und in der Praxis
Grails im Überblick und in der PraxisTobias Kraft
 
An Introduction to Ruby On Rails
An Introduction to Ruby On RailsAn Introduction to Ruby On Rails
An Introduction to Ruby On RailsJonathan Weiss
 
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoReady for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoOPEN KNOWLEDGE GmbH
 
Webinar - ABAP Development Tools
Webinar - ABAP Development ToolsWebinar - ABAP Development Tools
Webinar - ABAP Development ToolsCadaxo GmbH
 

Semelhante a DSLs in Scala & DB4O (20)

Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!
 
Supersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: QuarkusSupersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: Quarkus
 
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, OehmichenJFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
 
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, OehmichenJFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
 
Big Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im Überblick
Big Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im ÜberblickBig Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im Überblick
Big Data Community Webinar vom 16. Mai 2019: Oracle NoSQL DB im Überblick
 
Language Workbench
Language WorkbenchLanguage Workbench
Language Workbench
 
mongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - GrundlagenmongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - Grundlagen
 
BED-Con - Tools für den täglichen Kampf als Entwickler
BED-Con - Tools für den täglichen Kampf als EntwicklerBED-Con - Tools für den täglichen Kampf als Entwickler
BED-Con - Tools für den täglichen Kampf als Entwickler
 
Daos
DaosDaos
Daos
 
DevOps der Triple-E Klasse - Eclipse DemoCamp
DevOps der Triple-E Klasse - Eclipse DemoCampDevOps der Triple-E Klasse - Eclipse DemoCamp
DevOps der Triple-E Klasse - Eclipse DemoCamp
 
Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?
Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?
Oracle12c threaded execution - Ressourcen sparen zum Nulltarif?!?
 
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
 
Grails im Überblick und in der Praxis
Grails im Überblick und in der PraxisGrails im Überblick und in der Praxis
Grails im Überblick und in der Praxis
 
An Introduction to Ruby On Rails
An Introduction to Ruby On RailsAn Introduction to Ruby On Rails
An Introduction to Ruby On Rails
 
Digicomp sqlday migration
Digicomp sqlday migrationDigicomp sqlday migration
Digicomp sqlday migration
 
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoReady for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
 
Webinar - ABAP Development Tools
Webinar - ABAP Development ToolsWebinar - ABAP Development Tools
Webinar - ABAP Development Tools
 

DSLs in Scala & DB4O

  • 1. [1] Scala Scala present DSLs in Scala for MSI at HSMA Marcus Körner (@atla_) Johannes Wachter (@jow85)
  • 2. 2 Grande Cinnamon Dolce Latte with tripple shot with non-fat milk topped with whipped cream [2]
  • 3. 3 [3] place orders ( new Order to buy(100 sharesOf ”IBM”) limitPrice 300 allOrNone using premiumPricing, new Order to sell(200 bondsOf ”CISCO”) limitPrice 300 allOrNone using { (qty, unit) => qty * unit - 500 } ) Beispiel aus [DSLSINACTION]
  • 4. 4 Agenda Was sind Warum DSLs Scala? DSL Beispiele DB4O DSL in Scala
  • 6. 6 DSL Allgemeine Definition ˃ Domain Specific Language • Oder auch Fluent API ˃ Domain – [Domäne] • Problemorientiert • „Fachsprache“ ˃ Specific – [Speziell] • Konkret entworfen für einen spezifischen Einsatzzweck • Abgrenzung zur General Purpose Language
  • 7. 7 Domäne … oder auch Anwendungsdomäne ˃ Sammlung an Abläufen, Objekten und Rahmenbedingungen die Teil der Fachdomäne sind ˃ Brücke zwischen realen Objekten aus der Welt des Anwenders und Objekten eines Softwaresystems ˃ Domain-Driven-Design • Schwerpunkt ist die Fachlichkeit und Fachlogik • Ideales Einsatzgebiet für DSLs!
  • 8. 8 Ausdrucksschwäche von GPLs Ocean ocean = new Ocean (); Fish fish1 = new Fish (); fish1.setSize(Size.TINY); fish1.setColor(Color.RED); Fish fish2 = new Fish (); fish2.setSize(Size.MIDSIZE); fish2.setColor(Color.BLUE); Shark shark = new Shark (); shark.setSize(Size.HUGE); shark.setColor(Color.WHITE); Jellyfish jellyfish = new Jellyfish (); jellyfish.setSize(Size.SMALL); Turtle turtle = new Turtle (); turtle.setSize (Size.SMALL); ocean.add (fish1); ocean.add (fish2); ocean.add (shark); ocean.add (jellyfish); ocean.add (turtle);
  • 9. 9 Ausdrucksschwäche von GPLs Ocean ocean = new Ocean (); Wenn man eigentlich meint… Fish fish1 = new Fish (); ocean ( fish1.setSize(Size.TINY); ? fish1.setColor(Color.RED); Fish fish2 = new Fish (); fish2.setSize(Size.MIDSIZE); fish (TINY, RED), fish (SMALL, BLUE), shark (HUGE, WHITE), ? fish2.setColor(Color.BLUE); jellyfish (SMALL), Shark shark = new Shark (); turtle (SMALL) shark.setSize(Size.HUGE); ) shark.setColor(Color.WHITE); ? Jellyfish jellyfish = new Jellyfish (); jellyfish.setSize(Size.SMALL); Turtle turtle = new Turtle (); turtle.setSize (Size.SMALL); ? ocean.add (fish1); ocean.add (fish2); ocean.add (shark); ocean.add (jellyfish); ocean.add (turtle);
  • 10. 10 Ausdrucksschwäche von GPLs Ocean ocean = new Ocean (); Mit Scala 2.8: Named Parameters Fish fish1 = new Fish (); ocean ( fish1.setSize(Size.TINY); ? fish1.setColor(Color.RED); Fish fish2 = new Fish (); fish2.setSize(Size.MIDSIZE); ) fish (size=TINY, color=RED), jellyfish (size=SMALL) ? fish2.setColor(Color.BLUE); Shark shark = new Shark (); shark.setSize(Size.HUGE); shark.setColor(Color.WHITE); ? Jellyfish jellyfish = new Jellyfish (); jellyfish.setSize(Size.SMALL); Turtle turtle = new Turtle (); turtle.setSize (Size.SMALL); ? ocean.add (fish1); ocean.add (fish2); ocean.add (shark); ocean.add (jellyfish); ocean.add (turtle);
  • 11. 11 [5] Klassifizierung von DSLs
  • 12. 12 Klassifizierung ˃ Es gibt zwei wesentliche Unterschiede bei DSLs • Interne DSLs • Externe DSLs ˃ Es gibt allerdings auch einige graphische DSLs
  • 13. 13 Interne DSLs ˃ Eingebettet in eine Host-Sprache • z. B. in Java, Groovy, Scala, Python, C# … ˃ Beeinflusst und limitiert von den Sprachmitteln der Host-Sprache ˃ Einige Vertreter • LINQ (C#), Grails (Groovy), Lift (Scala), WebDSL (Scala)
  • 14. 14 Externe DSLs ˃ Liegen meist in Form von Skripten oder interpretierbaren Text-Dateien vor • Graphviz, (X)HTML ˃ Werden entweder • interpretiert • compiliert in eine andere Sprache (Xtext) ˃ Kennen wir alle nur zu gut… • SQL, Ant-Skripte, Makefiles, XML Konfigurationen
  • 15. 15 Graphische DSLs ˃ Graphische Modellierung einer Domäne • UML, BPM ˃ Meist verbunden mit einem spezifischen Tool • Bsp. Microsoft Oslo, JetBrains MPS, Intentional Domain Workbench ˃ Gut geeignet zum Dokumentieren ˃ Schlecht geeignet zum eigentlichen Entwickeln!
  • 16. 16 [6] Stand der Dinge
  • 17. 17 Naive API … ohne wirkliches Design Cream c = new WhippedCream (); Coffee coffee = new [7] Coffee(”CinnamonDolce”, TYPE_LATTE); coffee.sized(4); coffee.setDecaf (”decaf none”); coffee.addCream(c);
  • 18. 18 Query API … am Starbucks Beispiel Coffee coffee = new Coffee(); coffee.setSize(Size.Grande); coffee.setType(Type.CinnamonDolceLatte); coffee.setDecaf(DecafLimit.Full); coffee.setMilk(Milk.NonFat); coffee.setCream(Cream.WhippedCream);
  • 19. 19 Query API … am Starbucks Beispiel Coffee coffee = new Coffee(); coffee.setSize(Size.Grande); coffee.setType(Type.CinnamonDolceLatte); coffee.setDecaf(DecafLimit.Full); coffee.setMilk(Milk.NonFat); coffee.setCream(Cream.WhippedCream); ˃ Das geht doch schöner, oder?
  • 21. 21 Das Builder-Pattern … Expression-Builder ˃ Grundlage • Mittels Method-Chaining Lesbarkeit von Query APIs erhöhen ˃ Umsetzung • Ein oder mehrere Objekte die ein Fluent Interface anbieten und in eine darunterliegende Query-API transformieren. ˃ Ziel • Soll ähnlich lesbar wie eine interne DSL sein • Gutes Design für moderne APIs: Builder für die wichtigsten Objekte
  • 22. 22 Allgemeine Umsetzung … In Java Object o = new Object.Builder(General) .configureA (A) .configureB (B) .configureC (C) .build (); [9]
  • 23. 23 Fluent-APIs (mit dem Builder-Pattern) … am Starbucks Beispiel Coffee coffee = new Coffee.Builder (Size.Grande, Type.CinnamonDolceLatte) [10] .with (DecafLimit.Half) .with (Milk.Soy) .with (Cream.WhippedCream) .build();
  • 24. 24 Fluent-APIs (mit dem Builder-Pattern) … am Starbucks Beispiel Coffee coffee = new Coffee.Builder (Size.Grande, Type.CinnamonDolceLatte) [10] .with (DecafLimit.Half) .with (Milk.Soy) .with (Cream.WhippedCream) .build(); ˃ Nicht schlecht, aber warum soviel Overhead?
  • 25. 25 Code is written for people … and only then for computers! [11]
  • 26. 26 [12] Ziele für DSLs
  • 27. 27 Ziele Im Vordergrund ˃ Klare Wiedergabe der Absicht eines Systems • Im Bezug auf die Domäne ˃ Einfachere Lesbarkeit • flüssig • Hin zu natürlicher Sprache ˃ Bessere Modellierung der Domäne ˃ Domänenexperten sollten DSL verstehen und lesen können • Nicht zwingend selbst damit arbeiten (Wunschdenken)
  • 28. 28 Ziele … langfristig ˃ Abstraktionsebene von Software erhöhen ˃ Software-Entwicklung erleichtern ˃ Zeit einsparen • Bei der Kommunikation mit Domänen-Experten • Beim Umsetzen von fachlichen Anforderungen
  • 29. 29 Ziele … langfristig ˃ Abstraktionsebene von Software erhöhen ˃ Software-Entwicklung erleichtern ˃ Zeit einsparen • Bei der Kommunikation mit Domänen-Experten • Beim Umsetzen von fachlichen Anforderungen ˃ Und nein, Entwickler wollen wir nicht abschaffen • Hat bei COBOL auch nicht geklappt ;)
  • 30. 30 Schwierigkeiten … bei der Umsetzung ˃ Korrekte Abbildung einer Domäne in einer gegebenen Sprache oftmals schwierig ˃ Anpassung an die Host-Sprache notwendig ˃ DSL fühlt sich „fremd“ an in der Host-Sprache ˃ Warum passt sich die Sprache nicht der Domäne an?
  • 31. 31 Roadmap für den Einsatz von DSLs … am Beispiel Scala ˃ Schritt 1 • Tests von Java Objekten mit Scala DSL ˃ Schritt 2 • Scala DSL als Smart-Wrapper um Java Objekte herum ˃ Schritt 3 • Nicht-kritische Funktionalität mit Hilfe einer Scala DSL modellieren ˃ Man muss nicht gleich Produktionscode auf Scala umstellen…
  • 32. 32 [13] Warum Scala?
  • 33. 33 Warum Scala … einsetzen für Domain Specific Languages? ˃ Weniger „Noise“ • Optionale Punkte beim Methodenaufruf • Semikolon-Inferenz • Typ-Inferenz • Operatoren als Methoden und Infix-Operatoren • Optionale Klammern (an manchen Stellen) ˃ Funktionale Aspekte • Gleich mehr dazu ˃ Combinator Parsing (für externe DSLs)
  • 34. 34 „Fluent“-ness von Scala Ohne val s : Int = new Palm().get (new Banana(3)).size;
  • 35. 35 „Fluent“-ness von Scala mit Companion-Object und Type-Inference val s : Int = new Palm().get (new Banana(3)).size; val s = Palm().get (Banana(3)).size;
  • 36. 36 „Fluent“-ness von Scala mit Punkt- und Semicolon-Inferenz val s : Int = new Palm().get (new Banana(3)).size; val s = Palm().get (Banana(3)).size; val s = Palm() get (Banana(3)) size
  • 38. 38 CLOSURES & FUNCTIONS Closures ˃ Anonyme Funktionen ˃ Verwendung von Variablen aus dem aktuellen Scope möglich val greeting = "Welcome" val greet : String => String = s => { greeting + " " + s } println greet("MSI Course") // Welcome MSI Course
  • 39. 39 CLOSURES & FUNCTIONS Currying (1/2) def uncurried(s:String, i:Int):String = { s + i } println(uncurried("foo -> ", 1)) // foo -> 1
  • 40. 40 CLOSURES & FUNCTIONS Currying (2/2) def curried(s:String)(i:Int):String = { s + " " + i } val prefill = curried("foo") _ Currying ermöglicht val execute = prefill(1) - Partially Applied Functions println(execute) // foo 1 - „Neue“ Kontrollstrukturen val control = curried("foo"){ 1 + 10 - 12 } println(control) // foo -1
  • 41. 41 CLOSURES & FUNCTIONS Implicit Conversions Best Practice Implicit Conversions in ˃ „Magische Konvertierung“ Singleton Objects kapseln. ˃ Vorhandene APIs erweitern import some.Object.* class EnhancedInt(val int:Int){ def toBinaryString():String = { // ... } } implicit def intToEnhancedInt(i:Int):EnhancedInt={ new EnhancedInt(i) } println(12 toBinaryString) // 1100
  • 43. 43 CASE CLASSES Idee ˃ Normale Klassen mit Modifier case ˃ Erhalten implizit erweiterte Funktionen • Verwendbarkeit in Pattern Matching • Implizites Companion Object • Automatische Vergleichbarkeit
  • 44. 44 CASE CLASSES Definition und Verwendung abstract class TrainWaggon case class StandardWaggon(seats : Int) extends TrainWaggon case class BistroWaggon(seats : Int, bar : Boolean) extends TrainWaggon case class BaggageWaggon(capacity : Int) extends TrainWaggon StandardWaggon(50) BistroWaggon(20, true) BaggageWaggon(200)
  • 45. 45 CASE CLASSES Beispiel „Option“ val result : Option[String] = ... // Ergebnis einer anderen Funktion Some("Inhalt") // Es wurde ein Ergebnis erstellt und zurückgeliefert None // Es wurde kein Ergebnis erstellt
  • 47. 47 PATTERN MATCHING Matching auf Werte val input : String = "..." // Aus Eingaben, Dateien, ... val choice = input match { case "xml" => exportToXML case "json" => exportToJSON case "doc" => exportToWord case "docx" if isDocxEnabled => exportToWord case _ => invalidExport // Weitere Eingabenwerte }
  • 48. 48 PATTERN MATCHING Matching mit Objekten ˃ Case Classes optimal verwendbar ˃ Elegante Steuerung des Kontrollflusses val input : Option[String] = ... // Some("test"), None input match { case Some("foobar") => false case Some("test") => true case None => false }
  • 50. 50 PARTIAL FUNCTIONS val match1 : PartialFunction[String, String] = { case "pictures" => displayPictureGallery case "about" => displayAboutInformation } val match2 : PartialFunction[String, String] = { case "users" => displayUserList case "news" => displayNews } match1("users") match1 isDefinedAt "users" // scala.MatchError // false match2("users") match2 isDefinedAt "users„ // führt displayUserList aus // true
  • 52. 52 PARSER COMBINATORS [MAGIC] object SimpleScala extends RegexpParsers { val ID = """[a-zA-Z]([a-zA-Z0-9]|_[a-zA-Z0-9])*"""r val NUM = """[1-9][0-9]*"""r def program = clazz* // ... def classPrefix = "class" ~ ID ~ "(" ~ formals ~ ")" // ... Parser direkt in Scala anhand einer DSL def expr: Parser[Expr] = factor ~ ( definieren. "+" ~ factor | "-" ~ factor Beispiele: )* - JSON - SimpleScala // ... - WebDSL
  • 55. 55 Finance DSL in Scala aus DSLsinAction val fixedIncomeTrade = 200.discount_bonds(IBM) .for_client(NOMURA) .on(NYSE) .at(72.ccy(USD)) Beispiel aus [DSLSINACTION]
  • 56. 56 Finance DSL in Scala aus DSLsinAction val fixedIncomeTrade = 200 discount_bonds IBM for_client NOMURA on NYSE at 72.ccy(USD) Beispiel aus [DSLSINACTION]
  • 58. 58 Starbucks Scala DSL Beispiel für die Verwendung val o = order ( Tall (CinnamonDolceLatte decaf None withMilk NonFat withCream WhippedCream), Grande (ConPanna decaf Half), Venti (FlavoredLatte decaf None withMilk Soy withCream NoWhippedCream) )
  • 59. 59 Starbucks Scala DSL Schade ist… val o = order ( Tall (CinnamonDolceLatte decaf None withMilk NonFat withCream WhippedCream), Grande (ConPanna decaf Half), Venti (FlavoredLatte decaf None withMilk Soy withCream NoWhippedCream) )
  • 60. 60 Starbucks Scala DSL Verwendete Konzepte ˃ Companion + apply () für order (…) ˃ Case Objects um „new“ zu entgehen • Kaffeesorten (CinnamonDolceLatte, ConPanna…) • Milchsorten (NonFat, Soy…) • Größen (Tall, Venti, Grande…)
  • 62. 62 ScalaTest DSL http://www.scalatest.org class StackSpec extends FlatSpec with ShouldMatchers { "A Stack" should "pop values in last-in-first-out order" in { val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop() should equal (2) stack.pop() should equal (1) } it should "throw NoSuchElementException if an empty stack is popped" in { val emptyStack = new Stack[String] evaluating { emptyStack.pop() } should produce [NoSuchElementException] } } Beispiel von [SCALATEST]
  • 63. 63 Und mehr … weitere Scala DSLs ˃ ScalaModules [SCALAMODULES] • Konfiguration von OSGi Bundles ˃ Squeryl [SQUERYL] • Scala ORM und DSL für SQL-Datenbanken ˃ Baysick [BAYSICK] • Scala DSL die BASIC implementiert ˃ Apache Camel DSL [CAMELDSL] • DSL zur Integration von ESB Komponenten
  • 64. [24] DB4O [LOGOS]
  • 65. 65 DB4O Native Queries ˃ Interfaces: Predicate<T>, Comparator<T> final ObjectSet<User> nativeQuery = database.query(new Predicate<User>() { @Override public boolean match(final User o) { final User user = o; return user.getLastName().equals("Flanders") && user.getFirstName().endsWith("od"); } });
  • 66. 66 DB4O [SCADB4O] [SCADB4O2] Offensichtliche Vereinfachung für Native Queries final ObjectSet<User> nativeQuery = database.query(new Predicate<User>() { … }); ˃ Anonyme Klasse ersetzen durch Closure ˃ Transformation mit Implicit Conversions db query { user : User => user.name.contains("t") } implicit def toPredicate[T](predicate: T => Boolean) = { new Predicate[T]() { def `match`(entry: T): Boolean = { predicate(entry) Durch fehlende } Kompatibilität mit } Query Optimizer nicht } „Production ready“
  • 67. 67 DB4O SODA Queries ˃ Builder-Pattern final Query query = database.query(); query.constrain(User.class); query.descend("firstName").constrain("Johannes"); query.descend("lastName").constrain("Wachter"); query.descend("birthday").constrain("1985").like(); query.descend("age").constrain("19").smaller(); final ObjectSet<User> execute = query.execute();
  • 68. 68 DB4O Komplexere DSL für SODA Queries (1/8) Idee DB4O Abfragen SQL-ähnlich modellieren!
  • 69. 69 DB4O Komplexere DSL für SODA Queries (2/8) db select User.getClass where(„name := “Bart“) and('age < 20)
  • 70. 70 DB4O Komplexere DSL für SODA Queries (3/8) ObjectContainer db select User.getClass where(„name := “Bart“) and('age < 20) implicit def oCToDSLOC(c : ObjectContainer):DSLObjectContainer = DSLObjectContainer(c) case class DSLObjectContainer(val c : ObjectContainer){…}
  • 71. 71 DB4O Komplexere DSL für SODA Queries (4/8) db select User.getClass where(„name := “Bart“) and('age < 20) case class DSLQuery[T](query : Query, clazz : Class[T]) extends QueryUtil{ def where(constr : DSLConstraint):ExtendedDSLQuery[T]={…} def order(order : DSLOrdering):DSLQuery[T]{…} def execute()={…} }
  • 72. 72 DB4O Komplexere DSL für SODA Queries (5/8) def :=(obj:Any):DSLConstraint={…} Symbol db select User.getClass where(„name := “Bart“) and('age < 20) implicit def sToConstr(s: Symbol):DSLConstraint={ DSLConstraint(symbol) }
  • 73. 73 DB4O Komplexere DSL für SODA Queries (6/8) abstract class Operator „name := “Bart“ case object SMALLER extends Operator case object SMALLER_EQUAL extends Operator case class DSLConstraint(s : Symbol, var b : Any = 0, var op : Operator = EQUALS){ def :=(obj:Any):DSLConstraint={…} def ~|(obj:String):DSLConstraint={…} }
  • 74. 74 DB4O Komplexere DSL für SODA Queries (7/8) val res = c.operator match { case EQUALS => q.descend(c.symbol.name) .constrain(c.bound).equal case SMALLER => q.descend(c.symbol.name) .constrain(c.bound).smaller case SMALLER_EQUAL => q.descend(c.symbol.name).constrain(c.bound).smaller() .or(q.descend(c.symbol.name).constrain(c.bound).equal) } def or(c : DSLConstraint):ExtendedDSLQuery[T]={ q.constraints().or(constrain(q, c)) this }
  • 75. 75 DB4O Komplexere DSL für SODA Queries (8/8) ˃ Verwendete Scala Features • Implicit Conversions • Builder Pattern • Case Objects • Pattern Matching ˃ Typisches Beispiel: Wrapper für Bibliothek ˃ Viele Möglichkeiten APIs „lesbar“ abzubilden
  • 76. [25] THE DAWN OF DSLs [LOGOS]
  • 77. 77 [26] DEMO
  • 79. 79 [27] NOCH FRAGEN?
  • 80. 80 Werbung http://scala-southerngermany.mixxt.de/
  • 81. 81 Quellen [BAYSICK] http://blog.fogus.me/2009/03/26/baysick-a-scala-dsl-implementing-basic/ [STIME] http://github.com/jorgeortiz85/scala-time [SCADB4O] http://matlik.net/blog/2007/11/28/scala-and-db4o-native-queries/ [SCADB4O2] http://www.matthewtodd.info/?p=68 [SQUERYL] http://squeryl.org/ [SCALATEST] http://www.scalatest.org [DSLSINACTION] Debashish Ghosh – DSLs In Action (MEAP) (http://manning.com/ghosh/) [MAGIC] Daniel Spiewak, http://www.codecommit.com/blog/scala/the-magic-behind-parser-combinators [FOWLER] Martin Fowler, http://martinfowler.com/dslwip (News zum Buch unter http://martinfowler.com/snips/201005261418.html) [SCALAMODULES] http://wiki.github.com/weiglewilczek/scalamodules/ [CAMELDSL] http://camel.apache.org/scala-dsl.html
  • 82. 82 Quellen Bilder (1/3) [1] XKCD, http://xkcd.com/353/ [2] http://www.flickr.com/photos/stephenccwu/3035854901/ [3] http://www.flickr.com/photos/travel_aficionado/2396814840/ [4] http://www.flickr.com/photos/leonardlow/340763653/ [5] http://www.flickr.com/photos/13698839@N00/3001363490/ [6] http://www.flickr.com/photos/spherical_perceptions/4634722058/ [7] http://www.flickr.com/photos/7202153@N03/4623364964/ [8] http://www.flickr.com/photos/v1ctory_1s_m1ne/3416173688/ [9] http://www.flickr.com/photos/gorbould/3083371867/ [10] http://www.flickr.com/photos/jpdaigle/4221047282/ [11] http://www.flickr.com/photos/trinity-of-one/20562069/ [12] http://www.flickr.com/photos/bogdansuditu/2377844553/ [13] http://www.flickr.com/photos/stuartmckenna/3104554689/ [14] http://www.flickr.com/photos/erikcharlton/421678891/
  • 83. 83 Quellen Bilder (2/3) [15] http://www.flickr.com/photos/zkorb/1592677291/ [17] http://www.flickr.com/photos/mortimer/221051561/ [18] http://www.flickr.com/photos/flying_cloud/2666399483/ [19] http://www.flickr.com/photos/fattytuna/8586848/ [20] selbst fotografiert (Buch: Programming in Scala) [21] http://www.flickr.com/photos/travel_aficionado/2396824478/ [22] http://www.flickr.com/photos/webel/2406479887/ [23] http://www.flickr.com/photos/whisperwolf/3487084290/ [24] http://www.flickr.com/photos/adesigna/3237575990/ [25] http://www.flickr.com/photos/mugley/4207122005/ [26] http://www.flickr.com/photos/jof/263652571/ [27] http://www.flickr.com/photos/themonnie/2500388784/
  • 84. 84 Quellen Bilder(3/3) [LOGOS] DB4O - http://www.db4o.com LIFT - http://www.liftweb.net WEBDSL - http://www.webdsl.org Squeryl - http://max-l.github.com/Squeryl ScalaTest - http://scalatest.org Grails - http://www.grails.org Scala - http://www.scala-lang.org Groovy - http://groovy.codehaus.org Ruby - http://ruby-lang.org Python – http://www.python.org
  • 85. 85 License Präsentation http://creativecommons.org/licenses/by-nc-nd/3.0/de/ Quelltext http://www.apache.org/licenses/LICENSE-2.0.html