Top Banner
Insert company logo New Technology Scala: Durch Java 8 überflüssig geworden? Lutz Hühnken / @lutzhuehnken @lutzhuehnken 29/09/2016
41

Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Apr 06, 2017

Download

Software

Lutz Hühnken
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Insert company logo

New Technology

Scala: Durch Java 8 überflüssig geworden?Lutz Hühnken / @lutzhuehnken

@lutzhuehnken 29/09/2016

Page 2: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Was macht funktionale Programmierung aus?

• Funktionen • (Unveränderliche) Werte • Keine Seiteneffekte

Page 3: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Funktionen

• Code vs. Daten

scala> val sum = (x:Int, y:Int) => x + y Type of sum is (Int, Int) => Int

Page 4: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Werte

• Wert vs. Identität • kein PlOP

Integer x = new Integer(5)

String hello = „Hello“

Page 5: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Keine Seiteneffekte

• Ausdrücke evaluieren vs. Anweisungen ausführen • Ziel: Referenzielle Transparenz

Page 6: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Funktionale Programmierung Scala vs. Java8

Page 7: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Die Disziplinen

• Funktionen höherer Ordnung • Unveränderliche Werte und Datenstrukturen • Currying, partiell evaluierte Funktionen • Tupel • Pattern Matching • Ausdrücke • Rekursion

Page 8: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Die Teams

• Scala - http://www.scala-lang.org • Vereinigt OO mit FP

• Java8 mit Verstärkung: • Immutables - https://immutables.github.io • PCollections - http://pcollections.org • Javaslang - http://www.javaslang.io • Halva - https://github.com/soabase/soabase-halva

Page 9: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016
Page 10: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016
Page 11: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016
Page 12: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016
Page 13: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Funktionen

List<String> getNames(List<Customer> customers) { List<String> names = new ArrayList<String>(); for (customer : customers) { names.add(customer.getName()); } return names; }

Was wir nicht (mehr) wollen

Page 14: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Funktionen

val names = customers.map(_.name)

Scala

Page 15: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Funktionen

List<String> names = myList.stream()

.map(c -> c.name)

.collect(Collectors.toList());

Java 8

Page 16: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Funktionen

List<String> names = customers.map(c -> c.name);

Javaslang

Page 17: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Unveränderliche Werte

• Werte sind unveränderlich - nicht nur die Referenz (final), auch das Object, auf das sie zeigt! Werte

• Können geteilt werden • Haben stabilen Hashcode • Können übertragen werden

Page 18: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Werte

case class Time(hours: Int = 0, minutes: Int = 0)

val t1 = Time(12,0)

val t2 = Time(hours = 12)

val t3 = t2.copy(minutes = 30)

Scala

Page 19: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Werte

@Immutable public final class Time {

public final Integer hours; public final Integer minutes;

public Time(Integer hours, Integer minutes) { this.hours = hours; this.minutes = minutes; }

@Override public boolean equals(@Nullable Object other) { if (this == other) return true; if (!(other instanceof Time)) return false; Time otherTime = (Time) other;

return hours.equals(otherTime.hours) && minutes.equals(otherTime.minutes); }

@Override public int hashCode() { return Objects.hash(hours, minutes); }

@Override public String toString() { return MoreObjects.toStringHelper("Time") .add("hours", hours).add("minutes", minutes).toString(); } }

Java 8

Page 20: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Werte

import org.immutables.value.Value;

@Value.Immutable public abstract class Time { public abstract Integer hours(); public abstract Integer minutes(); }

Immutables

Page 21: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Werte

Time t1 = ImmutableTime.builder() .hours(12) .minutes(0) .build();

Immutables

Page 22: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Werte

Halva

@CaseClass public interface Time { Integer hours(); Integer minutes(); }

Time t1 = new TimeCase(12,0);

Page 23: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Unveränderliche Datenstrukturen

Für Aggregate (Collections) muss das gleiche gelten wie für ihre Elemente!

Auch sie wollen wir teilen und übertragen können - kein „PlOP“.

Page 24: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Datenstrukturen (Collections)

scala> val v1 = Vector(1,2,3) v1: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

scala> v1.updated(0,3) res0: scala.collection.immutable.Vector[Int] = Vector(3, 2, 3)

scala> v1 res1: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

Scala

Page 25: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Datenstrukturen (Collections)

import org.pcollections.PVector;import org.pcollections.TreePVector;

PVector<Integer> pv1 = TreePVector.from(Arrays.asList(1,2,3));

pv1.with(0,3);

System.out.println(pv1.toString()); // [1, 2, 3]

PCollections

Page 26: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Collections

• Fokussiert auf persistente Collections • Minimale API (plus, minus, with..) • Keine zusätzlichen Methoden, keine Lambda-

Unterstützung • Drop-In-Replacement (PVector implementiert

java.util.List, HashPMap impl. java.util.Map..)

Page 27: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Datenstrukturen (Collections)

import javaslang.collection.Vector;

Vector<Integer> v1 = Vector.of(1,2,3);

v1.update(0,3);

System.out.println(v1.mkString(",")); // (1,2,3)

Javaslang

Page 28: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Javaslang

• Bietet „reiche“ API (mit drop, take, permutation, map, flatMap, filter, collect, sliding, etc., entsprechend Scala-Collections.), inkl. Funktionen höherer Ordnung.

• Kein Drop-In-Replacement (implementiert nicht java.util.Collection etc.)

Page 29: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Currying

scala> def sum(a:Int)(b:Int) = a + b sum: (a: Int)(b: Int)Int

scala> val sum2: Function[Int,Int] = sum(2) sum2: Function[Int,Int] = <function1>

scala> sum2(4) res1: Int = 6

Scala

Page 30: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Currying

Function2<Integer, Integer, Integer> sum = (a, b) -> a + b;

Function1<Integer, Integer> add2 = sum.curried().apply(2);

add2.apply(4) // 6

Javaslang

Page 31: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Tupel

scala> val java8 = ("Java", 8) java8: (String, Int) = (Java,8)

scala> java8._1 res0: String = Java

scala> java8._2 res1: Int = 8

scala> List("a","b","c").zip(List(1,2,3)) res2: List[(String, Int)] = List((a,1), (b,2), (c,3))

Scala

Page 32: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Tupel

Tuple2<String, Integer> java8 = Tuple.of("Java", 8);

String s = java8._1; // "Java"

Integer i = java8._2; // 8

List<Tuple2<String,Integer>> zipped = List.of("a", "b", "c").zip(List.of(1,2,3));System.out.println(zipped.mkString(", ")); // (a, 1), (b, 2), (c, 3)

Javaslang

Page 33: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Pattern Matching

val s = i match { case 1 => "one" case 2 => "two" case _ => "?" }

Scala

Page 34: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Pattern Matching

String s = Match(i).of( Case($(1), "one"), Case($(2), "two"), Case($(), "?") );

Javaslang

Page 35: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Ausdrücke

• Ausdrücke („Expressions“) vs. Befehle („Statements“). • Statements haben kein Ergebnis und werden nur um

des Seiteneffekts wegen ausgeführt. • Wichtige Java-Kontrollstrukturen sind Statements (if,

for, while, try…). • In Scala ist alles ein Ausdruck.

Page 36: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Ausdrücke

for { n <- 1 to 3 m <- 1 to n } yield n * m

res0: Vector(1, 2, 4, 3, 6, 9)

scala> val b = if (3 < 4) "yes" else "no" b: String = yes

Scala

Page 37: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Rekursion

def factorial(n: Int, acc: BigInt = 1): BigInt = if (n == 0) acc else factorial(n - 1, n * acc)

Scala

Page 38: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Rekursion

• In Scala ok, da rechtsrekursiv (tail recursive) • In Java - java.lang.StackOverflowError

Page 39: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Problemfelder in Java

• Syntax - Unterstützung für Datenklassen (kommt in Java 10?), Tupel fehlt

• Unveränderliche Datenstrukturen (Collections) fehlen • Zu viele Anweisungen (if, switch, for..), zu wenig

Ausdrücke • Checked Exceptions • Keine Tail-Call-Optimierung für rechtsrekursive

Funktionen

Page 40: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Fazit

• Mit der Kombination Lambdas, Javaslang und Halva oder Immutables lässt sich brauchbar funktional programmieren - es gibt also keine Ausrede!

• Es gibt aber noch viel zu tun! Scala bleibt fürs erste die deutlich komfortablere Lösung.

Page 41: Funktionale Programmierung in Java 8 und Scala auf der CodeTalks Hamburg am am 29.9.2016

Insert company logo

New Technology

Scala: Durch Java 8 überflüssig geworden?Antwort: Nein.

Lutz Hühnken / @lutzhuehnken

@lutzhuehnken 29/09/2016