JVM Functional Language Battle

Werbung
JVM Functional
Language Battle
Orientation in Objects GmbH
Weinheimer Str. 68
68309 Mannheim
Version: 1.0
www.oio.de
[email protected]
Ihr Sprecher
Falk Sippach (@sippsack)
Trainer, Berater, Entwickler
Co-Organisator
© Orientation in Objects GmbH
Architektur
Agile Softwareentwicklung
Codequalität
JVM Functional Language Battle
2
Java, XML und Open Source seit 1998
) Software Factory )
) Object Rangers )
• Schlüsselfertige Realisierung
von Java Software
• Unterstützung laufender
• Individualsoftware
• Pilot- und Migrationsprojekte
• Sanierung von Software
• Software Wartung
• Perfect Match
• Rent-a-team
• Coaching on the project
• Inhouse Outsourcing
© Orientation in Objects GmbH
Java Projekte
) Competence Center)
• Schulungen, Coaching,
Weiterbildungsberatung,
Train & Solve-Programme
• Methoden, Standards und
Tools für die Entwicklung
von offenen, unternehmensweiten Systemen
JVM Functional Language Battle
3
Abstract
Funktionale Programmierung soll so viel ausdrucksstärker sein, aber
leider ist dieses Programmier-Paradigma nicht ganz kompatibel zu der
prozedural- und objektorientierten Denkweise von uns Java-Entwicklern.
Anhand eines kleinen Algorithmus werden wir uns verschiedene Lösungen
zunächst im klassischem imperativen Java (vor Java 8) und als Vergleich
dazu in alternativen JVM-Sprachen (Groovy, Frege, ggf. Scala bzw.
JavaScript) anschauen und die verschiedenen Lösungen diskutieren.
Herauskommen soll eine saubere und verständlichere Struktur, die zu
besser les- und wartbarem Code führen wird. Die gewonnenen
Erkenntnisse wollen wir dann letztendlich in Java 8 mittels Streams und
Lambda-Ausdrücken umsetzen, so dass jeder Zuhörer die Grundideen der
funktionalen Programmierung mit in seine tägliche Arbeit nehmen kann.
Es sind keine speziellen Vorkenntnisse in den angesprochenen
alternativen Sprachen notwendig, ein solides Verständnis für die
Programmiersprache Java genügt.
© Orientation in Objects GmbH
JVM Functional Language Battle
4
Agenda
<x>
<y/>
</x>
Einführung
© Orientation in Objects GmbH
Imperativ
Deklarativ
JVM Functional Language Battle
Functional
Java
5
Experiment
© Orientation in Objects GmbH
JVM Functional Language Battle
6
Scala
Clojure
Haskell
Frege
Java
Groovy
Imperativ
© Orientation in Objects GmbH
Funktional
JVM Functional Language Battle
7
Imperative Programmierung
Imperative Programmierung (lat. imperare
‚anordnen‘, ‚befehlen‘) ist ein
Programmierparadigma, nach dem „ein
Programm aus einer Folge von
Anweisungen besteht, die vorgeben, in
welcher Reihenfolge was vom Computer
getan werden soll“.
https://de.wikipedia.org/wiki/Imperative_Programmierung
© Orientation in Objects GmbH
JVM Functional Language Battle
8
Imperativ
© Orientation in Objects GmbH
Funktional
Deklarativ
JVM Functional Language Battle
9
Funktionale Programmierung
Funktionale Programmierung ist
ein Programmierparadigma, bei dem
Programme ausschließlich aus Funktionen
bestehen. Dadurch wird bewusst auf die aus
der imperativen Programmierung
bekannten Nebenwirkungen verzichtet.
© Orientation in Objects GmbH
JVM Functional Language Battle
10
Problemstellung
© Orientation in Objects GmbH
JVM Functional Language Battle
11
?
© Orientation in Objects GmbH
JVM Functional Language Battle
12
Prüfsummen-Berechnung
Luhn-Algorithmus;
Luhn-Formel;
"Modulo 10"-Algorithmus;
Double-Add-Double-Methode
© Orientation in Objects GmbH
JVM Functional Language Battle
13
Validierung von Kreditkarten
• Luhn Algorithmus
• Kreditkartennummern können sich selbst prüfen
rein clientseitige
Prüfung möglich
• Berechnung einer Prüfsumme aus den einzelnen Ziffern
• wenn Prüfsumme modulo 10
– = 0 => valide
– <> 0 => nicht valide
© Orientation in Objects GmbH
JVM Functional Language Battle
14
Wie funktioniert die Validierung genau
1. (Umwandlung in Ziffern)
2. Reihenfolge vertauschen
3. jede zweite Zahl verdoppeln
4. einzelne Zahlen zusammenaddieren
–
bei Zahlen größer 9 werden die einzelnen Ziffern aufaddiert
5. valide, wenn die Summe modulo 10 == 0
© Orientation in Objects GmbH
JVM Functional Language Battle
15
Beispiel
"4716347184862961"
4
7
1
6
3
4
7
1
8
4
8
6
2
9
6
1
1
6
9
2
6
8
4
8
1
7
4
3
6
1
7
4
1
12
9
4
6
16
4
16
1
14
4
6
6
2
7
8
1
1 2
9
4
6
1 6
4
1 6
1
1 4
4
6
6
2
7
8
1
3
9
4
6
7
4
7
1
5
4
6
6
2
7
8
1+3+9+4+6+7+4+7+1+5+4+6+6+2+7+8
80
80 % 10 == 0
gültig
© Orientation in Objects GmbH
JVM Functional Language Battle
16
© Orientation in Objects GmbH
JVM Functional Language Battle
17
© Orientation in Objects GmbH
JVM Functional Language Battle
18
Java klassisch – Variante 1
© Orientation in Objects GmbH
JVM Functional Language Battle
19
Java klassisch – Variante 2
© Orientation in Objects GmbH
JVM Functional Language Battle
20
Java klassisch mit sprechenden Methodennamen
© Orientation in Objects GmbH
JVM Functional Language Battle
21
Demo
Kreditkarten-Nummer prüfen mit Java:
public static void main(String[] args) {
System.out.println(isValid("4716347184862961"));
}
© Orientation in Objects GmbH
JVM Functional Language Battle
22
Programm: Folge von elementaren Schritten
Typischer Schritt ist die Wertzuweisung
Speicherung von Daten erfolgt in Variablen
Kontrollstrukturen:
• Sequenzen (…; …;)
• Alternativen (if, switch)
• Schleifen (for, while, do…while)
• Sprünge und Unterprogrammaufrufe (goto)
© Orientation in Objects GmbH
JVM Functional Language Battle
23
Imperativ vs. Deklarativ
Imperativ:
Wie erreiche ich mein Ziel?
Deklarativ:
Was will ich erreichen?
© Orientation in Objects GmbH
JVM Functional Language Battle
24
Imperativ
Funktional
© Orientation in Objects GmbH
JVM Functional Language Battle
25
Java klassisch – Spaghetti-Code
Aufspalten in Ziffern
Reihenfolge drehen
Jede 2. Ziffer verdoppeln
Aufsummieren
Validierungsprüfung
© Orientation in Objects GmbH
JVM Functional Language Battle
26
Und in anderen Sprachen?
© Orientation in Objects GmbH
JVM Functional Language Battle
27
Groovy
• objektorientiert
• dynamisch und/statisch typisiert
• ausdrucksstarke/prägnante Syntax
• sehr gute Integration mit Java (JVM, Bibliotheken, Vererbung, …)
• Metaprogrammierung, Closures, Operatorüberladung
© Orientation in Objects GmbH
JVM Functional Language Battle
28
Demo
Kreditkarten-Nummer prüfen mit Groovy
groovy> isValid 4716347184862961
true
© Orientation in Objects GmbH
JVM Functional Language Battle
29
JavaScript
• objektorientierte Skriptsprache
• aber klassenlos (Prototyp-basiert)
• dynamisch typisiert
• Funktionen sind First-Class-Citizens
• Client (Browser) und Server (Node.js, Nashorn auf JVM)
© Orientation in Objects GmbH
JVM Functional Language Battle
30
Demo
Kreditkarten-Nummer prüfen mit JavaScript
> isValid(4716347184862961)
true
© Orientation in Objects GmbH
JVM Functional Language Battle
31
Scala
• funktional und objektorientiert
• statisch typisiert (Typinferenz)
• Funktionen als First-Class-Citizens
• Pattern Matching
• Java-Integration
© Orientation in Objects GmbH
JVM Functional Language Battle
32
Demo
Kreditkarten-Nummer prüfen mit Scala
scala> isValid(4716347184862961)
true
© Orientation in Objects GmbH
JVM Functional Language Battle
33
Frege
• Haskell for the JVM
• rein funktionale Programmiersprache
• statisch typisiert mit Typinferenz und Typvariablen
• frei von Nebeneffekten
• Monaden zur Kapselung von imperativen Konstrukten
• Pattern Matching
• Typklassen
© Orientation in Objects GmbH
JVM Functional Language Battle
34
Demo
Kreditkarten-Nummer prüfen mit Frege (Haskell)
frege> isValid 4716347184862961
True
© Orientation in Objects GmbH
JVM Functional Language Battle
35
Algorithmus in Frege
Validierungsfunktion
Kreditkartennummer
isValid n =
(sumDigits (double2nd (toDigitsRev n))) % 10 == 0
Summe
der Ziffern
© Orientation in Objects GmbH
Verdoppeln
jede 2. Ziffer
Ziffern
rückwärts
JVM Functional Language Battle
Teilbar
durch 10?
36
Haskell/Frege
toDigits n = toDigits (n `div` 10) ++ [(n `mod` 10)]
toDigitsRev n = reverse (toDigits n)
double2nd = zipWith (*) (cycle [1, 2])
sumDigits xs = sum (concat (map toDigits xs))
isValid n =
mod (sumDigits (double2nd (toDigitsRev n))) 10 == 0
isValid n =
(sumDigits (double2nd (toDigitsRev n))) % 10 == 0
© Orientation in Objects GmbH
JVM Functional Language Battle
37
Keine veränderbaren Zustände
Seiteneffekt-frei
Referentielle Transparenz
First-Class-Citizens
Higher-Order Functions
Lambdas/Closures
Lazy Evaluation
Rekursion
© Orientation in Objects GmbH
JVM Functional Language Battle
38
Funktionen
© Orientation in Objects GmbH
JVM Functional Language Battle
39
Warum Funktionale Programmierung
• einfach zu testen, zu debuggen
• einfach zu verstehen durch einfache Abstraktionen und referentielle
Transparenz
• seiteneffektfrei, lässt sich leicht parallelisieren
• modularisierbar und einfach wieder zusammenführbar
• erhöht Code-Qualität
© Orientation in Objects GmbH
JVM Functional Language Battle
40
OO vs. Funktional
© Orientation in Objects GmbH
JVM Functional Language Battle
41
Ist Java 8 funktional?
© Orientation in Objects GmbH
JVM Functional Language Battle
42
"Funktional Programmieren" mit Java 8
• Lambdas: Funktionsliterale als First-Class-Citizens
• Higher-Order Functions
• Currying und Funktionskomposition
• Streams
• Erweiterungen Collections mit Default-Methoden
• (Rekursion)
© Orientation in Objects GmbH
JVM Functional Language Battle
43
Java 8: Currying und partielle Funktionsaufrufe
Currying: Konvertierung einer Funktion mit n Argumenten
in n Funktionen mit jeweils einem Argument.
© Orientation in Objects GmbH
JVM Functional Language Battle
44
Java 8: Funktionskomposition
© Orientation in Objects GmbH
JVM Functional Language Battle
45
Luhn-Algorithmus in Java 8 – Variante 1
© Orientation in Objects GmbH
JVM Functional Language Battle
46
Was fehlt Java 8 zur besseren funktionalen
Unterstützung?
• Erzwingen von Immutability
• persistente Datenstrukturen
• Vermeidung von Seiteneffekten
• referentielle Transparenz
• Lazy Evaluation
• funktionale Bibliotheksfunktionen
© Orientation in Objects GmbH
JVM Functional Language Battle
47
Immutable Klassen
• genau ein Zustand
– keine Prüfung von Invarianten und von Zustandsübergänge (API-Doc)
– abgeleitete Größen können in Cache gehalten werden
• Thread-safe
– keine Zustandsänderung
– keine Synchronisation
• gemeinsame Nutzung von Instanzen
– public Konstanten
– Instanzkontrolle durch statische Factories
– keine defensive Copies
• gemeinsame Nutzung innerer Zustände
– BigInteger#negate()
– String#subString()
© Orientation in Objects GmbH
JVM Functional Language Battle
48
Funktionale Erweiterungen für Java
Project Lombok
© Orientation in Objects GmbH
JVM Functional Language Battle
49
Project Lombok
• Compile-Time Metaprogrammierung
• Reducing Boilerplate Code durch Annotationen
• Generation des Immutable-Gerüsts mit @Value
• Lazy Evaluierung mit @Getter(lazy = true)
© Orientation in Objects GmbH
JVM Functional Language Battle
50
private, final,
keine Setter,
Argument-Konstruktor
equals/hashcode
Lazy-Evaluierung
© Orientation in Objects GmbH
JVM Functional Language Battle
51
FunctionalJava
• funktionale Programmierbibliothek für Java
• Lernplattform für funktionale Programmierung mit der gewohnten
Sprache
• unterstützt Java 6+ (mit Retro Lambda)
• Basis Datenstrukturen (Funktionen, partielle Funktionen, Unit, Void,
Option, Either, …
• Immutable Collections (Array, List, Stream, Set, Map, …
• Monaden, Zipper
© Orientation in Objects GmbH
JVM Functional Language Battle
52
© Orientation in Objects GmbH
JVM Functional Language Battle
53
Demo
Kreditkarten-Nummer prüfen mit Java 8 + FunctionalJava:
public static void main(String[] args) {
System.out.println(isValid("4716347184862961"));
}
© Orientation in Objects GmbH
JVM Functional Language Battle
54
Javaslang
• "Javaslang is a functional library for Java 8+ that provides persistent
data types and functional control structures."
• Persistent Data Structures
– LinkedList, Queue, Sorted Set, Stream
• Tuple
• Functions, CheckedFunctions
© Orientation in Objects GmbH
JVM Functional Language Battle
55
Javaslang: Tuple (bis Tuple8)
© Orientation in Objects GmbH
JVM Functional Language Battle
56
Javaslang: Partielle Funktionsaufrufe und
Komposition
© Orientation in Objects GmbH
JVM Functional Language Battle
57
Javaslang: Currying
© Orientation in Objects GmbH
JVM Functional Language Battle
58
Javaslang: Function Lift (Fangen von Exceptions)
© Orientation in Objects GmbH
JVM Functional Language Battle
59
Links
• Learn You a Haskell for Great Good!
– http://learnyouahaskell.com/chapters
• LYAH (Learn You a Haskell) adaptions for Frege
– https://github.com/Frege/frege/wiki/LYAH-adaptions-for-Frege
• Project Lombok
– https://projectlombok.org/
• Functional Java
– http://www.functionaljava.org/
• Javaslang
– http://www.javaslang.io/
© Orientation in Objects GmbH
JVM Functional Language Battle
60
Literaturhinweise
•
Functional Programming in Java: Harnessing
the Power Of Java 8 Lambda Expressions
– Venkat Subramaniam
– The Pragmatic Programmers, Erscheinungsdatum:
Februar 2014
– ISBN: 978-1-93778-546-8
– Sprache: Englisch
• Mastering Lambdas
–
–
–
–
–
© Orientation in Objects GmbH
Maurice Naftalin
Oracle Press
Erscheinungsdatum: Oktober 2014
ISBN: 0071829628
Sprache: Englisch
JVM Functional Language Battle
61
Literaturhinweise
• Learn You a Haskell for Great Good!: A
Beginner's Guide
–
–
–
–
Miran Lipovaca
No Starch Press, Erscheinungsdatum: April 2011
ISBN: 978-1593272838
Sprache: Englisch
• Real World Haskell
–
–
–
–
© Orientation in Objects GmbH
Bryan O'Sullivan und John Goerzen
O'Reilly, Erscheinungsdatum: 2010
ISBN: 978-0596514983
Sprache: Englisch
JVM Functional Language Battle
62
? ? ?
?
?
Fragen ?
Orientation in Objects GmbH
Weinheimer Str. 68
68309 Mannheim
www.oio.de
[email protected]
63
Vielen Dank für Ihre
Aufmerksamkeit !
Orientation in Objects GmbH
Weinheimer Str. 68
68309 Mannheim
www.oio.de
[email protected]
Herunterladen