Praktische Informatik 3 (WS 2016/17) - informatik.uni

Werbung
Fahrplan
Praktische Informatik 3: Funktionale Programmierung
I
Teil I: Funktionale Programmierung im Kleinen
I
Teil II: Funktionale Programmierung im Großen
I
Teil III: Funktionale Programmierung im richtigen Leben
Vorlesung 12 vom 17.01.17: Domänenspezifische Sprachen (DSLs)
Christoph Lüth
Universität Bremen
Wintersemester 2016/17
16:02:34 2017-01-17
I
Aktionen und Zustände
I
Monaden als Berechnungsmuster
I
Domänenspezifische Sprachen (DSLs)
I
Scala — Eine praktische Einführung
I
Rückblich & Ausblick
PI3 WS 16/17
1 [25]
Domain-Specific Languages (DSLs)
2 [25]
Programmiersprachen sind überall
I
Was ist das?
I
Beispiel 1: SQL — Anfragesprache für relationale Datenbanken
I
Wie macht man das?
I
Beispiel 2: Excel — Modellierung von Berechnungen
I
Wozu braucht man so etwas?
I
Beispiel 3: HTML oder LaTeX oder Word — Typesetting
PI3 WS 16/17
PI3 WS 16/17
3 [25]
Vom Allgemeinen zum Speziellen
I
DSL: Definition 1
Modellierung von Problemen und Lösungen
Allgemein Allgemeine Lösung: GPL
Mächtige Sprache
(Turing-mächtig)
I
- Spezifisch
Wohldefinierte Unterklasse
(Domäne) von Problemen
Großer Abstand zum Problem
I
Geringer Abstand zum Problem
Java, Haskell, C . . .
I
Domain-Specific Language
(DSL)
I
Als Teil einer
Programmiersprache
(eingebettet) oder alleinstehend
(stand-alone)
Große Klasse von Problemen
I
I
I
General purpose language (GPL)
PI3 WS 16/17
A domain-specific language (DSL) is a programming language or
executable specification language that offers, through appropriate
notations and abstractions, expressive power focused on, and usually
restricted to, a particular problem domain.
Spezifische Lösung: DSL
Maßgeschneiderte Sprache
I
I
I
5 [25]
Eigenschaften von DSLs
I
(van Deursen et al., 2000)
PI3 WS 16/17
Fokussierte Ausdrucksmächtigkeit
I
Turing-Mächtigkeit nicht Ziel der Sprache (aber kein Ausschlusskriterium)
I
Oftmals deutlich weniger mächtig: Reguläre Ausdrücke, Makefiles, HTML
Üblicherweise klein (“little languages”, “micro-languages”)
I
Anzahl der Sprachkonstrukte eingeschränkt und auf die Anwendung
zugeschnitten
Adressbuchformat
grammar {
start = entries
entries = element entries { entry* }
entry = element entry {
attribute name { text },
attribute birth { xsd:dateTime },
text }
}
I
Beschreibung von XML-Bäumen
I
I
Meist deklarativ: XSLT, Relax NG Schemas, Excel Formeln. . .
PI3 WS 16/17
6 [25]
DSL-Beispiel: Relax NG
I
I
4 [25]
7 [25]
Erlaubte Element-Verschachtelungen & -Reihenfolgen
Datentypen von Attributen & Elementwerten
I
Automatische Generierung von Validatoren
I
Nicht Turing-mächtig (?)
PI3 WS 16/17
8 [25]
Domain-Specific Embedded Languages
I
Beispiel: Reguläre Ausdrücke
DSL direkt in eine GPL einbetten
I
Vorhandenes Ausführungsmodell und Werkzeuge
Ein regulärer Ausdruck ist:
Haskell-Implementierung — Signatur:
type RegEx
I
Funktionale Sprachen eignen sich hierfür besonders gut
Algebraische Datentypen zur Termrepräsentation
I
Einzelnes Zeichen c
Funktional ⊆ Deklarativ
I
Beliebiges Zeichen ?
I
Funktionen höherer Ordnung ideal für Kombinatoren
I
Sequenzierung e1 e2
I
Alternierung e1 | e2
I
Kleene-Stern e ∗ = | ee ∗
Abgeleitet:
I
I
Interpreter (ghci, ocaml, . . . ) erlauben “rapid prototyping”
Erweiterung zu stand-alone leicht möglich
I
9 [25]
Regular Ausdrücke: Suche
Wie modellieren wir mehrfache
Suche?
Signatur:
type RegEx =
String→ [ String ]
I
eps
char
arb
seq
alt
star
::
::
::
::
::
::
RegEx
Char→ RegEx
RegEx
RegEx→ RegEx→ RegEx
RegEx→ RegEx→ RegEx
RegEx→ RegEx
Implementierung: siehe RegExS.hs
Kleene-Plus e + = e e ∗
Java: Eclipse Modelling Framework, Xtext
PI3 WS 16/17
I
I
Andere Sprachen:
I
I
Leeres Wort I
I
I
I
Wie modellieren wir ersetzen?
PI3 WS 16/17
10 [25]
Flache Einbettung vs. Tiefe Einbettung
Besser: Repräsentation durch
Datentypen
data RE = Eps
| Chr Char
| Str String
| Arb
| Seq RE RE
| Alt RE RE
| Star RE
| Plus RE
| Range [ Char ]
deriving (Eq, Show)
I
I
intp :: RE→ RegEx
Flache Einbettung:
I
Domänenfunktionen direkt als Haskell-Funktionen
I
Keine explizite Repräsentation der Domänenobjekte in Haskell
Tiefe Einbettung:
I
Repräsentation der Domänenobjekte durch Haskell-Datentyp (oder ADT)
I
Domänenfunktionen auf diesem Datentyp
searchAll :: RE→ String→
[ String ]
PI3 WS 16/17
11 [25]
Flach oder Tief?
I
I
PI3 WS 16/17
Beispiel: Grafik
Vorteile flache Einbettung:
I
Schnell geschrieben, weniger ’boilerplate’
I
Flexibel erweiterbar
Vorteile tiefe Einbettung:
I
Mächtiger: Manipulation der Domänenobjekte
I
Transformation, Übersetzung, . . .
I
Bsp: Übersetzung RE in Zustandsautomaten
I
Erzeugung von SVG-Grafiken
I
Eingebettete DSL:
I
Erste Näherung: TinySVG (modelliert nur die Daten)
I
Erweiterung: Monade Draw (Zustandsmonade)
I
Funktionen zum Zeichnen:
line
:: Point→ Point→ Draw ()
polygon :: [ Point ] → Draw ()
I
PI3 WS 16/17
12 [25]
13 [25]
Beispielprogramm: Sierpińksy-Dreieck
“Ausführen”:
draw :: Double→ Double→ String→ Draw ()→ IO ()
PI3 WS 16/17
14 [25]
Resultat: Sierpińsky-Dreieck und Schneeflocke
Dreieck mit Eckpunkten zeichnen:
drawTriangle :: Point→ Point→ Point→ Draw ()
Mitte zwischen zwei Punkten:
midway :: Point→ Point→ Point
midway p q = 0.5 ‘ smult ‘ (p+ q)
Sierpińksy-Dreieck rekursiv
spTri
spTri
h=
a=
sp3
sp3
|
|
PI3 WS 16/17
:: Double→ Int→ Draw ()
sz l i m i t = sp3 a b c 0 where
sz∗ sqrt 3/4
Pt 0 (−h ) ; b = Pt (−sz/2) h ; c= Pt ( sz/2) h
:: Point→ Point→ Point→ Int→ Draw ()
a b c n
n ≥ l i m i t = drawTriangle a b c
otherwise = do
let ab = midway a b ; bc = midway b c ; ca = midway c a
sp3 a ab ca (n+1); sp3 ab b bc (n+1); sp3 ca bc c (n+1)
15 [25]
PI3 WS 16/17
16 [25]
Erweiterung: Transformation
I
Beispiele: Verschiebung und Skalierung
Allgemein: Transformation von Grafiken
xform :: ( Graphics→ Graphics )→ Draw()→ Draw()
I
Speziell:
I
Rotation um einen Punkt:
rotate :: Point→ Double→ Draw ()→ Draw ()
I
Skalierung um einen Faktor:
scale :: Double→ Draw()→ Draw ()
I
Verschiebung um einen Vektor (Punkt):
translate :: Point → Draw () → Draw ()
PI3 WS 16/17
17 [25]
Weitere Abgrenzung
I
Etwa jUnit: assertTrue(), assertEquals() Methoden & @Before,
@Test, @After Annotationen
I
Ziel: Funktionalität von Schaltkreisen beschreiben
Einfachster Fall:
and :: Bool→ Bool→ Bool
or :: Bool→ Bool→ Bool
I
Funktionsnamen spiegeln ebenfalls Domänenvokabular wider
I
Gängige Sprachen (Java, C/C++) erschweren weitere Abstraktion:
Syntaxerweiterungen, Konzepte höherer Ordnung
I
I
Imperative Programmiersprache vs. deklarative DSL
CλaSH
Skriptsprachen
I JavaScript, PHP, Lua, Tcl, Ruby werden für DS-artige Aufgaben
verwendet
I
I
I
I
HTML/XML DOM-Manipulation
Game Scripting, GUIs, . . .
Webprogrammierung (Ruby on Rails)
Grundausrichtung: programmatische Erweiterung von Systemen
PI3 WS 16/17
19 [25]
Beispiel: SQL
I
SQL-Anfragen werden in Haskell modelliert, dann übersetzt und an DB
geschickt
Vorteil: typsicher, ausdrucksstark
I
Wie modelliert man das Ergebnis? → Abbildung Haskell-Typen auf DB
I
Haskell: Opaleye
I
Modellierung und Simulation von Schaltkreisen in Haskell
I
Typ Signal α für synchrone sequentielle Schaltkreise
I
Rekursion für Feedback
I
Simulation des Verhalten des Schaltkreises möglich
I
Generiert VHDL, Verilog, SystemVerilog, und Testdaten
I
Verwandt: Chisel (in Scala), Bluespec (kommerziell), Lava (veraltet)
PI3 WS 16/17
Ausdruck von Problemen/Lösungen in der Sprache und auf dem
Abstraktionslevel der Anwendungsdomäne
I
Notation matters: Programmiersprachen bieten oftmals nicht die
Möglichkeit, Konstrukte der Domäne angemessen wiederzugeben
I
DSL-Lösungen sind oftmals selbstdokumentierend und knapp
I
Bessere (automatische) Analyse, Optimierung und Testfallgenerierung
von Programmen
I
21 [25]
Nachteile der Verwendung von DSLs
I
Hohe initiale Entwicklungskosten
I
Schulungsbedarf
I
Sprachdesign ist eine äußerst schwierige und komplexe Angelegenheit,
deren Aufwand nahezu immer unterschätzt wird
I
I
Fehlender Tool-Support
I
Debugger
I
Generierung von (Online-)Dokumentation
I
Statische Analysen, . . .
Effizienz: Interpretation ggf. langsamer als direkte Implementierung in
GPL
PI3 WS 16/17
20 [25]
I
Scala: Slick
PI3 WS 16/17
Moderne Schaltkreise sind etwas komplizierter . . .
Vorteile der Verwendung von DSLs
I
I
18 [25]
Beispiel: Hardware Description Languages
Programmierschnittstellen (APIs)
I
PI3 WS 16/17
23 [25]
I
Klar umrissene Domänensemantik
I
eingeschränkte Sprachmächtigkeit ⇒ weniger Berechenbarkeitsfallen
Leichter von Nicht-Programmierern zu erlernen als GPLs
PI3 WS 16/17
22 [25]
Zusammenfassung
I
DSL: Maßgeschneiderte Sprache für wohldefinierten Problemkreis
I
Vorteile: näher am Problem, näher an der Lösung
I
Nachteile: Initialer Aufwand
I
Klassifikation von DSLs:
I
I
Flache vs. tiefe Einbettung
I
Stand-alone vs. embedded
Nächste Woche: Scala — eine Einführung.
PI3 WS 16/17
24 [25]
Literatur
Koen Claessen and David Sands.
Observable sharing for functional circuit description.
In P. S. Thiagarajan and R. Yap, editors, Advances in Computing
Science – ASIAN’99, volume 1742 of LNCS, pages 62–73, 1999.
Paul Hudak.
Building domain-specific embedded languages.
ACM Comput. Surv., 28, 1996.
Marjan Mernik, Jan Heering, and Anthony M. Sloane.
When and how to develop domain-specific languages.
ACM Comput. Surv., 37(4):316–344, 2005.
Arie van Deursen, Paul Klint, and Joost Visser.
Domain-specific languages: an annotated bibliography.
SIGPLAN Not., 35(6):26–36, 2000.
PI3 WS 16/17
25 [25]
Herunterladen