Reaktive Programmierung
Vorlesung 9 vom 17.06.14: Funktional-Reaktive Programmierung
Christoph Lüth & Martin Ring Universität Bremen Sommersemester 2014
1 [12]
Fahrplan
I Teil I: Grundlegende Konzepte I Teil II: Nebenläufigkeit
IFutures and Promises
IReaktive Datenströme I
IReaktive Datenströme II
IFunktional-Reaktive Programmierung
IAktoren
IAktoren und Akka
I Teil III: Fortgeschrittene Konzepte
2 [12]
Das Tagemenü
I Funktional-Reaktive Programmierung(FRP) istreinfunktionale, reaktive Programmierung.
I SehrabstraktesKonzept — im Gegensatz zu Observables und Aktoren.
I Literatur: Paul Hudak,The Haskell School of Expression, Cambridge University Press 2000, Kapitel 13, 15, 17.
I Andere (effizientere) Implementierung existieren.
3 [12]
FRP in a Nutshell
I Zwei Basiskonzepte
I Kontinuierliches, über der Zeit veränderlichesVerhalten:
type Time = F l o a t
type B e h a v i o u r a = Time → a
I Diskrete Ereignissezu einem bestimmten Zeitpunkt:
type E v e n t a = [ ( Time , a ) ]
I Obige Typdefinitionen sindSpezifikation, nichtImplementation
4 [12]
Verhalten: erste einfache Beispiele
I Ein kreisender und ein pulsierender Ball:
c i r c , p u l s e :: B e h a v i o r R e g i o n
c i r c = t r a n s l a t e ( c o s t i m e , s i n t i m e ) ( e l l 0 . 2 0 . 2 ) p u l s e = e l l ( c o s t i m e ∗ 0 . 5 ) ( c o s t i m e ∗ 0 . 5 )
I Was passiert hier?
I Basisverhalten:time :: Behaviour Time,constB:: a→Behavior a
I Grafikbücherei: DatentypRegion, FunktionEllipse
I Liftings (∗,0.5,sin, . . . )
5 [12]
Reaktive Animationen: Verhaltensänderung
I Beispiel: auf Knopfdruck Farbe ändern:
c o l o r 1 :: B e h a v i o r C o l o r
c o l o r 1 = r e d ‘ u n t i l B ‘ l b p − b l u e c o l o r 2 r = r e d ‘ u n t i l B ‘ c e where
c e = ( l b p − b l u e ‘ u n t i l B ‘ c e ) .|. ( k e y − y e l l o w ‘ u n t i l B ‘ c e ) I Was passiert hier?
IuntilBkombiniert Verhalten:
u n t i l B :: B e h a v i o r a → E v e n t ( B e h a v i o r a ) → B e h a v i o r a
I=istmapfür Ereignisse:
(=) :: E v e n t a → ( a→b ) → E v e n t b (− ) :: E v e n t a→ b→ E v e n t b
e − v =e = λ_ → v
IKombination von Ereignissen:
6 [12]
Der Springende Ball
b a l l 2 = p a i n t r e d ( t r a n s l a t e ( x , y ) ( e l l 0 . 2 0 . 2 ) ) where g = −4
x = −3+ i n t e g r a l 0 . 5 y = 1 . 5 + i n t e g r a l v v = i n t e g r a l g ‘ s w i t c h ‘
( h i t ‘ s n a p s h o t _ ‘ v = λv ’→ l i f t 0 (−v ’ ) + i n t e g r a l g ) h i t = when ( y <∗ −1.5)
I Nützliche Funktionen:
i n t e g r a l :: B e h a v i o r F l o a t → B e h a v i o r F l o a t s n a p s h o t :: E v e n t a → B e h a v i o r b → E v e n t ( a , b ) I Erweiterung: Ball ändert Richtung, wenn er gegen die Wand prallt.
7 [12]
Implementation
I Verhalten, erste Annäherung:
data Beh1 a =Beh1 ( [ ( U s e r A c t i o n , Time ) ]→ Time→ a ) I Problem:SpeicherleckundIneffizienz
I Analogie: suche insortiertenListen i n L i s t :: [ I n t ] → I n t → B o o l i n L i s t x s y = e l e m y x s
m a n y I n L i s t ’ :: [ I n t ]→ [ I n t ]→ [ B o o l ] m a n y I n L i s t ’ x s y s =map ( i n L i s t x s ) y s I Besser Sortiertheit direkt nutzen
m a n y I n L i s t :: [ I n t ] → [ I n t ] → [ B o o l ]
8 [12]
Implementation
I Verhalten werdeninkrementell abgetastet:
data Beh2 a
= Beh2 ( [ ( U s e r A c t i o n , Time ) ] → [ Time ] → [ a ] ) I Verbesserungen:
I Zeit doppelt, nureinmal
I Abtastung auchohne Benutzeraktion
I Currying
data B e h a v i o r a
= B e h a v i o r ( ( [ Maybe U s e r A c t i o n ] , [ Time ] ) → [ a ] ) I Ereignisse sind im Prinzipoptionales Verhalten:
data E v e n t a = E v e n t ( B e h a v i o u r ( Maybe a ) )
9 [12]
Längeres Beispiel: Paddleball
I Das Paddel:
p a d d l e = p a i n t r e d ( t r a n s l a t e ( f s t mouse , −1.7) ( r e c 0 . 5 0 . 0 5 ) ) I Der Ball:
p b a l l v e l =
l e t x v e l = v e l ‘ stepAccum ‘ x b o u n c e − n e g a t e x p o s = i n t e g r a l x v e l
x b o u n c e =when ( x p o s >∗ 2 | | ∗ x p o s <∗ −2) y v e l = v e l ‘ stepAccum ‘ y b o u n c e − n e g a t e y p o s = i n t e g r a l y v e l
y b o u n c e =when ( y p o s >∗ 1 . 5
| | ∗ y p o s ‘ between ‘ (−2 . 0 ,−1 . 5 ) &&∗
f s t mouse ‘ between ‘ ( x p o s−0 . 2 5 , x p o s+0 . 2 5 ) ) i n p a i n t y e l l o w ( t r a n s l a t e ( x p o s , y p o s ) ( e l l 0 . 2 0 . 2 ) ) I Die Mauern:
w a l l s :: B e h a v i o r P i c t u r e I . . . und alles zusammen:
p a d d l e b a l l v e l = w a l l s ‘ o v e r ‘ p a d d l e ‘ o v e r ‘ p b a l l v e l
10 [12]
Warum nicht in Scala?
I Lifting und Typklassen fürsyntaktischen Zucker— Traits in Scala
I Aber: zentrales Konzept sindunendlicheListen (Ströme) mit nicht-strikteAuswertung
I Implementation mit Scala-Listen nicht möglich
I Benötigt:Strömeals unendliche Listen mit effizienter, nicht-strikter Auswertung
I Möglich, aber nicht für diese Vorlesung I Generelle Schwäche:
I Fundamentalnicht-kompositional— ist gibteineHauptfunktion
I Fehlerbehandlung, Nebenläufigkeit?
11 [12]
Zusammenfassung
I Funktional-Reaktive Programmierung am Beispiel FAL (Functional Animation Library)
I Zwei Kernkonzepte: kontinuierlichesVerhaltenund diskreteEreignisse
I Implementiert in Haskell, Systemverhalten als unendlicher Strom von Zuständen
I ErlaubtabstrakteProgammierung vonreaktiven Animationen I Problem ist mangelndeKompositionalität
I Nächstes VL: Aktoren
12 [12]