SlideShare a Scribd company logo
1 of 40
The Road to Lambda
Mike Duigou | Oracle
The following is intended to outline our general product
direction. It is intended for information purposes only,
and may not be incorporated into any contract.
It is not a commitment to deliver any material, code, or
functionality, and should not be relied upon in making
purchasing decisions. The development, release, and
timing of any features or functionality described for
Oracle’s products remains at the sole discretion of
Oracle.
Modernizing Java
• Java SE 8 is a big step forward in modernizing the Java Language
– Lambda Expressions (closures)
– Interface Evolution (default methods)
• Java SE 8 is a big step forward in modernizing the Java Libraries
– Bulk data operations on Collections
– More library support for parallelism
• Together, perhaps the biggest upgrade ever
to the Java programming model
What is a Lambda Expression?
• A lambda expression (closure) is an anonymous method
– Has an argument list, a return type, and a body
(Object o) -> o.toString()
– Can refer to values from the enclosing lexical scope
(Person p) -> p.getName().equals(name)
• A method reference is a reference to an existing method
Object::toString
• Allow you to treat code as data
– Behavior can be stored in variables and passed to methods
Times change
• In 1995, most popular languages did not support closures
• Today, Java is just about the last holdout that does not
– C++ added them recently
– C# added them in 3.0
– New languages being designed today all do
“In another thirty years people will laugh at anyone who tries
to invent a language without closures, just as they'll laugh
now at anyone who tries to invent a language without
recursion.”
-Mark Jason Dominus
Closures for Java – a long and winding road
• 1997 – Odersky/Wadler experimental “Pizza” work
• 1997 – Java 1.1 added inner classes – a weak form of closures
– Too bulky, complex name resolution rules, many limitations
• In 2006-2008, a vigorous community debate about closures
– Multiple proposals, including BGGA and CICE
– Each had a different orientation
• BGGA was focused on creating control abstraction in libraries
• CICE was focused on reducing the syntactic overhead of inner
classes
– Things ran aground at this point…
Closures for Java – a long and winding road
• Dec 2009 – OpenJDK Project Lambda formed
• November 2010 – JSR-335 filed
• Current status
– EDR specification complete
– Prototype (source and binary) available on OpenJDK
– Part of Java SE 8 (Spring 2014)
• JSR-335 = Lambda Expressions
+ Interface Evolution
+ Bulk Collection Operations
External Iteration
• Snippet takes the red blocks and colors them blue
• Uses foreach loop
– Loop is inherently sequential
– Client has to manage iteration
• This is called external iteration
• Foreach loop hides complex interaction between library and
client
for (Shape s : shapes) {
if (s.getColor() == RED)
s.setColor(BLUE);
}
Lambda Expressions
• Re-written to use lambda and Collection.forEach
– Not just a syntactic change!
– Now the library is in control
– This is internal iteration
– More what, less how
• Library free to use parallelism, out-of-order execution, laziness
• Client passes behavior into the API as data
• Enables API designers to build more powerful, expressive APIs
– Greater power to abstract over behavior
shapes.forEach(s -> {
if (s.getColor() == RED)
s.setColor(BLUE);
})
Functional Interfaces
• What is the type of a lambda expression or method reference?
– Historically we’ve used single-method interfaces to represent functions
• Runnable, Comparator, ActionListener
– Let’s give these a name: functional interfaces
– And add some new ones like Predicate<T>, Consumer<T>
• A lambda expression evaluates to an instance of a functional interface
Predicate<String> isEmpty = s -> s.isEmpty();
Predicate<String> isEmpty = String::isEmpty;
Runnable r = () -> { System.out.println(“Boo!”) };
• So existing libraries are forward-compatible to lambdas
– Maintains significant investment in existing libraries
Interface Evolution
• The example used a new Collection method – forEach()
– Where did that come from?
– I thought you couldn’t add
new methods to interfaces?
– New feature: default methods
• Virtual method with default
implementation
• Libraries need to evolve!
• Default methods let us compatibly evolve libraries over time
interface Collection<T> {
default void forEach(Consumer<T> action) {
for (T t : this)
action.apply(t);
}
}
Interface Evolution
• Interfaces are a double-edged sword
– Cannot compatibly evolve them unless you control all implementations
– Reality: APIs age
• As we add cool new language features, existing APIs look even older!
– Lots of bad options for dealing with aging APIs
• Let the API stagnate
• Replace it in entirety (every few years!)
• Nail bags on the side (e.g., Collections.sort())
• Burden of API evolution should fall to implementors, not users
Default Methods
• A default method provides an implementation in the interface
• Wait, is this multiple inheritance in Java?
– Java always had multiple inheritance of types
– This adds multiple inheritance of behavior
• But no inheritance of state, where most of the trouble comes from
• Some similarity (and differences) with C# extension methods
– Default methods are virtual and declaration-site
• Primary goal is API evolution
– But useful as an inheritance mechanism on its own
Default Methods – Evolving Interfaces
• New Collection methods
– forEach(Consumer)
– removeIf(Predicate)
• Subclasses may provide
better implementations
• Defaults implemented in
terms of other interface
methods
interface Collection<E> {
default void forEach(Consumer<E> action) {
for (E e : this)
action.apply(e);
}
default boolean removeIf(Predicate<? super E> filter) {
boolean removed = false;
Iterator<E> each = iterator();
while(each.hasNext()) {
if(filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
}
Default Methods – Optional methods
• Default methods can reduce implementation burden
• Most implementations of Iterator don’t provide a useful
remove()
– So why make developer write one that throws?
– Default methods can be used to declare “optional” methods
interface Iterator<T> {
boolean hasNext();
T next();
default void remove() {
throw new UnsupportedOperationException();
}
}
interface Comparator<T> {
int compare(T o1, T o2);
default Comparator<T> reverse() {
return (o1, o2) -> compare(o2, o1);
}
default Comparator<T> compose(Comparator<T> other) {
return (o1, o2) -> {
int cmp = compare(o1, o2);
return cmp != 0 ? cmp : other.compare(o1, o2);
}
}
}
Default Methods – Combinators
• Comparator.reverse() –reverses order of a Comparator
• Comparator.compose() – computes “dictionary order” between
one Comparator and another
Comparator<Person> byFirst = ...
Comparator<Person> byLast = ...
Comparator<Person> byFirstLast = byFirst.compose(byLast);
Comparator<Person> byLastDescending = byLast.reverse();
Bulk operations on Collections
• The lambda version of the “shapes” code can be further
decomposed
• We have added other bulk operations, such as filter, map, into
• “Color the red blocks blue” can be decomposed into
filter+forEach
shapes.stream()
.filter(s -> s.getColor() == RED)
.forEach(s -> { s.setColor(BLUE); });
shapes.forEach(s -> {
if (s.getColor() == RED)
s.setColor(BLUE);
})
Bulk operations on Collections
• Collect the blue Shapes into a List
• If each Shape lives in a Box, find Boxes containing blue shape
List<Shape> blueBlocks
= shapes.stream()
.filter(s -> s.getColor() == BLUE)
.collect(Collectors.toList());
Set<Box> hasBlueBlock
= shapes.stream()
.filter(s -> s.getColor() == BLUE)
.map(s -> s.getContainingBox())
.collect(Collectors.toSet());
Bulk operations on Collections
• Compute sum of weights of blue shapes
• Alternately, with method references:
int sumOfWeight
= shapes.stream()
.filter(s -> s.getColor() == BLUE)
.map(s -> s.getWeight())
.sum();
int sumOfWeight
= shapes.stream()
.filter(s -> s.getColor() == BLUE)
.map(Shape::getWeight)
.sum();
Bulk operations on Collections
• The new bulk operations are expressive and composible
– Each stage does one thing
– Compose compound operations from basic building blocks
– Client code reads more like the problem statement
– Structure of client code is less brittle
– Less extraneous “noise” from intermediate results
– Library can use parallelism, out-of-order, laziness for performance
Laziness
• When does the computation occur?
– Eager – computation is done when we return from call
– Lazy – computation happens when we need the result
• Many operations, like filter, can be implemented either lazily or
eagerly
• Iterators are inherently lazy
• Laziness can be more efficient if you’re not going to use all the results
– “Find the first element that matches this criteria”
– Can stop after it finds one
Streams
• To add bulk operations, we create a new abstraction, Stream
– Represents a stream of values
• Not a data structure – doesn’t store the values
– Source can be a Collection, array, generating function, I/O…
– Operations that produce new streams are lazy
– Encourages a “fluent” usage style
Stream<Foo> fooStream = collection.stream();
Stream<Foo> filtered = fooStream.filter(f -> f.isBlue());
Stream<Bar> mapped = filtered.map(f -> f.getBar());
mapped.forEach(System.out::println);
collection.stream()
.filter(f -> f.isBlue())
.map(f -> f.getBar())
.forEach(System.out::println);
Streams
• Operations are divided between intermediate and terminal
– No computation happens until you hit the terminal operation
– Library then commits to an implementation strategy
interface Stream<T> {
...
Stream<T> filter(Predicate<T> predicate);
<U> Stream<U> map(Mapper<T,U> mapper);
<U> Stream<U> flatMap(FlatMapper<T,U> mapper);
...
}
interface Stream<T> {
...
Stream<T> distinct();
Stream<T> sorted(Comparator<? Super T> cmp);
Stream<T> limit(int n);
Stream<T> skip(int n);
Stream<T> concat(Stream<? extends> T> other);
...
}
interface Stream<T> {
...
void forEach(Block<? super T> block);
<A extends Destination<? super T>> A into(A target);
T[] toArray(Class<T> classToken);
<R> R collect(Collector<T,R> collector);
Optional<T> findFirst();
Optional<T> findAny();
...
}
Advanced Example: Aggregation
• Problem: select author, sum(pages) from documents group by
author
Map<String, Integer> map = new HashMap<>();
for (Document d : documents) {
String author = d.getAuthor();
Integer i = map.get(author);
if (i == null)
i = 0;
map.put(author, i + d.getPageCount());
}
Map<String, Integer> map =
documents.stream. collect(
groupingBy(Document::getAuthor,
reducing(0,
Document::getPageCount, Integer::sum)));
Streams and Laziness
• Operations tend to be combined into pipelines of source-lazy*-
eager
– collection-filter-map-sum
– array-map-sorted-forEach
• Streams are essentially lazy collections – compute as elements
are needed
– Pays off big in cases like filter-map-findFirst
– Laziness is mostly invisible (no new LazyList, LazySet, etc)
– Enables short-circuiting, operation fusing
Parallelism
• Goal: easy-to-use parallel libraries for Java
– Libraries can hide a host of complex concerns (task scheduling, thread
management, load balancing)
• Goal: reduce conceptual and syntactic gap between serial and
parallel expressions of the same computation
– Right now, the serial code and the parallel code for a given computation
don’t look anything like each other
– Fork-join (added in Java SE 7) is a good start, but not enough
• Goal: parallelism should be explicit, but unobtrusive
Fork/Join Parallelism
• JDK7 adds general-purpose Fork/Join framework
– Powerful and efficient, but not so easy to program to
– Based on recursive decomposition
• Divide problem into sub-problems, solve in parallel, combine results
• Keep dividing until small enough to solve sequentially
– Tends to be efficient across a wide range of processor counts
– Generates reasonable load balancing with no central coordination
Fork/Join Parallelism
Result solve(Problem p) {
if (p.size() < SMALL_ENOUGH)
return p.solveSequentially();
else {
Problem left = p.extractLeftHalf();
Problem right = p.extractRightHalf();
IN_PARALLEL {
solve(left);
solve(right);
}
return combine(left, right);
}
}
Parallel Sum with Fork/Join
class SumProblem {
final List<Shape> shapes;
final int size;
SumProblem(List<Shape> ls) {
this.shapes = ls;
size = ls.size();
}
public int solveSequentially() {
int sum = 0;
for (Shape s : shapes) {
if (s.getColor() == BLUE)
sum += s.getWeight();
}
return sum;
}
public SumProblem subproblem(int start, int end) {
return new SumProblem(shapes.subList(start, end));
}
}
ForkJoinExecutor pool = new ForkJoinPool(nThreads);
SumProblem finder = new SumProblem(problem);
pool.invoke(finder);
class SumFinder extends RecursiveAction {
private final SumProblem problem;
int sum;
protected void compute() {
if (problem.size < THRESHOLD)
sum = problem.solveSequentially();
else {
int m = problem.size / 2;
SumFinder left, right;
left = new SumFinder(problem.subproblem(0, m))
right = new SumFinder(problem.subproblem(m, problem.size));
forkJoin(left, right);
sum = left.sum + right.sum;
}
}
}
Parallel Sum with Collections
• Parallel sum-of-sizes with bulk collection operations
– Explicit but unobtrusive parallelism
– All three operations fused into a single parallel pass
int sumOfWeight
= shapes.parallel()
.filter(s -> s.getColor() == BLUE)
.map(Shape::getWeight)
.sum();
Parallel Streams
• A stream can execute either in serial or parallel
– Determined by stream source
• Collection.stream()
• Collection.parallel()
• Some data structures decompose better than others
– Arrays decompose better than linked lists
– Data structure contributes decomposition strategy
– Parallel stream ops can run against any decomposible data structure
Decomposition
• The parallel analogue of Iterator is … Spliterator
– Defines decomposition strategy for data structure
public interface Spliterator<T> {
Spliterator<T> trySplit();
Iterator<T> iterator();
default int getSizeIfKnown();
default int estimateSize();
}
Lambdas Enable Better APIs
• Lambda expressions enable delivery of more powerful APIs
• The boundary between client and library is more permeable
– Client can provide bits of functionality to be mixed into execution
– Library remains in control of the computation
– Safer, exposes more opportunities for optimization
Example: Sorting
• If we want to sort a List today, we’d write a Comparator
– Comparator conflates extraction of sort key with ordering of that key
• Can replace Comparator with a lambda, but only gets us so far
– Better to separate the two aspects
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
return x.getLastName().compareTo(y.getLastName());
}
});
Example: Sorting
• Lambdas encourage finer-grained APIs
– We add a method that takes a “key extractor” and returns Comparator
– Multiple versions: Comparable objects, ints, longs, etc
Comparator<Person> byLastName
= Comparators.comparing(p -> p.getLastName());
Class Comparators {
public static<T, U extends Comparable<? super U>>
Comparator<T> comparing(Mapper<T, U> m) {
return (x, y) -> m.map(x).compareTo(m.map(y));
}
}
Example: Sorting
Comparator<Person> byLastName
= Comparators.comparing(p -> p.getLastName());
Collections.sort(people, byLastName);
Collections.sort(people, comparing(p -> p.getLastName());
people.sort(comparing(p -> p.getLastName());
people.sort(comparing(Person::getLastName));
people.sort(comparing(Person::getLastName).reversed());
people.sort(comparing(Person::getLastName)
.andThen(comparing(Person::getFirstName)));
Lambdas Enable Better APIs
• The comparing() method is one built for lambdas
– Consumes an “extractor” function and produces a “comparator” function
– Factors out key extraction from comparison
– Eliminates redundancy, boilerplate
• Key effect on APIs is: more composability
– Leads to better factoring, more regular client code, more reuse
• Lambdas in the languages
→ can write better libraries
→ more readable, less error-prone user code
Lambdas Enable Better APIs
• Generally, we prefer to evolve the programming model through
libraries
– Time to market – can evolve libraries faster than language
– Decentralized – more library developers than language developers
– Risk – easier to change libraries, more practical to experiment
– Impact – language changes require coordinated changes to multiple
compilers, IDEs, and other tools
• But sometimes we reach the limits of what is practical to
express in libraries, and need a little help from the language
– But a little help, in the right places, can go a long way!
So … Why Lambda?
• It’s about time!
– Java is the lone holdout among mainstream OO languages at this point to
not have closures
– Adding closures to Java is no longer a radical idea
• Provide libraries a path to multicore
– Parallel-friendly APIs need internal iteration
– Internal iteration needs a concise code-as-data mechanism
• Empower library developers
– More powerful, flexible libraries
– Higher degree of cooperation between libraries and client code
Where are we now?
• EDR #3 spec draft available at
http://openjdk.java.net/projects/lambda/
• RI Binary drops available at http://jdk8.java.net/lambda
– Download them and try them out!
• Shipping with Java SE 8, Spring 2014

More Related Content

What's hot

Clojure - An Introduction for Java Programmers
Clojure - An Introduction for Java ProgrammersClojure - An Introduction for Java Programmers
Clojure - An Introduction for Java Programmerselliando dias
 
JDK8 Lambdas and Streams: Changing The Way You Think When Developing Java
JDK8 Lambdas and Streams: Changing The Way You Think When Developing JavaJDK8 Lambdas and Streams: Changing The Way You Think When Developing Java
JDK8 Lambdas and Streams: Changing The Way You Think When Developing JavaSimon Ritter
 
Clojure - An Introduction for Lisp Programmers
Clojure - An Introduction for Lisp ProgrammersClojure - An Introduction for Lisp Programmers
Clojure - An Introduction for Lisp Programmerselliando dias
 
55 New Features in Java SE 8
55 New Features in Java SE 855 New Features in Java SE 8
55 New Features in Java SE 8Simon Ritter
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to ScalaRahul Jain
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Martin Odersky
 
Java SE 8 - New Features
Java SE 8 - New FeaturesJava SE 8 - New Features
Java SE 8 - New FeaturesNaveen Hegde
 
Clojure talk at Münster JUG
Clojure talk at Münster JUGClojure talk at Münster JUG
Clojure talk at Münster JUGAlex Ott
 
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7Deniz Oguz
 
Introduction to Clojure
Introduction to ClojureIntroduction to Clojure
Introduction to ClojureRenzo Borgatti
 
Python first day
Python first dayPython first day
Python first dayfarkhand
 
Java 8 - Features Overview
Java 8 - Features OverviewJava 8 - Features Overview
Java 8 - Features OverviewSergii Stets
 
JSR 335 / java 8 - update reference
JSR 335 / java 8 - update referenceJSR 335 / java 8 - update reference
JSR 335 / java 8 - update referencesandeepji_choudhary
 
Java 8 selected updates
Java 8 selected updatesJava 8 selected updates
Java 8 selected updatesVinay H G
 
Clojure A Dynamic Programming Language for the JVM
Clojure A Dynamic Programming Language for the JVMClojure A Dynamic Programming Language for the JVM
Clojure A Dynamic Programming Language for the JVMelliando dias
 

What's hot (20)

Clojure - An Introduction for Java Programmers
Clojure - An Introduction for Java ProgrammersClojure - An Introduction for Java Programmers
Clojure - An Introduction for Java Programmers
 
JDK8 Lambdas and Streams: Changing The Way You Think When Developing Java
JDK8 Lambdas and Streams: Changing The Way You Think When Developing JavaJDK8 Lambdas and Streams: Changing The Way You Think When Developing Java
JDK8 Lambdas and Streams: Changing The Way You Think When Developing Java
 
Clojure - An Introduction for Lisp Programmers
Clojure - An Introduction for Lisp ProgrammersClojure - An Introduction for Lisp Programmers
Clojure - An Introduction for Lisp Programmers
 
55 New Features in Java SE 8
55 New Features in Java SE 855 New Features in Java SE 8
55 New Features in Java SE 8
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Quick introduction to scala
Quick introduction to scalaQuick introduction to scala
Quick introduction to scala
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009
 
Java SE 8 - New Features
Java SE 8 - New FeaturesJava SE 8 - New Features
Java SE 8 - New Features
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Lambdas in Java 8
Lambdas in Java 8Lambdas in Java 8
Lambdas in Java 8
 
Clojure talk at Münster JUG
Clojure talk at Münster JUGClojure talk at Münster JUG
Clojure talk at Münster JUG
 
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
 
Introduction to Clojure
Introduction to ClojureIntroduction to Clojure
Introduction to Clojure
 
Introduction to new features in java 8
Introduction to new features in java 8Introduction to new features in java 8
Introduction to new features in java 8
 
Python first day
Python first dayPython first day
Python first day
 
Python first day
Python first dayPython first day
Python first day
 
Java 8 - Features Overview
Java 8 - Features OverviewJava 8 - Features Overview
Java 8 - Features Overview
 
JSR 335 / java 8 - update reference
JSR 335 / java 8 - update referenceJSR 335 / java 8 - update reference
JSR 335 / java 8 - update reference
 
Java 8 selected updates
Java 8 selected updatesJava 8 selected updates
Java 8 selected updates
 
Clojure A Dynamic Programming Language for the JVM
Clojure A Dynamic Programming Language for the JVMClojure A Dynamic Programming Language for the JVM
Clojure A Dynamic Programming Language for the JVM
 

Viewers also liked

The Play Framework at LinkedIn: productivity and performance at scale - Jim B...
The Play Framework at LinkedIn: productivity and performance at scale - Jim B...The Play Framework at LinkedIn: productivity and performance at scale - Jim B...
The Play Framework at LinkedIn: productivity and performance at scale - Jim B...jaxconf
 
Apache TomEE, Java EE 6 Web Profile on Tomcat - David Blevins
Apache TomEE, Java EE 6 Web Profile on Tomcat - David BlevinsApache TomEE, Java EE 6 Web Profile on Tomcat - David Blevins
Apache TomEE, Java EE 6 Web Profile on Tomcat - David Blevinsjaxconf
 
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...jaxconf
 
How cloud and in memory computing revolutionised enterprise development - Ste...
How cloud and in memory computing revolutionised enterprise development - Ste...How cloud and in memory computing revolutionised enterprise development - Ste...
How cloud and in memory computing revolutionised enterprise development - Ste...jaxconf
 
The lean startup for enterprise Java developers - Peter Bell
The lean startup for enterprise Java developers - Peter BellThe lean startup for enterprise Java developers - Peter Bell
The lean startup for enterprise Java developers - Peter Belljaxconf
 
Cloud development goes lightweight - Ken Walker
Cloud development goes lightweight - Ken WalkerCloud development goes lightweight - Ken Walker
Cloud development goes lightweight - Ken Walkerjaxconf
 
Creating Data Driven Web Apps with BIRT - Michael Williams
Creating Data Driven Web Apps with BIRT - Michael WilliamsCreating Data Driven Web Apps with BIRT - Michael Williams
Creating Data Driven Web Apps with BIRT - Michael Williamsjaxconf
 
CPU Caches - Jamie Allen
CPU Caches - Jamie AllenCPU Caches - Jamie Allen
CPU Caches - Jamie Allenjaxconf
 
Living on the edge at Netflix - Adrian Cole
Living on the edge at Netflix - Adrian ColeLiving on the edge at Netflix - Adrian Cole
Living on the edge at Netflix - Adrian Colejaxconf
 
Considerations for using NoSQL technology on your next IT project - Akmal Cha...
Considerations for using NoSQL technology on your next IT project - Akmal Cha...Considerations for using NoSQL technology on your next IT project - Akmal Cha...
Considerations for using NoSQL technology on your next IT project - Akmal Cha...jaxconf
 
Beautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les HazlewoodBeautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les Hazlewoodjaxconf
 
Mocha Raspberry Pi hacking - Stephen Chin
Mocha Raspberry Pi hacking - Stephen ChinMocha Raspberry Pi hacking - Stephen Chin
Mocha Raspberry Pi hacking - Stephen Chinjaxconf
 
JavaScript: Your New Overlord
JavaScript: Your New OverlordJavaScript: Your New Overlord
JavaScript: Your New Overlordjaxconf
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chinjaxconf
 
Writing Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason LeeWriting Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason Leejaxconf
 
The Brave New World of Continuous Release - Baruch Sadogursky
The Brave New World of Continuous Release - Baruch SadogurskyThe Brave New World of Continuous Release - Baruch Sadogursky
The Brave New World of Continuous Release - Baruch Sadogurskyjaxconf
 
Java EE Web Security By Example: Frank Kim
Java EE Web Security By Example: Frank KimJava EE Web Security By Example: Frank Kim
Java EE Web Security By Example: Frank Kimjaxconf
 
Interview in Kwaliteit in Bedrijf december 2015
Interview in Kwaliteit in Bedrijf december 2015Interview in Kwaliteit in Bedrijf december 2015
Interview in Kwaliteit in Bedrijf december 2015Edo Peet
 
Mikratul jannah baru
Mikratul jannah baruMikratul jannah baru
Mikratul jannah baruPaarief Udin
 
Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?
Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?
Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?Health Evidence™
 

Viewers also liked (20)

The Play Framework at LinkedIn: productivity and performance at scale - Jim B...
The Play Framework at LinkedIn: productivity and performance at scale - Jim B...The Play Framework at LinkedIn: productivity and performance at scale - Jim B...
The Play Framework at LinkedIn: productivity and performance at scale - Jim B...
 
Apache TomEE, Java EE 6 Web Profile on Tomcat - David Blevins
Apache TomEE, Java EE 6 Web Profile on Tomcat - David BlevinsApache TomEE, Java EE 6 Web Profile on Tomcat - David Blevins
Apache TomEE, Java EE 6 Web Profile on Tomcat - David Blevins
 
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
 
How cloud and in memory computing revolutionised enterprise development - Ste...
How cloud and in memory computing revolutionised enterprise development - Ste...How cloud and in memory computing revolutionised enterprise development - Ste...
How cloud and in memory computing revolutionised enterprise development - Ste...
 
The lean startup for enterprise Java developers - Peter Bell
The lean startup for enterprise Java developers - Peter BellThe lean startup for enterprise Java developers - Peter Bell
The lean startup for enterprise Java developers - Peter Bell
 
Cloud development goes lightweight - Ken Walker
Cloud development goes lightweight - Ken WalkerCloud development goes lightweight - Ken Walker
Cloud development goes lightweight - Ken Walker
 
Creating Data Driven Web Apps with BIRT - Michael Williams
Creating Data Driven Web Apps with BIRT - Michael WilliamsCreating Data Driven Web Apps with BIRT - Michael Williams
Creating Data Driven Web Apps with BIRT - Michael Williams
 
CPU Caches - Jamie Allen
CPU Caches - Jamie AllenCPU Caches - Jamie Allen
CPU Caches - Jamie Allen
 
Living on the edge at Netflix - Adrian Cole
Living on the edge at Netflix - Adrian ColeLiving on the edge at Netflix - Adrian Cole
Living on the edge at Netflix - Adrian Cole
 
Considerations for using NoSQL technology on your next IT project - Akmal Cha...
Considerations for using NoSQL technology on your next IT project - Akmal Cha...Considerations for using NoSQL technology on your next IT project - Akmal Cha...
Considerations for using NoSQL technology on your next IT project - Akmal Cha...
 
Beautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les HazlewoodBeautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les Hazlewood
 
Mocha Raspberry Pi hacking - Stephen Chin
Mocha Raspberry Pi hacking - Stephen ChinMocha Raspberry Pi hacking - Stephen Chin
Mocha Raspberry Pi hacking - Stephen Chin
 
JavaScript: Your New Overlord
JavaScript: Your New OverlordJavaScript: Your New Overlord
JavaScript: Your New Overlord
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
 
Writing Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason LeeWriting Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason Lee
 
The Brave New World of Continuous Release - Baruch Sadogursky
The Brave New World of Continuous Release - Baruch SadogurskyThe Brave New World of Continuous Release - Baruch Sadogursky
The Brave New World of Continuous Release - Baruch Sadogursky
 
Java EE Web Security By Example: Frank Kim
Java EE Web Security By Example: Frank KimJava EE Web Security By Example: Frank Kim
Java EE Web Security By Example: Frank Kim
 
Interview in Kwaliteit in Bedrijf december 2015
Interview in Kwaliteit in Bedrijf december 2015Interview in Kwaliteit in Bedrijf december 2015
Interview in Kwaliteit in Bedrijf december 2015
 
Mikratul jannah baru
Mikratul jannah baruMikratul jannah baru
Mikratul jannah baru
 
Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?
Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?
Health-evidence.ca to Healthevidence.org: What's New in Public Health Reviews?
 

Similar to The Road to Lambda - Mike Duigou

Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8IndicThreads
 
Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8Simon Ritter
 
Java 8 - Project Lambda
Java 8 - Project LambdaJava 8 - Project Lambda
Java 8 - Project LambdaRahman USTA
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streamsjessitron
 
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?Chuk-Munn Lee
 
pull requests I sent to scala/scala (ny-scala 2019)
pull requests I sent to scala/scala (ny-scala 2019)pull requests I sent to scala/scala (ny-scala 2019)
pull requests I sent to scala/scala (ny-scala 2019)Eugene Yokota
 
Lambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon Ritter
Lambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon RitterLambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon Ritter
Lambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon RitterJAXLondon2014
 
Lambdas And Streams in JDK8
Lambdas And Streams in JDK8Lambdas And Streams in JDK8
Lambdas And Streams in JDK8Simon Ritter
 
Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & StreamsC4Media
 
Java Closures
Java ClosuresJava Closures
Java ClosuresBen Evans
 
Scala in the Wild
Scala in the WildScala in the Wild
Scala in the WildTomer Gabel
 
Spark - The Ultimate Scala Collections by Martin Odersky
Spark - The Ultimate Scala Collections by Martin OderskySpark - The Ultimate Scala Collections by Martin Odersky
Spark - The Ultimate Scala Collections by Martin OderskySpark Summit
 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...jaxLondonConference
 
Java jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3mJava jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3mSteve Elliott
 
Scala final ppt vinay
Scala final ppt vinayScala final ppt vinay
Scala final ppt vinayViplav Jain
 

Similar to The Road to Lambda - Mike Duigou (20)

Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8
 
Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8
 
Java 8 - Project Lambda
Java 8 - Project LambdaJava 8 - Project Lambda
Java 8 - Project Lambda
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streams
 
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
pull requests I sent to scala/scala (ny-scala 2019)
pull requests I sent to scala/scala (ny-scala 2019)pull requests I sent to scala/scala (ny-scala 2019)
pull requests I sent to scala/scala (ny-scala 2019)
 
Java8
Java8Java8
Java8
 
Apouc 2014-java-8-create-the-future
Apouc 2014-java-8-create-the-futureApouc 2014-java-8-create-the-future
Apouc 2014-java-8-create-the-future
 
Lambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon Ritter
Lambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon RitterLambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon Ritter
Lambdas and Streams in Java SE 8: Making Bulk Operations simple - Simon Ritter
 
Lambdas And Streams in JDK8
Lambdas And Streams in JDK8Lambdas And Streams in JDK8
Lambdas And Streams in JDK8
 
Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & Streams
 
10-DesignPatterns.ppt
10-DesignPatterns.ppt10-DesignPatterns.ppt
10-DesignPatterns.ppt
 
Java Closures
Java ClosuresJava Closures
Java Closures
 
Java 8
Java 8Java 8
Java 8
 
Scala in the Wild
Scala in the WildScala in the Wild
Scala in the Wild
 
Spark - The Ultimate Scala Collections by Martin Odersky
Spark - The Ultimate Scala Collections by Martin OderskySpark - The Ultimate Scala Collections by Martin Odersky
Spark - The Ultimate Scala Collections by Martin Odersky
 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
 
Java jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3mJava jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3m
 
Scala final ppt vinay
Scala final ppt vinayScala final ppt vinay
Scala final ppt vinay
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 

Recently uploaded (20)

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 

The Road to Lambda - Mike Duigou

  • 1. The Road to Lambda Mike Duigou | Oracle
  • 2. The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
  • 3. Modernizing Java • Java SE 8 is a big step forward in modernizing the Java Language – Lambda Expressions (closures) – Interface Evolution (default methods) • Java SE 8 is a big step forward in modernizing the Java Libraries – Bulk data operations on Collections – More library support for parallelism • Together, perhaps the biggest upgrade ever to the Java programming model
  • 4. What is a Lambda Expression? • A lambda expression (closure) is an anonymous method – Has an argument list, a return type, and a body (Object o) -> o.toString() – Can refer to values from the enclosing lexical scope (Person p) -> p.getName().equals(name) • A method reference is a reference to an existing method Object::toString • Allow you to treat code as data – Behavior can be stored in variables and passed to methods
  • 5. Times change • In 1995, most popular languages did not support closures • Today, Java is just about the last holdout that does not – C++ added them recently – C# added them in 3.0 – New languages being designed today all do “In another thirty years people will laugh at anyone who tries to invent a language without closures, just as they'll laugh now at anyone who tries to invent a language without recursion.” -Mark Jason Dominus
  • 6. Closures for Java – a long and winding road • 1997 – Odersky/Wadler experimental “Pizza” work • 1997 – Java 1.1 added inner classes – a weak form of closures – Too bulky, complex name resolution rules, many limitations • In 2006-2008, a vigorous community debate about closures – Multiple proposals, including BGGA and CICE – Each had a different orientation • BGGA was focused on creating control abstraction in libraries • CICE was focused on reducing the syntactic overhead of inner classes – Things ran aground at this point…
  • 7. Closures for Java – a long and winding road • Dec 2009 – OpenJDK Project Lambda formed • November 2010 – JSR-335 filed • Current status – EDR specification complete – Prototype (source and binary) available on OpenJDK – Part of Java SE 8 (Spring 2014) • JSR-335 = Lambda Expressions + Interface Evolution + Bulk Collection Operations
  • 8. External Iteration • Snippet takes the red blocks and colors them blue • Uses foreach loop – Loop is inherently sequential – Client has to manage iteration • This is called external iteration • Foreach loop hides complex interaction between library and client for (Shape s : shapes) { if (s.getColor() == RED) s.setColor(BLUE); }
  • 9. Lambda Expressions • Re-written to use lambda and Collection.forEach – Not just a syntactic change! – Now the library is in control – This is internal iteration – More what, less how • Library free to use parallelism, out-of-order execution, laziness • Client passes behavior into the API as data • Enables API designers to build more powerful, expressive APIs – Greater power to abstract over behavior shapes.forEach(s -> { if (s.getColor() == RED) s.setColor(BLUE); })
  • 10. Functional Interfaces • What is the type of a lambda expression or method reference? – Historically we’ve used single-method interfaces to represent functions • Runnable, Comparator, ActionListener – Let’s give these a name: functional interfaces – And add some new ones like Predicate<T>, Consumer<T> • A lambda expression evaluates to an instance of a functional interface Predicate<String> isEmpty = s -> s.isEmpty(); Predicate<String> isEmpty = String::isEmpty; Runnable r = () -> { System.out.println(“Boo!”) }; • So existing libraries are forward-compatible to lambdas – Maintains significant investment in existing libraries
  • 11. Interface Evolution • The example used a new Collection method – forEach() – Where did that come from? – I thought you couldn’t add new methods to interfaces? – New feature: default methods • Virtual method with default implementation • Libraries need to evolve! • Default methods let us compatibly evolve libraries over time interface Collection<T> { default void forEach(Consumer<T> action) { for (T t : this) action.apply(t); } }
  • 12. Interface Evolution • Interfaces are a double-edged sword – Cannot compatibly evolve them unless you control all implementations – Reality: APIs age • As we add cool new language features, existing APIs look even older! – Lots of bad options for dealing with aging APIs • Let the API stagnate • Replace it in entirety (every few years!) • Nail bags on the side (e.g., Collections.sort()) • Burden of API evolution should fall to implementors, not users
  • 13. Default Methods • A default method provides an implementation in the interface • Wait, is this multiple inheritance in Java? – Java always had multiple inheritance of types – This adds multiple inheritance of behavior • But no inheritance of state, where most of the trouble comes from • Some similarity (and differences) with C# extension methods – Default methods are virtual and declaration-site • Primary goal is API evolution – But useful as an inheritance mechanism on its own
  • 14. Default Methods – Evolving Interfaces • New Collection methods – forEach(Consumer) – removeIf(Predicate) • Subclasses may provide better implementations • Defaults implemented in terms of other interface methods interface Collection<E> { default void forEach(Consumer<E> action) { for (E e : this) action.apply(e); } default boolean removeIf(Predicate<? super E> filter) { boolean removed = false; Iterator<E> each = iterator(); while(each.hasNext()) { if(filter.test(each.next())) { each.remove(); removed = true; } } return removed; } }
  • 15. Default Methods – Optional methods • Default methods can reduce implementation burden • Most implementations of Iterator don’t provide a useful remove() – So why make developer write one that throws? – Default methods can be used to declare “optional” methods interface Iterator<T> { boolean hasNext(); T next(); default void remove() { throw new UnsupportedOperationException(); } }
  • 16. interface Comparator<T> { int compare(T o1, T o2); default Comparator<T> reverse() { return (o1, o2) -> compare(o2, o1); } default Comparator<T> compose(Comparator<T> other) { return (o1, o2) -> { int cmp = compare(o1, o2); return cmp != 0 ? cmp : other.compare(o1, o2); } } } Default Methods – Combinators • Comparator.reverse() –reverses order of a Comparator • Comparator.compose() – computes “dictionary order” between one Comparator and another Comparator<Person> byFirst = ... Comparator<Person> byLast = ... Comparator<Person> byFirstLast = byFirst.compose(byLast); Comparator<Person> byLastDescending = byLast.reverse();
  • 17. Bulk operations on Collections • The lambda version of the “shapes” code can be further decomposed • We have added other bulk operations, such as filter, map, into • “Color the red blocks blue” can be decomposed into filter+forEach shapes.stream() .filter(s -> s.getColor() == RED) .forEach(s -> { s.setColor(BLUE); }); shapes.forEach(s -> { if (s.getColor() == RED) s.setColor(BLUE); })
  • 18. Bulk operations on Collections • Collect the blue Shapes into a List • If each Shape lives in a Box, find Boxes containing blue shape List<Shape> blueBlocks = shapes.stream() .filter(s -> s.getColor() == BLUE) .collect(Collectors.toList()); Set<Box> hasBlueBlock = shapes.stream() .filter(s -> s.getColor() == BLUE) .map(s -> s.getContainingBox()) .collect(Collectors.toSet());
  • 19. Bulk operations on Collections • Compute sum of weights of blue shapes • Alternately, with method references: int sumOfWeight = shapes.stream() .filter(s -> s.getColor() == BLUE) .map(s -> s.getWeight()) .sum(); int sumOfWeight = shapes.stream() .filter(s -> s.getColor() == BLUE) .map(Shape::getWeight) .sum();
  • 20. Bulk operations on Collections • The new bulk operations are expressive and composible – Each stage does one thing – Compose compound operations from basic building blocks – Client code reads more like the problem statement – Structure of client code is less brittle – Less extraneous “noise” from intermediate results – Library can use parallelism, out-of-order, laziness for performance
  • 21. Laziness • When does the computation occur? – Eager – computation is done when we return from call – Lazy – computation happens when we need the result • Many operations, like filter, can be implemented either lazily or eagerly • Iterators are inherently lazy • Laziness can be more efficient if you’re not going to use all the results – “Find the first element that matches this criteria” – Can stop after it finds one
  • 22. Streams • To add bulk operations, we create a new abstraction, Stream – Represents a stream of values • Not a data structure – doesn’t store the values – Source can be a Collection, array, generating function, I/O… – Operations that produce new streams are lazy – Encourages a “fluent” usage style Stream<Foo> fooStream = collection.stream(); Stream<Foo> filtered = fooStream.filter(f -> f.isBlue()); Stream<Bar> mapped = filtered.map(f -> f.getBar()); mapped.forEach(System.out::println); collection.stream() .filter(f -> f.isBlue()) .map(f -> f.getBar()) .forEach(System.out::println);
  • 23. Streams • Operations are divided between intermediate and terminal – No computation happens until you hit the terminal operation – Library then commits to an implementation strategy interface Stream<T> { ... Stream<T> filter(Predicate<T> predicate); <U> Stream<U> map(Mapper<T,U> mapper); <U> Stream<U> flatMap(FlatMapper<T,U> mapper); ... } interface Stream<T> { ... Stream<T> distinct(); Stream<T> sorted(Comparator<? Super T> cmp); Stream<T> limit(int n); Stream<T> skip(int n); Stream<T> concat(Stream<? extends> T> other); ... } interface Stream<T> { ... void forEach(Block<? super T> block); <A extends Destination<? super T>> A into(A target); T[] toArray(Class<T> classToken); <R> R collect(Collector<T,R> collector); Optional<T> findFirst(); Optional<T> findAny(); ... }
  • 24. Advanced Example: Aggregation • Problem: select author, sum(pages) from documents group by author Map<String, Integer> map = new HashMap<>(); for (Document d : documents) { String author = d.getAuthor(); Integer i = map.get(author); if (i == null) i = 0; map.put(author, i + d.getPageCount()); } Map<String, Integer> map = documents.stream. collect( groupingBy(Document::getAuthor, reducing(0, Document::getPageCount, Integer::sum)));
  • 25. Streams and Laziness • Operations tend to be combined into pipelines of source-lazy*- eager – collection-filter-map-sum – array-map-sorted-forEach • Streams are essentially lazy collections – compute as elements are needed – Pays off big in cases like filter-map-findFirst – Laziness is mostly invisible (no new LazyList, LazySet, etc) – Enables short-circuiting, operation fusing
  • 26. Parallelism • Goal: easy-to-use parallel libraries for Java – Libraries can hide a host of complex concerns (task scheduling, thread management, load balancing) • Goal: reduce conceptual and syntactic gap between serial and parallel expressions of the same computation – Right now, the serial code and the parallel code for a given computation don’t look anything like each other – Fork-join (added in Java SE 7) is a good start, but not enough • Goal: parallelism should be explicit, but unobtrusive
  • 27. Fork/Join Parallelism • JDK7 adds general-purpose Fork/Join framework – Powerful and efficient, but not so easy to program to – Based on recursive decomposition • Divide problem into sub-problems, solve in parallel, combine results • Keep dividing until small enough to solve sequentially – Tends to be efficient across a wide range of processor counts – Generates reasonable load balancing with no central coordination
  • 28. Fork/Join Parallelism Result solve(Problem p) { if (p.size() < SMALL_ENOUGH) return p.solveSequentially(); else { Problem left = p.extractLeftHalf(); Problem right = p.extractRightHalf(); IN_PARALLEL { solve(left); solve(right); } return combine(left, right); } }
  • 29. Parallel Sum with Fork/Join class SumProblem { final List<Shape> shapes; final int size; SumProblem(List<Shape> ls) { this.shapes = ls; size = ls.size(); } public int solveSequentially() { int sum = 0; for (Shape s : shapes) { if (s.getColor() == BLUE) sum += s.getWeight(); } return sum; } public SumProblem subproblem(int start, int end) { return new SumProblem(shapes.subList(start, end)); } } ForkJoinExecutor pool = new ForkJoinPool(nThreads); SumProblem finder = new SumProblem(problem); pool.invoke(finder); class SumFinder extends RecursiveAction { private final SumProblem problem; int sum; protected void compute() { if (problem.size < THRESHOLD) sum = problem.solveSequentially(); else { int m = problem.size / 2; SumFinder left, right; left = new SumFinder(problem.subproblem(0, m)) right = new SumFinder(problem.subproblem(m, problem.size)); forkJoin(left, right); sum = left.sum + right.sum; } } }
  • 30. Parallel Sum with Collections • Parallel sum-of-sizes with bulk collection operations – Explicit but unobtrusive parallelism – All three operations fused into a single parallel pass int sumOfWeight = shapes.parallel() .filter(s -> s.getColor() == BLUE) .map(Shape::getWeight) .sum();
  • 31. Parallel Streams • A stream can execute either in serial or parallel – Determined by stream source • Collection.stream() • Collection.parallel() • Some data structures decompose better than others – Arrays decompose better than linked lists – Data structure contributes decomposition strategy – Parallel stream ops can run against any decomposible data structure
  • 32. Decomposition • The parallel analogue of Iterator is … Spliterator – Defines decomposition strategy for data structure public interface Spliterator<T> { Spliterator<T> trySplit(); Iterator<T> iterator(); default int getSizeIfKnown(); default int estimateSize(); }
  • 33. Lambdas Enable Better APIs • Lambda expressions enable delivery of more powerful APIs • The boundary between client and library is more permeable – Client can provide bits of functionality to be mixed into execution – Library remains in control of the computation – Safer, exposes more opportunities for optimization
  • 34. Example: Sorting • If we want to sort a List today, we’d write a Comparator – Comparator conflates extraction of sort key with ordering of that key • Can replace Comparator with a lambda, but only gets us so far – Better to separate the two aspects Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getLastName().compareTo(y.getLastName()); } });
  • 35. Example: Sorting • Lambdas encourage finer-grained APIs – We add a method that takes a “key extractor” and returns Comparator – Multiple versions: Comparable objects, ints, longs, etc Comparator<Person> byLastName = Comparators.comparing(p -> p.getLastName()); Class Comparators { public static<T, U extends Comparable<? super U>> Comparator<T> comparing(Mapper<T, U> m) { return (x, y) -> m.map(x).compareTo(m.map(y)); } }
  • 36. Example: Sorting Comparator<Person> byLastName = Comparators.comparing(p -> p.getLastName()); Collections.sort(people, byLastName); Collections.sort(people, comparing(p -> p.getLastName()); people.sort(comparing(p -> p.getLastName()); people.sort(comparing(Person::getLastName)); people.sort(comparing(Person::getLastName).reversed()); people.sort(comparing(Person::getLastName) .andThen(comparing(Person::getFirstName)));
  • 37. Lambdas Enable Better APIs • The comparing() method is one built for lambdas – Consumes an “extractor” function and produces a “comparator” function – Factors out key extraction from comparison – Eliminates redundancy, boilerplate • Key effect on APIs is: more composability – Leads to better factoring, more regular client code, more reuse • Lambdas in the languages → can write better libraries → more readable, less error-prone user code
  • 38. Lambdas Enable Better APIs • Generally, we prefer to evolve the programming model through libraries – Time to market – can evolve libraries faster than language – Decentralized – more library developers than language developers – Risk – easier to change libraries, more practical to experiment – Impact – language changes require coordinated changes to multiple compilers, IDEs, and other tools • But sometimes we reach the limits of what is practical to express in libraries, and need a little help from the language – But a little help, in the right places, can go a long way!
  • 39. So … Why Lambda? • It’s about time! – Java is the lone holdout among mainstream OO languages at this point to not have closures – Adding closures to Java is no longer a radical idea • Provide libraries a path to multicore – Parallel-friendly APIs need internal iteration – Internal iteration needs a concise code-as-data mechanism • Empower library developers – More powerful, flexible libraries – Higher degree of cooperation between libraries and client code
  • 40. Where are we now? • EDR #3 spec draft available at http://openjdk.java.net/projects/lambda/ • RI Binary drops available at http://jdk8.java.net/lambda – Download them and try them out! • Shipping with Java SE 8, Spring 2014

Editor's Notes

  1. Bigger than generics – really! Just as generics allowed libraries to abstract better over types, lambdas allow libraries to abstract better over behavior
  2. This may not seem like a big deal, but in reality it is a HUGE deal, because of the impact it has on library design.
  3. It is hard to see why loops are bad when it is the only tool we have for aggregate operations! The essential problem with this code is that it conflates the “what” – change the red blocks to blue – with the “how”. This is so second-nature to us that we don’t even notice.But in today’s multicore world, a language construct that is inherently sequential is a significant problem.
  4. Note that lambda infers type of s
  5. Powerful type inference – get type from context
  6. If Java had closures in 1997, our Collections would surely look differentSo modernizing the language has the perverse effect of making the libraries look even older!Historically could not add methods to interfaces without breaking implementationsHas something in common with, but not exactly like, C# extension methods, Scala traitsThis is not something we did lightly – “no code in interfaces” is a long-standing aspect of Java
  7. Compare to C# extension methods, traits
  8. Let’s look at a few use cases for default methods. First the obvious one – adding new methods to an interface after it’s been published.
  9. Key point – why is this code better? Each part does one thing, and is clearly labeled. Plus parallelism
  10. Plus parallelism
  11. Plus parallelism
  12. Composibility and separation of concerns powered by lambdas“Less brittle” means small changes to the problem result in small changes to the codeNoise == “garbage variables”
  13. One of Java’s strength has always been its libraries. The best way to write better applications is to have better, more powerful libraries. If parallelism is to become easier, libraries have to be a key part of getting there. While there are parallel libraries for Java today, such as the fork-join library added to Java SE 7, the code for expressing a computation serially and the code for expressing it in parallel is very different, and this places a barrier in front of users to move their code from serial to parallel.
  14. Safer = can avoid issues like CME
  15. Declaration of Comparators.compare method may be a little scary, but invocation is very clearExample of a higher-order function – takes a function (extractor), returns a function (comparator)Method references can be used instead of lambdas
  16. All of this “better libraries” talk is because it’s all about the libraries.