Scala Collections : Java 8 on Steroids

45
Scala Collections : Java 8 on Steroids François Garillot Twitter : @huitseeker [email protected] 1

description

A small talk comparing Java 8 & Scala Collections on functionality, design & goals. psug-44.eventbrite.fr

Transcript of Scala Collections : Java 8 on Steroids

Page 1: Scala Collections : Java 8 on Steroids

Scala Collections : Java 8 on Steroids

François Garillot

Twitter : @huitseeker

[email protected]

1

Page 2: Scala Collections : Java 8 on Steroids

What this talk is

2

Page 3: Scala Collections : Java 8 on Steroids

What this talk is

! A look at Java 8 gives you

2-a

Page 4: Scala Collections : Java 8 on Steroids

What this talk is

! A look at Java 8 gives you

! ... and what it doesn’t

2-b

Page 5: Scala Collections : Java 8 on Steroids

What this talk is

! A look at Java 8 gives you

! ... and what it doesn’t

! A look at Scala collections

2-c

Page 6: Scala Collections : Java 8 on Steroids

What this talk is

! A look at Java 8 gives you

! ... and what it doesn’t

! A look at Scala collections

! A look at the why and how of collections

2-d

Page 7: Scala Collections : Java 8 on Steroids

What this talk is not

3

Page 8: Scala Collections : Java 8 on Steroids

What this talk is not

! New stuff

3-a

Page 9: Scala Collections : Java 8 on Steroids

What this talk is not

! New stuff

! Rocket Science

3-b

Page 10: Scala Collections : Java 8 on Steroids

What this talk is not

! New stuff

! Rocket Science

! Polemic

3-c

Page 11: Scala Collections : Java 8 on Steroids

What I’m hoping for

4

Page 12: Scala Collections : Java 8 on Steroids

What I’m hoping for

! A discussion

4-a

Page 13: Scala Collections : Java 8 on Steroids

What I’m hoping for

! A discussion

! Making things a tad more clear

4-b

Page 14: Scala Collections : Java 8 on Steroids

What I’m hoping for

! A discussion

! Making things a tad more clear

! ... or just less overlooked ?

4-c

Page 15: Scala Collections : Java 8 on Steroids

What I’m hoping for

! A discussion

! Making things a tad more clear

! ... or just less overlooked ?

! Not too boring

4-d

Page 16: Scala Collections : Java 8 on Steroids

What (functional, new things) you can do with Java 8

Lambda-expressions

(String first, String second) ->

Integer.compare(first.length(), second.length)

Functional Interfaces

Runnable r = () -> System.out.println("I am Runnable!");

Method references

button.setOnAction(System.out::println);

Constructor references

List<String> labels = ... ;

Stream<Button> buttonsStream = labels.stream().map(Button::new);

Buttons[] buttonsArray = labels.stream().toArray(Button::new);

int[]::new;

5

Page 17: Scala Collections : Java 8 on Steroids

The devil is in the details

Optional<T>, Optional.of(), Optional.ofNullable(), Optional.empty()

Default methods in interfaces.

list.forEach(System.out::println)

... beware: SuperClasses win, Interfaces clash. ... And the standard library was not

entirely rewritten (Path/Paths)

Important topics : variable capture in closures, parallel execution.

int[] counter = new int[1];

button.setOnAction(event -> counter[0]++);

6

Page 18: Scala Collections : Java 8 on Steroids

And also, Streams

! Any Collection has a stream()

! Stream.of() with a vararg, an array

! filter, map, flatMap, as well as plumbing: split, concat, limit

! Lazy processing, parallel() processing (you enforce statelessness)

! terminal reductions, e.g. reduce

! collector:HashSet<String> result =

stream.collect(HashSet::new, HashSet::add, HashSet::addAll)

! Collector implementations (toList, toMap, ...)

! counting, maxBy, groupinBy, mapping, ...

! Beware: think about reuse.

7

Page 19: Scala Collections : Java 8 on Steroids

Interlude

8

Page 20: Scala Collections : Java 8 on Steroids

Interlude

! Does that make Java a functional programming language ?

8-a

Page 21: Scala Collections : Java 8 on Steroids

Interlude

! Does that make Java a functional programming language ?

! First class functions

8-b

Page 22: Scala Collections : Java 8 on Steroids

Interlude

! Does that make Java a functional programming language ?

! First class functions

! Technicalities

8-c

Page 23: Scala Collections : Java 8 on Steroids

Interlude

! Does that make Java a functional programming language ?

! First class functions

! Technicalities

! Does that make Java a Scala competitor ?

8-d

Page 24: Scala Collections : Java 8 on Steroids

Interlude

! Does that make Java a functional programming language ?

! First class functions

! Technicalities

! Does that make Java a Scala competitor ?

! Scala has never had a feature poverty problem.

8-e

Page 25: Scala Collections : Java 8 on Steroids

What you can’t do with Java 8 (yet)

1. Case classes

2. Pattern matching

3. Tail call elimination

4. Scoped access

5. Lazy keyword

6. Traits (well-scoped)

7. Rich Imports (local, aliased)

8. Macros

9. Backend (Miguel Garcia)

10. Specialization (Vlad Ureche)

11. Value classes

12. Implicits

13. Cake !

9

Page 26: Scala Collections : Java 8 on Steroids

Collections

! The signatures of map

! Type classes & implicits

! Design goals

10

Page 27: Scala Collections : Java 8 on Steroids

The signatures of map

11

Page 28: Scala Collections : Java 8 on Steroids

The signatures of map

! def map[B](f: (A) ⇒ B) : Map[B]

11-a

Page 29: Scala Collections : Java 8 on Steroids

The signatures of map

! def map[B](f: (A) ⇒ B) : Map[B]

! But ... Type Constructor Polymorphism

11-b

Page 30: Scala Collections : Java 8 on Steroids

The signatures of map

! def map[B](f: (A) ⇒ B) : Map[B]

! But ... Type Constructor Polymorphismtrait TraversableLike[+Elem, +Coll[+x]] {

def map[NewElem](f: Elem ⇒ NewElem): Coll[NewElem]

def filter(p: Elem ⇒ Boolean): Coll[Elem]

}

11-c

Page 31: Scala Collections : Java 8 on Steroids

The signatures of map

! def map[B](f: (A) ⇒ B) : Map[B]

! But ... Type Constructor Polymorphismtrait TraversableLike[+Elem, +Coll[+x]] {

def map[NewElem](f: Elem ⇒ NewElem): Coll[NewElem]

def filter(p: Elem ⇒ Boolean): Coll[Elem]

}

! The idea that, whatever map needs, it will always deal with:

11-d

Page 32: Scala Collections : Java 8 on Steroids

The signatures of map

! def map[B](f: (A) ⇒ B) : Map[B]

! But ... Type Constructor Polymorphismtrait TraversableLike[+Elem, +Coll[+x]] {

def map[NewElem](f: Elem ⇒ NewElem): Coll[NewElem]

def filter(p: Elem ⇒ Boolean): Coll[Elem]

}

! The idea that, whatever map needs, it will always deal with:(Collection[Elements],

Elements ⇒ OtherElements,

Collection[OtherElements])

11-e

Page 33: Scala Collections : Java 8 on Steroids

The signatures of map

12

Page 34: Scala Collections : Java 8 on Steroids

The signatures of map

12-a

Page 35: Scala Collections : Java 8 on Steroids

The signatures of map

! trait TraversableLike[+Elem, +Repr] {

protected[this] def newBuilder: Builder[Elem, Repr] // deferred

def foreach[U](f: Elem ⇒ U) // deferred

def filter(p: Elem ⇒ Boolean): Repr = {

val b = newBuilder

foreach { elem <- if (p(elem)) b += elem }

b.result

}

}

class Builder[-Elem, +To] {

def +=(elem: Elem): this.type = . . .

def result(): To = . . .

def clear() = . . .

def mapResult[NewTo](f: To ⇒ NewTo): Builder[Elem, NewTo] = . . .

}

12-b

Page 36: Scala Collections : Java 8 on Steroids

The signatures of map

! trait TraversableLike[+Elem, +Repr] {

protected[this] def newBuilder: Builder[Elem, Repr] // deferred

def foreach[U](f: Elem ⇒ U) // deferred

def filter(p: Elem ⇒ Boolean): Repr = {

val b = newBuilder

foreach { elem <- if (p(elem)) b += elem }

b.result

}

}

class Builder[-Elem, +To] {

def +=(elem: Elem): this.type = . . .

def result(): To = . . .

def clear() = . . .

def mapResult[NewTo](f: To ⇒ NewTo): Builder[Elem, NewTo] = . . .

}

! Why do we care ? Extensibility.

12-c

Page 37: Scala Collections : Java 8 on Steroids

The signatures of map (cont’d)

13

Page 38: Scala Collections : Java 8 on Steroids

The signatures of map (cont’d)

13-a

Page 39: Scala Collections : Java 8 on Steroids

The signatures of map (cont’d)

! def map[B, That](f: ((A,B)) ⇒ B)

(implicit bf:CanBuildFrom[Map[A,B], B, That]):That

13-b

Page 40: Scala Collections : Java 8 on Steroids

The signatures of map (cont’d)

! def map[B, That](f: ((A,B)) ⇒ B)

(implicit bf:CanBuildFrom[Map[A,B], B, That]):That

! Why ?

13-c

Page 41: Scala Collections : Java 8 on Steroids

The signatures of map (cont’d)

! def map[B, That](f: ((A,B)) ⇒ B)

(implicit bf:CanBuildFrom[Map[A,B], B, That]):That

! Why ?

! Dealing with (Bitset, Int, BitSet) and

(Bitset, String, Set[String])

13-d

Page 42: Scala Collections : Java 8 on Steroids

The signatures of map (cont’d)

! def map[B, That](f: ((A,B)) ⇒ B)

(implicit bf:CanBuildFrom[Map[A,B], B, That]):That

! Why ?

! Dealing with (Bitset, Int, BitSet) and

(Bitset, String, Set[String])

! Dealing with (Map[A, B], (A, B)) ⇒ (B, A), Map[B, A]) and

(Map[A, B], (A, B)) ⇒ T, Iterable[T])

13-e

Page 43: Scala Collections : Java 8 on Steroids

With Implicits

trait CanBuildFrom[-Collection, -NewElem, +Result] {

def apply(from: Collection): Builder[NewElem, Result]

}

trait TraversableLike[+A, +Repr] {

def repr: Repr = . . .

def foreach[U](f: A ⇒ U): Unit = . . .

def map[B, To](f: A ⇒ B)(implicit cbf: CanBuildFrom[Repr, B, To]): To = {

val b = cbf(repr) // get the builder from the CanBuildFrom instance

for (x <- this) b += f(x) // transform element and add

b.result

}

}

14

Page 44: Scala Collections : Java 8 on Steroids

trait SetLike[+A, +Repr] extends TraversableLike[A, Repr] { }

trait BitSetLike[+This <: BitSetLike[This] with Set[Int]]

extends SetLike[Int, This] {}

trait Traversable[+A] extends TraversableLike[A, Traversable[A]]

trait Set[+A] extends Traversable[A] with SetLike[A, Set[A]]

class BitSet extends Set[Int] with BitSetLike[BitSet]

object Set {

implicit def canBuildFromSet[B] = new CanBuildFrom[Set[_], B, Set[B]] {

def apply(from: Set[_]) = . . .

}

}

object BitSet {

implicit val canBuildFromBitSet = new CanBuildFrom[BitSet, Int, BitSet] {

def apply(from: BitSet) = . . .

}

}

15

Page 45: Scala Collections : Java 8 on Steroids

ConclusionA word about design.

16