• Keine Ergebnisse gefunden

Reaktive Programmierung Vorlesung 8 vom 15.05.19 Meta-Programmierung

N/A
N/A
Protected

Academic year: 2022

Aktie "Reaktive Programmierung Vorlesung 8 vom 15.05.19 Meta-Programmierung"

Copied!
22
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Reaktive Programmierung Vorlesung 8 vom 15.05.19 Meta-Programmierung

Christoph Lüth, Martin Ring

Universität Bremen

Sommersemester 2019

(2)

Fahrplan

I Einführung

I Monaden und Monadentransformer I Nebenläufigkeit: Futures and Promises I Aktoren I: Grundlagen

I Aktoren II: Implementation I Meta-Programmierung

I Bidirektionale Programmierung I Reaktive Ströme I

I Reaktive Ströme II

I Funktional-Reaktive Programmierung I Software Transactional Memory I Eventual Consistency

I Robustheit und Entwurfsmuster

(3)

Was ist Meta-Programmierung?

“Programme höherer Ordnung” / Makros

Source Compiler Program

(4)

Was sehen wir heute?

I Anwendungsbeispiel: JSON Serialisierung I Meta-Programmierung in Scala:

I Scala Meta

I Meta-Programmierung in Haskell:

I Template Haskell

I Generische Programmierung in Scala und Haskell

(5)

Beispiel: JSON Serialisierung

Scala

case class Person(

names : L i s t [ String ] , age : Int

)

Haskell

data Person = Person { names :: [ String ] , age :: Int

}

Ziel: Scala ←−−−→JSON Haskell

(6)

JSON: Erster Versuch

JSON1.scala

I Unpraktisch: Für jeden Typ muss manuell eine Instanz erzeugt werden I Idee: Makros for the win

(7)

JSON: Erster Versuch

JSON1.scala

I Unpraktisch: Für jeden Typ muss manuell eine Instanz erzeugt werden I Idee: Makros for the win

(8)

Klassische Metaprogrammierung (Beispiel C)

#define square (n) ((n)∗(n) )

#define UpTo( i , n) for(( i ) = 0; ( i ) < (n) ; ( i )++) UpTo( i ,10) {

p r i n t f (" i squared i s : %d\n", square ( i ) ) ; }

I Eigene Sprache: C Präprozessor

I Keine Typsicherheit: einfache String Ersetzungen

(9)

Metaprogrammierung in Scala: Scalameta

I Idee: Der Compiler ist im Programm verfügbar

> "x + 2 ∗ 7". parse [Term ] . get . structure

Term. ApplyInfix (Term.Name("x") , Term.Name("+") , Nil , Seq(Term. ApplyInfix ( L i t . Int (2) , Term.Name("∗") , Nil , Seq( L i t . Int (7) ) ) ) )

I Abstrakter syntaxbaum (AST) als algebraischer Datentyp→ typsicher I Sehr komplexer Datentyp . . .

(10)

Quasiquotations

I Idee: Programmcode statt AST I Zur Konstruktion . . .

> val p = q"case c l a s s Person(name: String ) "

p : meta . Defn . Class = case class Person(name: String ) I . . . und zur Extraktion

> val q"case c l a s s $name($param) "= p name: meta . Type .Name = Person

param : scala . meta .Term.Param = name: String

(11)

Makro Annotationen

I Idee: FunktionASTAST zur Compilezeit ausführen I Werkzeug: Annotationen

class h e l l o extends StaticAnnotation {

inline def apply ( defn : Any) : Any = meta { defn match { case q" object $name { . . $members }" ⇒

q""" object $name { . . $members

def h e l l o : Unit = p r i n t l n ("Hello" ) }"""

case _⇒ abort ("@h e l l o must annotate an object ") } }

}

(12)

JSON: Zweiter Versuch

JSON2.scala

I Generische Ableitungen fürcase classes

I Funktioniert das für alle algebraischen Datentypen?

(13)

JSON: Zweiter Versuch

JSON2.scala

I Generische Ableitungen fürcase classes

I Funktioniert das für alle algebraischen Datentypen?

(14)

Generische Programmierung

I Beispiel: YAML statt JSON erzeugen

I Idee: Abstraktion über die Struktur von Definitionen I Erster Versuch:ToMap. scala

I Das klappt so nicht . . .

I Keine geeignete Repräsentation!

(15)

Generische Programmierung

I Beispiel: YAML statt JSON erzeugen

I Idee: Abstraktion über die Struktur von Definitionen

I Erster Versuch:ToMap. scala I Das klappt so nicht . . .

I Keine geeignete Repräsentation!

(16)

Heterogene Listen

I Generische Abstraktion von Tupeln

> val l = 42 : : "foo" : : 4.3 : : HNil l : Int : : String : : Double : : HNil = . . .

I Viele Operationen normaler Listen vorhanden:

I Was ist der parameter fürflatMap?

⇒Polymorphe Funktionen

(17)

Heterogene Listen

I Generische Abstraktion von Tupeln

> val l = 42 : : "foo" : : 4.3 : : HNil l : Int : : String : : Double : : HNil = . . .

I Viele Operationen normaler Listen vorhanden:

I Was ist der parameter fürflatMap?

⇒Polymorphe Funktionen

(18)

Records

I Uns fehlen namen I Dafür: Records

> import shapeless ._; record ._; import syntax . singleton ._

> val person = ("name" →> "Donald") : : ("age" →> 70) : : HNil

person : String with KeyTag[ String ("name") , String ] : : Int with KeyTag[ String ("age") , Int ] : : HNil = Donald : : 70

: : HNil

> person ("name") res1 : String = Donald

(19)

Die Typklasse Generic

I Typklasse Generic [T]

t r a i t Generic [T] { type Repr

def from( r : Repr) : T def to ( t : T) : Repr }

I kann magisch abgeleitet werden:

> case class Person(name: String , age : Int )

> val gen = Generic [ Person ]

gen : shapeless . Generic [ Person ]{type Repr = String : : Int : : shapeless . HNil} = . . .

(20)

JSON Serialisierung: Teil 3

JSON3. scala

(21)

Automatische Linsen

case class Address( s t r e e t : String , c i t y : String , zip : Int ) case class Person(name: String , age : Int , address : Address) val streetLens = lens [ Person ] >> ’ address >> ’s t r e e t

(22)

Zusammenfassung

I Meta-Programmierung: “Programme Höherer Ordnung”

I Scalameta: Scala in Scala manipulieren I Quasiquotations: Reify and Splice

I Macros mit Scalameta:ASTAST zur Compilezeit I Äquivalent in Haskell: TemplateHaskell

I Generische Programmierung in Shapeless I Äquivalent in Haskell: GHC.Generic

Referenzen

ÄHNLICHE DOKUMENTE

I Cold Observables fangen erst an Werte zu produzieren, wenn man ihnen zuhört.. Für jeden Observer

[r]

I Promises sind das Gegenstück zu Futures trait Promise {. def complete(result: Try[T]) def

I Werte vom Typ IO (Aktionen) können kombiniert werden wie alle anderen. I

I Aber: zentrales Konzept sind unendliche Listen (Ströme) mit nicht-strikte Auswertung. I Implementation mit Scala-Listen

[r]

I Nachdem onCompleted oder onError aufgerufen wurde wird onNext nicht mehr

I Wenn der Konsument keine Daten mehr annehmen kann soll der Produzent aufhören sie zu Produzieren. I Erste Idee: Wir können den produzierenden