Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

41
Generics: Past, Present and Future @richardwarburto insightfullogic.com @raoulUK cambridgecoding.com

Transcript of Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Page 1: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Generics: Past, Present and [email protected]

@raoulUKcambridgecoding.com

Page 2: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

binarySearch(List<? extends Comparable<? super T>> list, T key)

Page 3: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Past

Present

Future

Page 4: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma
Page 5: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

… also generics are added to Java.

Yay!

Page 6: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Static Safety Concision

Simplicity

Dynamically Typed Languages - Javascript, Ruby, Python

StringListFantom

GenericsJava, Scala, C#, C++ ...

Page 7: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Past

Present

Future

Page 8: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Intersection Types

Curiously Recurring Generics Pattern

Wildcards

Page 9: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

IntersectionA ∩ B = elements has to be a member of both A and B

Intersection Type<T extends A> = T has is a subtype of A

<T extends A & B> = T is a subtype of A and B

Page 10: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

<T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

Page 11: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

A Confusing Intersection Type

<T extends Object & Comparable<? super T>>

T max(Collection<? extends T> coll)

intersection

Page 12: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Signature pre-generics

public static Object max(Collection coll)

● max is stuck with this signature to preserve binary compatibility.

● Can only find the max if the objects are Comparable

Page 13: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Type erasure

<T extends Comparable<? super T>> T max(Collection<? extends T> coll)

Comparable max(Collection coll)

javac compilation

Page 14: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Type erasure with intersection

<T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

Object max(Collection coll)

javac compilation

Page 15: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Serializable lambdas

<T, U extends Comparable<? super U>> Comparator<T>

comparing(Function<? super T, ? extends U> keyExtractor) {

Objects.requireNonNull(keyExtractor);

return (Comparator<T> & Serializable)

(c1, c2) ->

keyExtractor.apply(c1)

.compareTo(keyExtractor.apply(c2));

}

Page 16: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

class Enum<E extends Enum<E>>

Page 17: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Curiously Recurring Generics Pattern

Page 18: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Bounded Wildcards

Page 19: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Examples

<T> List<T> unmodifiableList(List<? extends T> list)

<T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)

<T> int binarySearch(List<? extends Comparable<? super T>> list, T key)

Page 20: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

It’s all about subtyping!

Page 21: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

? super

Commonly used for Functional Interfaces

Comparator<Foo>always Comparator<? super Foo>int compare(T o1, T o2);

Comparator<Message> <: Comparator<? super EmailMessage>

Predicate<Foo>always Predicate<? super Foo>boolean test(T t);

Predicate<Message> <: Predicate<? super EmailMessage>

Page 22: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Adoption and use of Java generics

90% generics use with Collections○ List<String>, ArrayList<String>,○ HashMap<String,String>, Set<String>

wildcards 10%○ Class<?>

http://www.cc.gatech.edu/~vector/papers/generics2.pdf

Page 23: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Intersection Types

Curiously Recurring Generics Pattern

Wildcards

Page 24: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Past

Present

Future

Page 25: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Use-site variance

static void logAllWithAction(List<? extends Message> messages,

Consumer<? super Message> action) {

messages.forEach(action);

}

Page 26: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Declaration-site variance

Library:interface Consumer<? super T> {

void accept(T t);

}

interface StreamStream<? extends T> {

...

}

User code:static void logAllWithAction(StreamStream<Message> messages,

Consumer<Message> action) {

...

}

Page 27: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Declaration-site variance

● User-site variance○ variance complexity pushed to users○ can add more verbosity due to annotations

● Declaration-site variance○ variance complexity pushed to library level ○ List needs to be split in ReadOnly, WriteOnly○ Adopted by C#, Scala

Improved variance for generic classes and interfaceshttp://openjdk.java.net/jeps/8043488

Page 28: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Value Types

● “codes like a class, works like an int”

● No Identity

● Just a struct of values

Page 29: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Compactness (Less memory)

● No Mark Word○ Locking

● No klass pointer

● Saving 8-16 bytes depending upon architecture/VM

Page 30: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Sequential Locality (Flatness)

0

1

2

...

User

Name

Id

User0

1

2

...

Name

Id

Page 31: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

BUT there’s yet generics more complexity

● No Identity, reference equality, locking or condition variables

● So we need to add a new concept to generics

● Explicitly need to opt your generic type into any value:

class ArrayList<any T> implements List<T>

Page 32: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Primitive specialisation

List<int> numbers = new ArrayList<>();

numbers.add(1);

numbers.add(2);

State of the Specializationhttp://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html

http://openjdk.java.net/projects/valhalla/

Page 33: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Of interest …

● Unbounded Wildcards

● Type Bounds

● Erasure Problems & Advantages

● Static safety failures

● Other Languages & Features (Lambda Cube)

● Source Code

○ https://github.com/RichardWarburton/generics-examples

Page 34: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Conclusions

● Usage patterns change as other features are added

● Generics usage continues to increase in both scale and

complexity

● Most of the complexity burden is on library authors

Page 35: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Static Type-safety often involves a tradeoff

between simplicity and flexibility

Page 37: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

The EndRichard Warburton(@richardwarburto)

Raoul-Gabriel Urma(@raoulUK)

Page 38: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Mmmm

Java API

<T> List<T>

unmodifiableList(List<? extends T> list)

vs

<T> List<? extends T>

unmodifiableList(List<? extends T> list)

Page 39: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

public static <T,K,U,M extends Map<K,U>> Collector<T,?,M>

toMap(Function<? super T,? extends K> keyMapper,

Function<? super T, ? extends U> valueMapper,

BinaryOperator<U> mergeFunction,

Supplier<M> mapSupplier)

From Java 8’s Collectors

Page 40: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma
Page 41: Java Generics Past, Present and Future - Richard Warburton, Raoul-Gabriel Urma

Higher kinded types

trait Mapable[F[_]] {

def map[A, B](fa: F[A])(f: A => B): F[B]

}

Stream[T] extends Mapable[Stream]

Option[T] extends Mapable[Option]