SlideShare ist ein Scribd-Unternehmen logo
Funktionale
reaktive
Programmierung
mit Sodium
Torsten Fink
torsten.fink@akquinet.de
http://viralpatel.net/blogs/lambda-expressions-java-tutorial/
Zu meiner Person
• 2003: Promotion an der FU zum Thema
SW-Architekturen und Verteilte Systeme
• Ab 2004: Berater bei der akquinet
• technischer Architekt in J2EE-Projekten
• Projektleitung
• Betriebsführung, Wartung
• klassische Beratung und Schulungen
• 2006-2010:
Leiter des JBoss-Competence-Centers bei der akquinet
• Ab 2011:
Geschäftsführer der akquinet tech@spree
Meine Firma
Funktionale GUIs – ein Oxymoron ??
Funktionale GUIs – ein Oxymoron?
„Reine funktionale Sprachen (z.B. Haskell)
§haben keine Seiteneffekte
§=> f(x) ist für festes x konstant
„Problematisch sind damit, z.B.
leseDateneingabeVomBenutzer()
leseAktuelleMausposition()
leseFormularfelder()
Dann kam...
„Erste Version: 0.1.0.0 – März 2011
„Aktuelle Version: 1.1.0.1 – Mai 2016
„Nur GUI-Logik, ohne GUI-Anbindung
=> Im Prinzip fertig
„three-penny-gui: Browser als GUI
Reactive Banana
Für Haskell coole GUIs ..
Problem gelöst?
„Prinzipiell schon, aber..
§Framework für Nicht-Haskell-Experten
nicht leicht zugänglich
„Aus einem Tutorial
How?
variation in time as first-class value
type Behavior a = Time → a
type Event a = [(Time, a)]
key data types are Behavior and Event.
vior corresponds to a „value that varies in time“.
t corresponds to „events that occurr at certains points in time“.
Behavior API
instance Applicative Behavior
Functor
instance Functor Behavior
Subjektive Bewertung
„GUI-Problem für funktionale Sprachen damit prinzipiell gelöst.
„Stringente Architektur mit einfachen Primitiven,
§die komplexe
§interaktive und aktive
§Oberflächen ermöglicht.
Parallel/leicht verzögert entwickelte sich ...
„The Reactive Manifesto (V1.0 – 2013, V2.0 - 2014)
https://www.reactivemanifesto.org
§Architekturprinzipien für antwortbereite (responsive),
widerstandsfähige (resilient), elastische, nachrichtenorientierte
Systeme
„Reactive Extensions (Rx)
§Erweiterung von LINQ (Abfragesprache für .NET) für
Ereignissteuerung ohne Rückrufmethoden basierend auf
Observer-Muster
http://reactivex.io/intro.html
(vor 2012 entwickelt, konstante Weiterentwicklung)
Und auch dieses hier...
„Von Stephen Blackheath, Anthony
Jones; 2016
„FRP als Architekturstil
mit Schwerpunkt auf Sodium
=> eigenes Framework
„IMHO:
Erfahrene GUI-Pragmatiker entdecken
FRP im Reactive-Umfeld neu
(späterer Abgleich mit Reactive Banana)
Worum geht es hier?
„Framework
§mit theoretisch beweisbaren
Eigenschaften
§um Fehlerklassen zu eliminieren,
§die bei klassischer Callback-basierten GUIs
auftreten
§unabhängig von GUI-Framework.
„... klingt erstmal nach Elfenbeinturm
Die 6 Plagen der Listener
Aus dem FRP-Buch von
S. Blackheath, A. Jones
entnommen
Unpredictable Order of Events
„Ausführungsreihenfolge von Listenern
hängt ab von Registrierungsreihenfolge
„bei FRP:
§Reihenfolge der Bearbeitung ist nicht
relevant,
§da unabhängige Berechnungen sich
nicht „sehen“
§aufgrund von unveränderbaren Daten
und GUI-TX
Missed First Events
„Problem, dass Events verschickt
werden, bevor alle Listener registriert
sind
(z.B. in der Initialisierungsphase)
„Bei FRP:
Zuerst werden alle “Listener“
konfiguriert, bevor Events verschickt
werden
Messy State
„Listener-basierter Code orientiert sich
üblicherweise an Zustandsmaschinen
(z.B. Entität unverändert/verändert,
Feld gültig/ungültig)
„Dieser ist mit Zustand und
Zustandsübergängen im Code sehr
verteilt und wird schnell unwartbar
„Bei FRP:
Funktionales Ordnen von Zuständen
und Übergängen
Threading Issues
„Gefahr von Deadlock in einem
Multihreading-System
„Bei FRP
§keine inhärenten Listener, sondern
Event-Ströme, die sich nicht in die
Quere kommen können
§+ Immutable State, so dass keine
Synchronisierung notwendig ist
(innerhalb des FRPs)
Leaking Callbacks
„Speicherlöcher durch nicht
deregistrierte Listener
„Registrierung von Listenern ist schon
schwierig, umso mehr die
Deregistrierung
„Bei FRP
keine Listener, sondern Event-Ströme,
die in Gänze aus dem Scope fallen und
aufgeräumt werden
Accidental Recursion
„Die Reihenfolge, in der Zustand verändert
wird und Events ausgelöst werden, ist
wichtig, Fehler können zu Endlosschleifen
und Inkonsistenzen führen.
„Bei FRP:
§komplette Analyse der Eventströme
§+ Transaktionsmodell
§= keine Rekursion/Zyklen, keine
Inkonsistenzen
Ich will
Code !!!
Die zwei Basiselemente von Sodium
„Zellen (Cell<T>)
§Speichern/Verwalten von Zustand, der sich über
Zeit ändert
(alle anderen Daten/Objekte sind unveränderbar)
§Hält ein Element vom Typ T
„Ströme (Stream<T>)
§Verwalten von Aktivitäten
§Überträgt ein Ereignis vom Typ T
Zelle
Strom
Der Taschenrechner
„War zu optimistische Übungsaufgabe in Java
„Fähigkeiten
§Eingabe von Zahlen
§Mehrstufige Additionen und Subtraktionen
§Abschluss einer Berechnung
„GUI in Java FX
„Der Code:
https://github.com/akquinet/sodiumcalculat
or
Die (grobe) Architektur
„CalculatorView
§Erzeugt GUI
§Delegiert Aktionen an den Controller
§Angemeldet an der DisplayCell für die
Darstellung der Anzeige
„CalculatorController
§GUI – Status
§GUI – Logik
Ankopplung von FRP mit Sodium
„ Registrieren an einer Zelle in der GUI
// Bibliothek für Hilfsfunktionen außerhalb FRP
Operational
// Konvertiert Cell in Strom von Zuständen
.updates(controller.getDisplayCell())
// registriert Listener
.listen(v -> displayTF.setText("" + v));
„ Senden von Ereignissen außerhalb FRP
void pressDigit(Long digit) {
clickedDigitS.send(digit);
}
„ Achtung: Dies hier ist außerhalb von FRP, die
6 Plagen existieren hier.
Feature 1: Die Anzeige
„Zelle Display – hält den Wert, der angezeigt werden soll
„Klick auf Taste dig: display -> display*10+dig
“3“ “2“
In FRP als Diagramm – Schritt 1
„Anwender drückt eine Zahl 3, diese wird von außen reingegeben
„TX startet, 3 wird propagiert
displayC
clickedDigitS updatedEnteredNumberS
3 3
In FRP als Diagramm – Schritt 2
„Nächster Strom bekommt die 3, holt sich den aktuellen Zustand
aus Display, verknüpft beide über eine Berechnung
displayC
clickedDigitS updatedEnteredNumberS
3
0
0*10 + 3
3
In FRP als Diagramm – Schritt 3
„Ende der Transaktion, Ergebnis wird in Zelle gespeichert
„Externe Listener werden benachrichtigt
displayC
clickedDigitS updatedEnteredNumberS
3
Berechnung als programmatische Konfiguration
„updatedEnteredNumberS =
clickedDigitS.snapshot(displayC,
(digit, display) -> display * 10 + digit);
displayC
clickedDigitS updatedEnteredNumberS
display * 10 + digit
In Gänze mit Schleife
„displayC = new CellLoop<>();
updatedEnteredNumberS = ...; // vorherige Folie
displayC.loop(updatedEnteredNumberS.hold(0L));
displayC
clickedDigitS updatedEnteredNumberS
displayC ist
immer
definiert
Feature 2: Mehrfaches Plus
„Ist nur mit Display
nicht möglich
„IMHO: 2 Register
123 + 2 +
Mit zwei Register: Main und Back
123 + 2 +
m=0
b=0
m=123
b=0
m=0
b=123
m=2
b=123
m=0
b=125
In FRP als Diagramm
displayC
clickedDigitS updatedEnteredNumberS
clickedPlusS
mainC
backC
:CombinedState
updateStateFromPlusS
Das hier ist die
fachliche Komplexität
des halben Rechners
=>
Er ist tatsächlich nicht
so einfach.
Lift: Abgeleitete Zustände
„class CombinedState {
final Long display;
final Long back;
final Long main;
CombinedState(Long display,
Long main, Long back) {...}
}
„final Cell<CombinedState> calculatorStateC =
displayC.lift(mainC, backC,
CombinedState::new);
displayC
mainC
backC
:CombinedState
Die Berechnung bei Plus
„final Stream<CombinedState> updatedStateFromPlusS =
clickedPlusS.snapshot(
calculatorStateC, (unit, state) -> {
Long result = state.main + state.back;
return new CombinedState(result, 0L, result);
});
clickedPlusS
calculatorStateC:CombinedState
updateStateFromPlusS
Anpassung des Hintergrundregister
„backC.loop(
updatedStateFromPlusS
.map(s -> s.back)
.hold(0L));
backCcalculatorStateC
updateStateFromPlusS
Anpassung der Anzeige
„displayC.loop(
updatedEnteredNumberS
.orElse(updatedStateFromPlusS
.map(s -> s.display))
.hold(0L));
displayC
clickedDigitS updatedEnteredNumberS
updateStateFromPlusS
Analog das Main-Register
Finale Ausbaustufe
„Mit
§zusätzlicher „-“ Operation
§ „=“ Taste für Abschluss von Berechnungen
„Code hier mal ausgelassen
(als Übung für den interessierten Zuhörer :-)
Vergleich der LOCs pro Ausbaustufe
„Gemessen wurde der Controller nicht die GUI (86 LOC)
„LOCs steigen „vernünftig“ mit der fachlichen Komplexität (Anstieg
zwischen „Addition“ und „Finale“ ist erstaunlich gering)
„Code lässt sich IMHO gut refactoren bei neuen Anforderungen
0
20
40
60
80
100
120
LOC
Anzeige Addition Finale
Testen lässt es sich auch
„@Test
void pressDigit123() {
calculatorController.pressDigit(1L);
calculatorController.pressDigit(2L);
calculatorController.pressDigit(3L);
assertEquals(Long.valueOf(123L), getDisplay());
}
„private Long getDisplay() {
return calculatorController
.getDisplayCell().sample();
}
Was soll
ich mit
JavaFX?
... Ich will Web!
„Sodium ist Framework-unabhängig.
„Hier der Taschenrechner mit
§Typescript + Sodium + Angular
https://blog.akquinet.de/2018/06/24/functional-reactive-
programming-with-angular-and-sodium/
(etwas komplexer, um Komponententauglichkeit zu evaluieren.)
Ok, genug Code
...
Vielleicht noch ein
paar allgemeine
Dinge
GUI Transaktionen
Meistens ist es einfach....
Manchmal aber nicht ...
Nebenläufige Verarbeitung
Unbestimmte
Reihenfolge
der
Bearbeitung
Auf welchen Modellen?
Nichtdisjunkte
Operationen =>
Fehler
Was sieht der Nutzer?
Evtl. Flackern,
Falsches finales
Modell
Jetzt mit Transaktionen in Sodium
Jetzt mit Transaktionen in Sodium
Ausführungs-
reihenfolge
irrelevant,
weil ...
Operationen greifen auf altes Modell zu
Ergebnisse
anderer
Operationen
werden nicht
gesehen
... und festschreiben ...
Reihenfolge egal,
durch
Zusammenfüh-
rung von
Ereignissen
Was der User sieht ....
Kein Flackern,
deterministischer
Zustand
Transaktionen in der GUI - Kommentare
„Start von Transaktionen
§Automatisch, wenn extern ein Ereignis erzeugt wird
§Oder händisch über Transaction Bibliotheksklasse
„Zusammenfassung über Events durch:
// Kombinationsfunktion, falls beide Streams einen Event anbieten
s1.merge(s2, (l,r) -> l)
// Kurzschreibweise für oben
s1.orElse(s2)
Threading
Geschenke durch Funktionale Programmierung
„Referenzielle Transparenz reduziert Threading-
Probleme
„FRP
§analysiert Abhängigkeiten
§arbeitet diese sequenziell ab
§und hat daher keine Nebenläufigkeitsprobleme
Herausforderungen der Nicht-FP-Welt
„Einstieg in FRP über send()
void pressDigit(Long digit) {
clickedDigitS.send(digit);
}
Aus welchen Threads ist der Aufruf erlaubt?
„Ausstieg aus FRP über Listener
Operational
.updates(displayC)
.listen(displayListener);
Was dürfen die Listener und in welchem Thread laufen sie?
Die Regeln
„Sodiums Threading-Eigenschaften
§ send() kann aus (fast) jedem Kontext ausgeführt werden, ohne zu
blockieren
§ Ausführung der Listeners auf dem Thread, der send() ausgeführt
hat
„Regeln von Sodium für (externe) Listeners
§ Kein Aufruf von send()
§ Keine blockierende Operation (muss an anderen Thread delegiert
werden)
„Zusammengefasst: Externer Code kümmert sich um Threading (z.B. Mit
klassichen Workern)
Was ist mit RX?
RX ist überall
„Kontinuierliche Weiterentwicklung
„Z.B. direkt in Angular eingebaut.
„Aus unserer Erfahrung häufig verwirrend, z.B.
§ Hot (Event-Weiterleitung)
vs.
Cold (Kapselung eines Stream-Erzeugers)
§ Life-Cycle-Callbacks (next(), error(), complete())
§ Menge an Funktionalitäten
RX-Subject (~ 125 Methoden)
vs.
Sodium-Stream (~25 Methoden)
RxJs und FRP
„Keine klare Trennung zwischen der „reinen“ FRP Welt und dem Rest
des Codes
=> keine FRP-Kompositionseigenschaften
(man verliert leicht schöne Eigenschaften, s. die 6 Plagen)
„RxJs bietet viele unterschiedliche Dinge, insb. I/O Unterstützung,
Threading aber auch Rechenfunktionalität (Listenverarbeitung über
Cold-Observables)
„RxJs hat kein Transaktionskonzept und keine erzwungene
Zusammenführung für gleichzeitige Ereignisse
„Mit einem Subset von Rx lässt sich FRP-ähnlich entwickeln. (Stream =
Hot Observable, BehaviorSubject = Cell)
Kommentare zu Sodium
Der äußere Eindruck
„Bescheidener Webauftritt
(altertümliches, aber gut funktionierendes Forum +GitHub)
Unterstützte Sprachen:
„C#, Typescript
aktive Weiterentwicklung
„Java, Clojure
Wartungsmodus
„Haskell, Rust, C++
keine Weiterentwicklung
„Rust, C , Kotlin
experimental
Persönliche Bewertung
„Nach
§ Einigen explorativen Fingerübungen (JavaFX, Angular/TS)
§ Einem Swing-Portal für eine Mikroservicearchitektur
„Gefühl
§ Ausgereiftes, abgeschlossenes Framework
=> kein aufgetretenes Problem lag an Sodium
§ Einarbeitung benötigte kurzes Umdenken, dann war es einfach.
(Vorbedingung: Grundlagen funktionaler Programmierung)
§ Trennung von konkretem GUI-Framework fühlte sich gut an.
Dennoch: Eine Integration könnte den Komfort erhöhen.
Alles gut?
Mal
zusammengefasst
Die letzte Folie
„Functional Reactive Programming
ist ein stringentes Programmiermodell
für GUIs
mit schönen Eigenschaften
„Sodium
hat bis jetzt einen stabilen und vollständigen Eindruck und Spaß
gemacht.
„Listeners sind out.
„Und, ja, wir sind auch auf der Suche nach neuen Kollegen :-)

Weitere ähnliche Inhalte

Ähnlich wie Funktionale Reaktive Programmierung mit Sodium

OSMC 2010 | Java Monitoring und Troubleshooting by Rainer Jung
OSMC 2010 | Java Monitoring und Troubleshooting by Rainer JungOSMC 2010 | Java Monitoring und Troubleshooting by Rainer Jung
OSMC 2010 | Java Monitoring und Troubleshooting by Rainer Jung
NETWAYS
 
Werkzeugkasten
WerkzeugkastenWerkzeugkasten
Werkzeugkasten
Hendrik Lösch
 
Metaprogrammierung und Reflection
Metaprogrammierung und ReflectionMetaprogrammierung und Reflection
Metaprogrammierung und ReflectionStefan Marr
 
Opensource Tools für das Data Center Management
Opensource Tools für das Data Center ManagementOpensource Tools für das Data Center Management
Opensource Tools für das Data Center Management
inovex GmbH
 
Production-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenProduction-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 Wochen
André Goliath
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
jlink
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
GFU Cyrus AG
 
Icsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratoren
Icsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratorenIcsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratoren
Icsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratoren
ICS User Group
 
Java Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s StapelnJava Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s Stapeln
gedoplan
 
Forms and Reports 12c - Processes and Automation in Development and Operations
Forms and Reports 12c - Processes and Automation in Development and OperationsForms and Reports 12c - Processes and Automation in Development and Operations
Forms and Reports 12c - Processes and Automation in Development and Operations
Torsten Kleiber
 
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Marc Müller
 
2009 03 17 Spring101
2009 03 17 Spring1012009 03 17 Spring101
2009 03 17 Spring101gueste4be40
 
Neue Features der Java EE 6
Neue Features der Java EE 6Neue Features der Java EE 6
Neue Features der Java EE 6
GFU Cyrus AG
 
TYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerkTYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerk
die.agilen GmbH
 
JSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederJSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael Greifeneder
Christoph Pickl
 
Bkr Workflow Oeffentlich
Bkr Workflow OeffentlichBkr Workflow Oeffentlich
Bkr Workflow Oeffentlich
Ralf Ruethlein
 
bccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-admins
bccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-adminsbccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-admins
bccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-admins
ICS User Group
 
Tipps und Skripts aus dem Leben eines Connections Admins
Tipps und Skripts aus dem Leben eines Connections AdminsTipps und Skripts aus dem Leben eines Connections Admins
Tipps und Skripts aus dem Leben eines Connections Admins
Klaus Bild
 
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG KonferenzDomino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
panagenda
 

Ähnlich wie Funktionale Reaktive Programmierung mit Sodium (20)

Feature Flags mit Togglz
Feature Flags mit TogglzFeature Flags mit Togglz
Feature Flags mit Togglz
 
OSMC 2010 | Java Monitoring und Troubleshooting by Rainer Jung
OSMC 2010 | Java Monitoring und Troubleshooting by Rainer JungOSMC 2010 | Java Monitoring und Troubleshooting by Rainer Jung
OSMC 2010 | Java Monitoring und Troubleshooting by Rainer Jung
 
Werkzeugkasten
WerkzeugkastenWerkzeugkasten
Werkzeugkasten
 
Metaprogrammierung und Reflection
Metaprogrammierung und ReflectionMetaprogrammierung und Reflection
Metaprogrammierung und Reflection
 
Opensource Tools für das Data Center Management
Opensource Tools für das Data Center ManagementOpensource Tools für das Data Center Management
Opensource Tools für das Data Center Management
 
Production-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenProduction-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 Wochen
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
Icsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratoren
Icsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratorenIcsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratoren
Icsug conf 14_tipps-und-skripts-fuer-ibm-connections-administratoren
 
Java Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s StapelnJava Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s Stapeln
 
Forms and Reports 12c - Processes and Automation in Development and Operations
Forms and Reports 12c - Processes and Automation in Development and OperationsForms and Reports 12c - Processes and Automation in Development and Operations
Forms and Reports 12c - Processes and Automation in Development and Operations
 
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
 
2009 03 17 Spring101
2009 03 17 Spring1012009 03 17 Spring101
2009 03 17 Spring101
 
Neue Features der Java EE 6
Neue Features der Java EE 6Neue Features der Java EE 6
Neue Features der Java EE 6
 
TYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerkTYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerk
 
JSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederJSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael Greifeneder
 
Bkr Workflow Oeffentlich
Bkr Workflow OeffentlichBkr Workflow Oeffentlich
Bkr Workflow Oeffentlich
 
bccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-admins
bccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-adminsbccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-admins
bccon-2014 adm01 tipps-und-skripts-aus-dem-leben-eines-ibm-connections-admins
 
Tipps und Skripts aus dem Leben eines Connections Admins
Tipps und Skripts aus dem Leben eines Connections AdminsTipps und Skripts aus dem Leben eines Connections Admins
Tipps und Skripts aus dem Leben eines Connections Admins
 
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG KonferenzDomino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
 

Mehr von Torsten Fink

MEAN SCS in der Cloud
MEAN SCS in der CloudMEAN SCS in der Cloud
MEAN SCS in der Cloud
Torsten Fink
 
Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...
Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...
Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...
Torsten Fink
 
Docker in der Anwendungsentwicklung
Docker in der AnwendungsentwicklungDocker in der Anwendungsentwicklung
Docker in der Anwendungsentwicklung
Torsten Fink
 
Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...
Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...
Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...
Torsten Fink
 
OptaPlanner hilft bei verteilten Schulstandorten
OptaPlanner hilft bei verteilten SchulstandortenOptaPlanner hilft bei verteilten Schulstandorten
OptaPlanner hilft bei verteilten Schulstandorten
Torsten Fink
 
JSF Anwendungen testen mit AcceptIt
JSF Anwendungen testen mit AcceptItJSF Anwendungen testen mit AcceptIt
JSF Anwendungen testen mit AcceptIt
Torsten Fink
 
Haskell aus einer Java EE Perspektive
Haskell aus einer Java EE PerspektiveHaskell aus einer Java EE Perspektive
Haskell aus einer Java EE Perspektive
Torsten Fink
 

Mehr von Torsten Fink (7)

MEAN SCS in der Cloud
MEAN SCS in der CloudMEAN SCS in der Cloud
MEAN SCS in der Cloud
 
Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...
Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...
Open Source als Innovator und Treiber von De‐Facto Standards für das Internet...
 
Docker in der Anwendungsentwicklung
Docker in der AnwendungsentwicklungDocker in der Anwendungsentwicklung
Docker in der Anwendungsentwicklung
 
Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...
Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...
Security in Rechenzentren und Fabriken - Ansätze und Parallelen für Industrie...
 
OptaPlanner hilft bei verteilten Schulstandorten
OptaPlanner hilft bei verteilten SchulstandortenOptaPlanner hilft bei verteilten Schulstandorten
OptaPlanner hilft bei verteilten Schulstandorten
 
JSF Anwendungen testen mit AcceptIt
JSF Anwendungen testen mit AcceptItJSF Anwendungen testen mit AcceptIt
JSF Anwendungen testen mit AcceptIt
 
Haskell aus einer Java EE Perspektive
Haskell aus einer Java EE PerspektiveHaskell aus einer Java EE Perspektive
Haskell aus einer Java EE Perspektive
 

Funktionale Reaktive Programmierung mit Sodium

  • 2. Zu meiner Person • 2003: Promotion an der FU zum Thema SW-Architekturen und Verteilte Systeme • Ab 2004: Berater bei der akquinet • technischer Architekt in J2EE-Projekten • Projektleitung • Betriebsführung, Wartung • klassische Beratung und Schulungen • 2006-2010: Leiter des JBoss-Competence-Centers bei der akquinet • Ab 2011: Geschäftsführer der akquinet tech@spree
  • 4. Funktionale GUIs – ein Oxymoron ??
  • 5. Funktionale GUIs – ein Oxymoron? „Reine funktionale Sprachen (z.B. Haskell) §haben keine Seiteneffekte §=> f(x) ist für festes x konstant „Problematisch sind damit, z.B. leseDateneingabeVomBenutzer() leseAktuelleMausposition() leseFormularfelder()
  • 6. Dann kam... „Erste Version: 0.1.0.0 – März 2011 „Aktuelle Version: 1.1.0.1 – Mai 2016 „Nur GUI-Logik, ohne GUI-Anbindung => Im Prinzip fertig „three-penny-gui: Browser als GUI Reactive Banana
  • 8. Problem gelöst? „Prinzipiell schon, aber.. §Framework für Nicht-Haskell-Experten nicht leicht zugänglich „Aus einem Tutorial How? variation in time as first-class value type Behavior a = Time → a type Event a = [(Time, a)] key data types are Behavior and Event. vior corresponds to a „value that varies in time“. t corresponds to „events that occurr at certains points in time“. Behavior API instance Applicative Behavior Functor instance Functor Behavior
  • 9. Subjektive Bewertung „GUI-Problem für funktionale Sprachen damit prinzipiell gelöst. „Stringente Architektur mit einfachen Primitiven, §die komplexe §interaktive und aktive §Oberflächen ermöglicht.
  • 10. Parallel/leicht verzögert entwickelte sich ... „The Reactive Manifesto (V1.0 – 2013, V2.0 - 2014) https://www.reactivemanifesto.org §Architekturprinzipien für antwortbereite (responsive), widerstandsfähige (resilient), elastische, nachrichtenorientierte Systeme „Reactive Extensions (Rx) §Erweiterung von LINQ (Abfragesprache für .NET) für Ereignissteuerung ohne Rückrufmethoden basierend auf Observer-Muster http://reactivex.io/intro.html (vor 2012 entwickelt, konstante Weiterentwicklung)
  • 11. Und auch dieses hier... „Von Stephen Blackheath, Anthony Jones; 2016 „FRP als Architekturstil mit Schwerpunkt auf Sodium => eigenes Framework „IMHO: Erfahrene GUI-Pragmatiker entdecken FRP im Reactive-Umfeld neu (späterer Abgleich mit Reactive Banana)
  • 12. Worum geht es hier? „Framework §mit theoretisch beweisbaren Eigenschaften §um Fehlerklassen zu eliminieren, §die bei klassischer Callback-basierten GUIs auftreten §unabhängig von GUI-Framework. „... klingt erstmal nach Elfenbeinturm
  • 13. Die 6 Plagen der Listener Aus dem FRP-Buch von S. Blackheath, A. Jones entnommen
  • 14. Unpredictable Order of Events „Ausführungsreihenfolge von Listenern hängt ab von Registrierungsreihenfolge „bei FRP: §Reihenfolge der Bearbeitung ist nicht relevant, §da unabhängige Berechnungen sich nicht „sehen“ §aufgrund von unveränderbaren Daten und GUI-TX
  • 15. Missed First Events „Problem, dass Events verschickt werden, bevor alle Listener registriert sind (z.B. in der Initialisierungsphase) „Bei FRP: Zuerst werden alle “Listener“ konfiguriert, bevor Events verschickt werden
  • 16. Messy State „Listener-basierter Code orientiert sich üblicherweise an Zustandsmaschinen (z.B. Entität unverändert/verändert, Feld gültig/ungültig) „Dieser ist mit Zustand und Zustandsübergängen im Code sehr verteilt und wird schnell unwartbar „Bei FRP: Funktionales Ordnen von Zuständen und Übergängen
  • 17. Threading Issues „Gefahr von Deadlock in einem Multihreading-System „Bei FRP §keine inhärenten Listener, sondern Event-Ströme, die sich nicht in die Quere kommen können §+ Immutable State, so dass keine Synchronisierung notwendig ist (innerhalb des FRPs)
  • 18. Leaking Callbacks „Speicherlöcher durch nicht deregistrierte Listener „Registrierung von Listenern ist schon schwierig, umso mehr die Deregistrierung „Bei FRP keine Listener, sondern Event-Ströme, die in Gänze aus dem Scope fallen und aufgeräumt werden
  • 19. Accidental Recursion „Die Reihenfolge, in der Zustand verändert wird und Events ausgelöst werden, ist wichtig, Fehler können zu Endlosschleifen und Inkonsistenzen führen. „Bei FRP: §komplette Analyse der Eventströme §+ Transaktionsmodell §= keine Rekursion/Zyklen, keine Inkonsistenzen
  • 21. Die zwei Basiselemente von Sodium „Zellen (Cell<T>) §Speichern/Verwalten von Zustand, der sich über Zeit ändert (alle anderen Daten/Objekte sind unveränderbar) §Hält ein Element vom Typ T „Ströme (Stream<T>) §Verwalten von Aktivitäten §Überträgt ein Ereignis vom Typ T Zelle Strom
  • 22. Der Taschenrechner „War zu optimistische Übungsaufgabe in Java „Fähigkeiten §Eingabe von Zahlen §Mehrstufige Additionen und Subtraktionen §Abschluss einer Berechnung „GUI in Java FX „Der Code: https://github.com/akquinet/sodiumcalculat or
  • 23. Die (grobe) Architektur „CalculatorView §Erzeugt GUI §Delegiert Aktionen an den Controller §Angemeldet an der DisplayCell für die Darstellung der Anzeige „CalculatorController §GUI – Status §GUI – Logik
  • 24. Ankopplung von FRP mit Sodium „ Registrieren an einer Zelle in der GUI // Bibliothek für Hilfsfunktionen außerhalb FRP Operational // Konvertiert Cell in Strom von Zuständen .updates(controller.getDisplayCell()) // registriert Listener .listen(v -> displayTF.setText("" + v)); „ Senden von Ereignissen außerhalb FRP void pressDigit(Long digit) { clickedDigitS.send(digit); } „ Achtung: Dies hier ist außerhalb von FRP, die 6 Plagen existieren hier.
  • 25. Feature 1: Die Anzeige „Zelle Display – hält den Wert, der angezeigt werden soll „Klick auf Taste dig: display -> display*10+dig “3“ “2“
  • 26. In FRP als Diagramm – Schritt 1 „Anwender drückt eine Zahl 3, diese wird von außen reingegeben „TX startet, 3 wird propagiert displayC clickedDigitS updatedEnteredNumberS 3 3
  • 27. In FRP als Diagramm – Schritt 2 „Nächster Strom bekommt die 3, holt sich den aktuellen Zustand aus Display, verknüpft beide über eine Berechnung displayC clickedDigitS updatedEnteredNumberS 3 0 0*10 + 3 3
  • 28. In FRP als Diagramm – Schritt 3 „Ende der Transaktion, Ergebnis wird in Zelle gespeichert „Externe Listener werden benachrichtigt displayC clickedDigitS updatedEnteredNumberS 3
  • 29. Berechnung als programmatische Konfiguration „updatedEnteredNumberS = clickedDigitS.snapshot(displayC, (digit, display) -> display * 10 + digit); displayC clickedDigitS updatedEnteredNumberS display * 10 + digit
  • 30. In Gänze mit Schleife „displayC = new CellLoop<>(); updatedEnteredNumberS = ...; // vorherige Folie displayC.loop(updatedEnteredNumberS.hold(0L)); displayC clickedDigitS updatedEnteredNumberS displayC ist immer definiert
  • 31. Feature 2: Mehrfaches Plus „Ist nur mit Display nicht möglich „IMHO: 2 Register 123 + 2 +
  • 32. Mit zwei Register: Main und Back 123 + 2 + m=0 b=0 m=123 b=0 m=0 b=123 m=2 b=123 m=0 b=125
  • 33. In FRP als Diagramm displayC clickedDigitS updatedEnteredNumberS clickedPlusS mainC backC :CombinedState updateStateFromPlusS Das hier ist die fachliche Komplexität des halben Rechners => Er ist tatsächlich nicht so einfach.
  • 34. Lift: Abgeleitete Zustände „class CombinedState { final Long display; final Long back; final Long main; CombinedState(Long display, Long main, Long back) {...} } „final Cell<CombinedState> calculatorStateC = displayC.lift(mainC, backC, CombinedState::new); displayC mainC backC :CombinedState
  • 35. Die Berechnung bei Plus „final Stream<CombinedState> updatedStateFromPlusS = clickedPlusS.snapshot( calculatorStateC, (unit, state) -> { Long result = state.main + state.back; return new CombinedState(result, 0L, result); }); clickedPlusS calculatorStateC:CombinedState updateStateFromPlusS
  • 36. Anpassung des Hintergrundregister „backC.loop( updatedStateFromPlusS .map(s -> s.back) .hold(0L)); backCcalculatorStateC updateStateFromPlusS
  • 37. Anpassung der Anzeige „displayC.loop( updatedEnteredNumberS .orElse(updatedStateFromPlusS .map(s -> s.display)) .hold(0L)); displayC clickedDigitS updatedEnteredNumberS updateStateFromPlusS Analog das Main-Register
  • 38. Finale Ausbaustufe „Mit §zusätzlicher „-“ Operation § „=“ Taste für Abschluss von Berechnungen „Code hier mal ausgelassen (als Übung für den interessierten Zuhörer :-)
  • 39. Vergleich der LOCs pro Ausbaustufe „Gemessen wurde der Controller nicht die GUI (86 LOC) „LOCs steigen „vernünftig“ mit der fachlichen Komplexität (Anstieg zwischen „Addition“ und „Finale“ ist erstaunlich gering) „Code lässt sich IMHO gut refactoren bei neuen Anforderungen 0 20 40 60 80 100 120 LOC Anzeige Addition Finale
  • 40. Testen lässt es sich auch „@Test void pressDigit123() { calculatorController.pressDigit(1L); calculatorController.pressDigit(2L); calculatorController.pressDigit(3L); assertEquals(Long.valueOf(123L), getDisplay()); } „private Long getDisplay() { return calculatorController .getDisplayCell().sample(); }
  • 42. ... Ich will Web! „Sodium ist Framework-unabhängig. „Hier der Taschenrechner mit §Typescript + Sodium + Angular https://blog.akquinet.de/2018/06/24/functional-reactive- programming-with-angular-and-sodium/ (etwas komplexer, um Komponententauglichkeit zu evaluieren.)
  • 43. Ok, genug Code ... Vielleicht noch ein paar allgemeine Dinge
  • 45. Meistens ist es einfach....
  • 49. Was sieht der Nutzer? Evtl. Flackern, Falsches finales Modell
  • 51. Jetzt mit Transaktionen in Sodium Ausführungs- reihenfolge irrelevant, weil ...
  • 52. Operationen greifen auf altes Modell zu Ergebnisse anderer Operationen werden nicht gesehen
  • 53. ... und festschreiben ... Reihenfolge egal, durch Zusammenfüh- rung von Ereignissen
  • 54. Was der User sieht .... Kein Flackern, deterministischer Zustand
  • 55. Transaktionen in der GUI - Kommentare „Start von Transaktionen §Automatisch, wenn extern ein Ereignis erzeugt wird §Oder händisch über Transaction Bibliotheksklasse „Zusammenfassung über Events durch: // Kombinationsfunktion, falls beide Streams einen Event anbieten s1.merge(s2, (l,r) -> l) // Kurzschreibweise für oben s1.orElse(s2)
  • 57. Geschenke durch Funktionale Programmierung „Referenzielle Transparenz reduziert Threading- Probleme „FRP §analysiert Abhängigkeiten §arbeitet diese sequenziell ab §und hat daher keine Nebenläufigkeitsprobleme
  • 58. Herausforderungen der Nicht-FP-Welt „Einstieg in FRP über send() void pressDigit(Long digit) { clickedDigitS.send(digit); } Aus welchen Threads ist der Aufruf erlaubt? „Ausstieg aus FRP über Listener Operational .updates(displayC) .listen(displayListener); Was dürfen die Listener und in welchem Thread laufen sie?
  • 59. Die Regeln „Sodiums Threading-Eigenschaften § send() kann aus (fast) jedem Kontext ausgeführt werden, ohne zu blockieren § Ausführung der Listeners auf dem Thread, der send() ausgeführt hat „Regeln von Sodium für (externe) Listeners § Kein Aufruf von send() § Keine blockierende Operation (muss an anderen Thread delegiert werden) „Zusammengefasst: Externer Code kümmert sich um Threading (z.B. Mit klassichen Workern)
  • 60. Was ist mit RX?
  • 61. RX ist überall „Kontinuierliche Weiterentwicklung „Z.B. direkt in Angular eingebaut. „Aus unserer Erfahrung häufig verwirrend, z.B. § Hot (Event-Weiterleitung) vs. Cold (Kapselung eines Stream-Erzeugers) § Life-Cycle-Callbacks (next(), error(), complete()) § Menge an Funktionalitäten RX-Subject (~ 125 Methoden) vs. Sodium-Stream (~25 Methoden)
  • 62. RxJs und FRP „Keine klare Trennung zwischen der „reinen“ FRP Welt und dem Rest des Codes => keine FRP-Kompositionseigenschaften (man verliert leicht schöne Eigenschaften, s. die 6 Plagen) „RxJs bietet viele unterschiedliche Dinge, insb. I/O Unterstützung, Threading aber auch Rechenfunktionalität (Listenverarbeitung über Cold-Observables) „RxJs hat kein Transaktionskonzept und keine erzwungene Zusammenführung für gleichzeitige Ereignisse „Mit einem Subset von Rx lässt sich FRP-ähnlich entwickeln. (Stream = Hot Observable, BehaviorSubject = Cell)
  • 64. Der äußere Eindruck „Bescheidener Webauftritt (altertümliches, aber gut funktionierendes Forum +GitHub)
  • 65. Unterstützte Sprachen: „C#, Typescript aktive Weiterentwicklung „Java, Clojure Wartungsmodus „Haskell, Rust, C++ keine Weiterentwicklung „Rust, C , Kotlin experimental
  • 66. Persönliche Bewertung „Nach § Einigen explorativen Fingerübungen (JavaFX, Angular/TS) § Einem Swing-Portal für eine Mikroservicearchitektur „Gefühl § Ausgereiftes, abgeschlossenes Framework => kein aufgetretenes Problem lag an Sodium § Einarbeitung benötigte kurzes Umdenken, dann war es einfach. (Vorbedingung: Grundlagen funktionaler Programmierung) § Trennung von konkretem GUI-Framework fühlte sich gut an. Dennoch: Eine Integration könnte den Komfort erhöhen.
  • 68. Die letzte Folie „Functional Reactive Programming ist ein stringentes Programmiermodell für GUIs mit schönen Eigenschaften „Sodium hat bis jetzt einen stabilen und vollständigen Eindruck und Spaß gemacht. „Listeners sind out. „Und, ja, wir sind auch auf der Suche nach neuen Kollegen :-)