SlideShare una empresa de Scribd logo
1 de 56
Java gets a closure
Tomasz Kowalczewski
Agenda
•   Lambdas and closures
•   Java syntax
•   Functional interfaces
•   Implementation notes
•   Defender methods and interface evolution
•   Library changes
•   Lambda related language changes
Lambda expression
• First class function that closes over free variables in
  its lexical context.
• Lambda exprssion is another name for an
  anonymous function e.g. function not bound to an
  identifier.
• In Java it includes an optional list of type
  parameters, a list of formal parameters, and an
  expression or block expressed in terms of those
  parameters.
Examples
• Haskell:                            free variables
x -> x + x
x -> x * y


• Scala:
val isBelow = ( y : Int ) => y < threshold


• C#:
Predicate<string> p = it => it.Length < maxLength;

• C++:
[&count](int n){ return n * (++count); }
Why we hate anonymous inner classes?
• Java already has a form of closures - anonymous
  inner classes

List<Person> list = new ArrayList<>();
Collections.sort(list, new Comparator<Person>() {
  @Override
  public int compare(Person p1, Person p2) {
      return p1.getName().compareTo(p2.getName());
  }
});
Why we hate anonymous inner classes?
• Bulky syntax
• Inability to capture non-final local variables
• Transparency issues surrounding the meaning of
  return, break, continue, and 'this'
• No nonlocal control flow operators
Will we love lambda expressions?
• Bulky syntax
• Inability to capture non-final local variables
• Transparency issues surrounding the meaning of
  return, break, continue, and 'this'
• No nonlocal control flow operators
Lambda syntax
List<Person> list = new ArrayList<>();
Collections.sort(list, (p1, p2) ->
  p1.getName().compareTo(p2.getName())
);


List<Person> list = new ArrayList<>();
Collections.sort(list, new Comparator<Person>() {
  @Override
  public int compare(Person p1, Person p2) {
      return p1.getName().compareTo(p2.getName());
  }
});
Lambda syntax
LambdaExpression:
  TypeParametersopt LambdaParameters '->'
  LambdaBody

(int i) -> { System.out.println(i+1); }

(String s, int offset) -> {
     return s.charAt(offset) }

<T> (T i) -> { }
Lambda syntax
LambdaExpression:
  TypeParametersopt LambdaParameters '->' LambdaBody

LambdaParameters:
  Identifier
  '(' InferredFormalParameterList ')'
  '(' FormalParameterListopt ')‘

i -> { System.out.println(i+1); }

(s, offset) -> {
     return s.charAt(offset) }

() -> {}
Lambda syntax
LambdaExpression:
  TypeParametersopt LambdaParameters '->' LambdaBody

LambdaBody:
  Expression
  Block

(r) -> r *r *3.14

() -> System.out.println(i +1)

(s, offset) -> s.charAt(offset)
(s, offset) -> {
     return s.charAt(offset); }
Invalid syntax examples
• Either types/modifiers are infered or we need to specify all of them:
(final x) -> {}
(int x, y) -> 3.14


• Lambda body is either an expression (no brackets) or a block (brakcets and
  return statement needed):
() -> { 3.14; }


• Only unary lambda may omit parentheses:
i, j -> i*j


• There is no nilary syntax:
 -> "foo"
What is the type of a lambda?
• There will be no function types in Java 8
• We need to define how lambdas interact with other
  parts of Java
• We need ways to store, pass and execute them
• We need to define how closure conversion is
  performed
 ▫ Greatly influences lambda flexibility e.g. referencing
   local mutalbe variables
Functional interfaces
• Previously known as SAM interfaces
    ▫ SAM = Single Abstract Method
• Interfaces that define one method
    ▫ Public methods defined by Object do not count

interface Runnable { void run(); }

interface Callable<T> { T call(); }

interface Comparator<T> {
      int compare(T o1, T o2);

        boolean equals(Object obj);
}
Closure conversion
• Lambda expresion is converted to an instance of a
  functional interface
• It can appear in assignment, invocation and casting
  contexts
• The type lambda is converted to is infered from the
  context
  ▫ Target typing
• Parameter types of the lambda are also inferred
Type inference
interface Processor<T> {
     void process(Context c, T item);
}

Processor<Integer> p = (Context c, Integer i) -> {
  ... };



Processor<Integer> p = (c, i) -> { ... };
Local variable capture
• Lambda expressions can refer to effectively final local
  variables from the enclosing scope
int getAdultCount(List<Person> people, int threshold) {
      return Collections.filter(people, p -> p.getAge()
  > threshold).size();
}

void registerNotifier(JButton button, JLabel label) {
      button.addActionListener(e -> label.setText(""));
}
Local variable capture
• Cannot do this:
int accumulatedExperience = 0;
people.forEach(p -> accumulatedExperience += p.getEmploymentYears());

• Don’t even try this:
/* final */ int[] accumulatedExperience = { 0 };
people.forEach(p -> accumulatedExperience[0] += p.getEmploymentYears());

• Try this:
/* final */ AtomicInteger accumulatedExperience = new AtomicInteger();
people.forEach(p -> accumulatedExperience.addAndGet(p.getEmploymentYears()));

• Best solution:
people.reduce(0, (value, p) -> value +p.getEmploymentYears());
people.reduce(0, Math::add);
Lexical scoping
• All identifiers retain their meaning inside lambda
  expression
• The meaning of this does not change.
• Lambda formals cannot shadow variables from
  enclosing scope.
• There is no non-local control flow
Lexical scoping
interface ConfigFilter {
  String KEY = "configuration.source";
  boolean matches(Properties properties);
}

class FileConfigurator {
  String VALUE = "file://";

    public void configure(List<Properties> list) {
         configure(list, p ->
                 p.getProperty(ConfigFilter.KEY).startsWith(VALUE));
    }

    void configure(List<Properties> l, ConfigurationFilter f) { ... }
}
Lambda self reference
• Definite assignment rules say when a variable is
  definitely assigned
  ▫ e.g. if it is a local variable it can be safely used
• Definite uassignment say when a variable is
  definitely unassigned
  ▫ e.g. so that it can be assigned if it is final

• Function fib = n -> { n == 0 ? 1 : n *fib.apply(n -1) };
Method references
• Method reference is a shorthand for a lambda invoking just that method

• Static methods simply translate like lambda with same arguments and
  return type:
class Math {
  public static int max(int a, int b) { ... }
}

interface Operator<T> {
  T eval(T left, T right);
}

Operator<Integer> lambda = (a, b) -> Math.max(a, b);
Operator<Integer> methodRef = Math::max;
Method references
class Reducer {
  <T> static reduce(T base, Operator<T> op, T... items) {
      for(T item : items) {
             base = op.eval(base, item);
      }
  }
}
// result is 9
Reducer.reduce(0, Math::max, 1, 6, 9, 8);

// result is 24
Reducer.reduce(0, Math::add, 1, 6, 8, 9);
Method references
• Non static method reference of type T translates like
  lambda with an additional argument of type T:
interface Mapper<T, U> {
      U map(T t);
}

Mapper<String, Integer> lambda = s -> s.length;
Mapper<String, Integer> methodRef = String::length;

int getMaxTenure(List<Pereson> people) {
       return Collections.mapreduce(people,
             Person::getEmploymentTime, 0, Math::max);
}
Method references
• Instance method reference translates like lambda
  with same arguments and return type (and implicit
  receiver)
Callable<Integer> lambda = () -> "test".length();
Callable<Integer> c = "test"::length;
Method references
ExecutorService exec = Executors.newFixedThreadPool(4);

ServerSocket socket = new ServerSocket();
socket.bind(new InetSocketAddress(61000));

Callable<Socket> callable = socket::accept;
Future<Socket> socket = exec.submit(callable);

URL url = new URL("http://www.google.com");
URLConnection connection = url.openConnection();
Future<InputStream> s = exec.submit(url::openStream);
Constructor references
• Basically same as method references
Callable<Person> p = Person::new;
• Generic type constructor
LinkedList<Integer>::new
• Raw type constructor
LinkedList::new
• Generic constructor with type argument
Foo::<Integer>new
Constructor references
MapMaker maker = new MapMaker();
ConcurrentMap<String, Integer> map;

map = maker.<String, Integer>
makeComputingMap(Integer#new);
Exception transparency
• Generic exceptions are cumbersome to use
• Libraries either use interface with methods that throw Exception
  or throw nothing
interface Runnable {
}

interface Callable<V> {
      V call() throws Exception
}

interface Callable<V, E extends Exception> {
      V call() throws E
}
Exception transparency
interface Callable<V, throws E> {
       V call() throws E
}

class Executor {
       static <V, throws E> execute(Callable<V, E>) throws E;
}

Callable<Integer, IOException> c = ...
Executor.execute(c); // Throws IOException

Callable<Integer> d = ...
Executor.execute(d); // Throws nothing

Callable<Integer, ExecutionException, BadBreathException> e = ...
Executor.execute(e); // Throws ExecutionException, BadBreathException
Translation to inner classes
public class SimpleLambda {
      Runnable r = new Runnable() {
             public void run() { }
      };
}

public class SimpleLambda {
      Runnable r = () -> {};
}

• Compiling this source files will each time generate two classes:
  ▫ SimpleLambda.cass
  ▫ SimpleLambda$1.class
• In both situations classes are almost identical
Translation to method handles
• Try compiling with option -XDlambdaToMethod
• This will generate one class file.
• It will contain additional elements:
 ▫ Static method called lambda$0 with compiled lambda
   body
 ▫ Bootstrap method that will call ProxyHelper to
   generate interface proxy
 ▫ Calls to Runnable.run() will be dispatched through
   MethodHandle
 ▫ InvokeDynamic instruction at instantiation callsite
Extension Methods
Extension methods
• Programming style would be different if Java had
  closures from day one
• Different library designs, different collection classes
• Adding closures without library support would be
  dissapointing
• When interface is published it is effectively freezed –
  adding new methods will break existing
  implementations
Extension methods
• We would like to be able to write:

list.sortBy(Person::getFirstName).filter(Person::
  isEmployed).filter(p -> p.getAge()
  <30).forEach(System.out::println);

students.map(s ->
  s.getScore()).reduce(0.0, Math::max);
Static extension methods
• In C# they enable adding methods to existing types
  without recompiling or creating a new type.
• Special kind of static method, called as if it was an
  instance method on the extended type.
• Use site extension – user is in control
• Create illusion of adding a method
• Not reflectively discoverable
• No way to override
Extension methods
•   Mechnism for interface evolution
•   Library developer is in control
•   Main use case: java collections
•   A.k.a. public defender methods:

    “if you cannot afford an implementation of this
         method, one will be provided for you”
Virtual extension methods
public interface List<E> extends Collections<E> {
      public void sort(Comparator<? super E> c)
            default Collections.<E>sort;
}

public class Collections {
      public static <T extends Comparable<? super T>>
  void sort(List<T> list) { ... }
}

List<Person> jddAtendee = ...
jddAtendee.sort(...);
Virtual extension methods
•   Compiled to regular invokeinterface call
•   Caller is unaware of special call dispatch
•   Target method is resolved by JVM at runtime
•   Adds multiple inheritance of behavior not state!
•   Changes are (mostly) soruce and binary compatible
Method resolution
• Inheritance of methods from classes and interfaces is
  treated separately
• First JVM performs standard method
  implementation search – from the receiver class
  upwards through inheritance hierarchy to Object
Method resolution
                                      Which method is called?
        interface List
void foo() default Collections.foo;
                                       new C().foo();



  class D implements List
        void foo() { ... }




      class C extends D
       implements List
Method resolution
• List interfaces implemented by C (directly or
  indirectly) which provide a default for the method in
  question
• Remove all items that are superinterface of any
  other one from this list
• Create a set of distinct defaults provided by
  interfaces on the list
• Resolution is succesful if this set has a single item
• Throw a linkage exception otherwise
Method resolution
                                      Which method is called?
    interface Collection
void foo() default Collections.foo;
                                       new C().foo();


interface List implements               class C extends D
       Collection                     implements Collection
  void foo() default Lists.foo;




  class D implements List
Method resolution
                         interface Collection
                     void foo() default Collections.foo;




    interface List implements               interface Queue implements
           Collection                               Collection



                          class LinkedList
                       implements List, Queue


• When using this method resolution rules diamonds
  are not a problem (there is no state inheritance!)
Manual method disambiguation
• Compile time disambiguation of conflicting defaults is done
  using new syntax: A.super.method()

interface A {
  void foo() default As.foo;
}

interface B {
  void foo() default Bs.foo;
}

class C implements A, B {
  public void foo() { A.super.foo(); }
}
Source and binary compatibility
          Operation              Source Compatible         Binary Compatible
   Add default to a method               yes                       yes
    Remove default from a                 no                       no
          method
    Add new method with                  yes                      yes*
          default
   Remove a method with                   no                       no
         default
      Modify the default                 yes                       yes

* As long as adding the method itself does not create an invalid overloading
Collection enhancements
Collection enhancements
public interface Predicate<T> {
      boolean eval(T t);
}

public interface Block<T> {
      void apply(T t);
}

public interface Mapper<T, U> {
    U map(T t);
}
Iterable
public interface Iterable<T>{
  Iterable<T> filter(Predicate<? super T> predicate)
      default Iterables.filter;

    Iterable<T> forEach(Block<? super T> block)
        default Iterables.forEach;

    <U> Iterable<U> map(Mapper<? super T, ? extends U>
    mapper) default Iterables.map;

    T reduce(T base, Operator<T> reducer)
        default Iterables.reduce;
}
Collection
public interface Collection<E> extends Iterable<E> {

    boolean retainAll(Predicate<? super E> filter)
      default CollectionHelpers.retainAll;

    boolean removeAll(Predicate<? super E> filter)
      default CollectionHelpers.removeAll;

    void addAll(Iterable<? extends E> source)
      default CollectionHelpers.addAll;
}
Iterator
public interface Iterator<E> {
  boolean hasNext();
  E next();
  void remove() default Iterators.removeUnsupported;
}

public final class Iterators {
  public static <T> void removeUnsupported(Iterator<T> t) {
        throw new UnsupportedOperationException("remove");
    }
}
Enumeration
interface Enumeration<E> extends Iterator<E> {
  boolean hasMoreElements();

    E nextElement();

    // { return hasMoreElements(); }
    boolean hasNext() default Enumerations.hasNext;

    // { return nextElement(); }
    E next() default Enumerations.next;
}
Collections enhancements
Collections.sort(list, (p1, p2) ->
  p1.getName().compareTo(p2.getName())
);



public void<T, U extends Comparable<? super U>>
 sortBy(Collection<T> coll, Mapper<T, U> ext);




        Collections.sortBy(people, Person::getName);



               people.sortBy(Person::getName);
Development status
• Started in december 2009
• Compiler implemented as part of an OpenJDK
• Early Draft Review recently published
 ▫ http://www.jcp.org/en/jsr/summary?id=335
• No VM support for extension methods yet
Resources
• Compiler prototype binaries available at:
  ▫ http://jdk8.java.net/lambda/
• State of the lambda document:
  ▫ http://cr.openjdk.java.net/~briangoetz/lambda/lambd
    a-state-3.html
• Extension methods draft:
  ▫ http://cr.openjdk.java.net/~briangoetz/lambda/Defend
    er%20Methods%20v3.pdf
• Extension methods weaving agent availbale at:
  ▫ hg.openjdk.java.net/lambda/defender-prototype/
Resources
• JDK Enchancement Proposals:
  ▫ http://openjdk.java.net/jeps/0
• Brian Goetz’s Oracle Blog
  ▫ http://blogs.oracle.com/briangoetz
• Neal Gafter’s blog (interesting for historical purposes)
  ▫ http://gafter.blogspot.com
• lambda-dev discussion list
  ▫ http://mail.openjdk.java.net/pipermail/lambda-dev

Más contenido relacionado

La actualidad más candente

More on Lex
More on LexMore on Lex
More on Lex
Tech_MX
 
Procedure Typing for Scala
Procedure Typing for ScalaProcedure Typing for Scala
Procedure Typing for Scala
akuklev
 

La actualidad más candente (20)

Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
 
Lambda Expressions in Java
Lambda Expressions in JavaLambda Expressions in Java
Lambda Expressions in Java
 
Java8
Java8Java8
Java8
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
More on Lex
More on LexMore on Lex
More on Lex
 
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of Lambdas
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streams
 
Practical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan HodorogPractical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan Hodorog
 
What You Need to Know about Lambdas
What You Need to Know about LambdasWhat You Need to Know about Lambdas
What You Need to Know about Lambdas
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 
Java 8 streams
Java 8 streamsJava 8 streams
Java 8 streams
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
Functional Programming in Scala: Notes
Functional Programming in Scala: NotesFunctional Programming in Scala: Notes
Functional Programming in Scala: Notes
 
Procedure Typing for Scala
Procedure Typing for ScalaProcedure Typing for Scala
Procedure Typing for Scala
 
Lexyacc
LexyaccLexyacc
Lexyacc
 

Destacado (9)

Gold leaf photos
Gold leaf photosGold leaf photos
Gold leaf photos
 
Case study-Markigence
Case study-MarkigenceCase study-Markigence
Case study-Markigence
 
Making waves
Making wavesMaking waves
Making waves
 
It's a wonderful world
It's a wonderful worldIt's a wonderful world
It's a wonderful world
 
Tugasan 1 KPT6044
Tugasan 1 KPT6044Tugasan 1 KPT6044
Tugasan 1 KPT6044
 
Dingo’s in the wild!
Dingo’s in the wild!Dingo’s in the wild!
Dingo’s in the wild!
 
Social studies chap 1 subject 1
Social studies chap 1  subject 1Social studies chap 1  subject 1
Social studies chap 1 subject 1
 
Soalan peperiksaan ptd
Soalan peperiksaan ptdSoalan peperiksaan ptd
Soalan peperiksaan ptd
 
S O C C E R
S O C C E RS O C C E R
S O C C E R
 

Similar a Java gets a closure

FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
 

Similar a Java gets a closure (20)

Java 8
Java 8Java 8
Java 8
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
The Style of C++ 11
The Style of C++ 11The Style of C++ 11
The Style of C++ 11
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
 
Java SE 8
Java SE 8Java SE 8
Java SE 8
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 
Java8
Java8Java8
Java8
 
Java 8 new features
Java 8 new featuresJava 8 new features
Java 8 new features
 
New Functional Features of Java 8
New Functional Features of Java 8New Functional Features of Java 8
New Functional Features of Java 8
 
Major Java 8 features
Major Java 8 featuresMajor Java 8 features
Major Java 8 features
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
 
Matlab Functions
Matlab FunctionsMatlab Functions
Matlab Functions
 
Java 8 Intro - Core Features
Java 8 Intro - Core FeaturesJava 8 Intro - Core Features
Java 8 Intro - Core Features
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 iti
 
C# programming
C# programming C# programming
C# programming
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
20160520 what youneedtoknowaboutlambdas
20160520 what youneedtoknowaboutlambdas20160520 what youneedtoknowaboutlambdas
20160520 what youneedtoknowaboutlambdas
 
CS101- Introduction to Computing- Lecture 29
CS101- Introduction to Computing- Lecture 29CS101- Introduction to Computing- Lecture 29
CS101- Introduction to Computing- Lecture 29
 

Más de Tomasz Kowalczewski

Más de Tomasz Kowalczewski (14)

How I learned to stop worrying and love the dark silicon apocalypse.pdf
How I learned to stop worrying and love the dark silicon apocalypse.pdfHow I learned to stop worrying and love the dark silicon apocalypse.pdf
How I learned to stop worrying and love the dark silicon apocalypse.pdf
 
Is writing performant code too expensive?
Is writing performant code too expensive? Is writing performant code too expensive?
Is writing performant code too expensive?
 
Is writing performant code too expensive?
Is writing performant code too expensive? Is writing performant code too expensive?
Is writing performant code too expensive?
 
Is writing performant code too expensive?
Is writing performant code too expensive?Is writing performant code too expensive?
Is writing performant code too expensive?
 
Deep dive reactive java (DevoxxPl)
Deep dive reactive java (DevoxxPl)Deep dive reactive java (DevoxxPl)
Deep dive reactive java (DevoxxPl)
 
Everybody Lies
Everybody LiesEverybody Lies
Everybody Lies
 
Forgive me for i have allocated
Forgive me for i have allocatedForgive me for i have allocated
Forgive me for i have allocated
 
AWS Java SDK @ scale
AWS Java SDK @ scaleAWS Java SDK @ scale
AWS Java SDK @ scale
 
Measure to fail
Measure to failMeasure to fail
Measure to fail
 
Reactive Java at JDD 2014
Reactive Java at JDD 2014Reactive Java at JDD 2014
Reactive Java at JDD 2014
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
 
Introduction to Reactive Java
Introduction to Reactive JavaIntroduction to Reactive Java
Introduction to Reactive Java
 
Java 8 jest tuż za rogiem
Java 8 jest tuż za rogiemJava 8 jest tuż za rogiem
Java 8 jest tuż za rogiem
 

Último

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Último (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
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
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 

Java gets a closure

  • 1. Java gets a closure Tomasz Kowalczewski
  • 2. Agenda • Lambdas and closures • Java syntax • Functional interfaces • Implementation notes • Defender methods and interface evolution • Library changes • Lambda related language changes
  • 3. Lambda expression • First class function that closes over free variables in its lexical context. • Lambda exprssion is another name for an anonymous function e.g. function not bound to an identifier. • In Java it includes an optional list of type parameters, a list of formal parameters, and an expression or block expressed in terms of those parameters.
  • 4. Examples • Haskell: free variables x -> x + x x -> x * y • Scala: val isBelow = ( y : Int ) => y < threshold • C#: Predicate<string> p = it => it.Length < maxLength; • C++: [&count](int n){ return n * (++count); }
  • 5. Why we hate anonymous inner classes? • Java already has a form of closures - anonymous inner classes List<Person> list = new ArrayList<>(); Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.getName().compareTo(p2.getName()); } });
  • 6. Why we hate anonymous inner classes? • Bulky syntax • Inability to capture non-final local variables • Transparency issues surrounding the meaning of return, break, continue, and 'this' • No nonlocal control flow operators
  • 7. Will we love lambda expressions? • Bulky syntax • Inability to capture non-final local variables • Transparency issues surrounding the meaning of return, break, continue, and 'this' • No nonlocal control flow operators
  • 8. Lambda syntax List<Person> list = new ArrayList<>(); Collections.sort(list, (p1, p2) -> p1.getName().compareTo(p2.getName()) ); List<Person> list = new ArrayList<>(); Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.getName().compareTo(p2.getName()); } });
  • 9. Lambda syntax LambdaExpression: TypeParametersopt LambdaParameters '->' LambdaBody (int i) -> { System.out.println(i+1); } (String s, int offset) -> { return s.charAt(offset) } <T> (T i) -> { }
  • 10. Lambda syntax LambdaExpression: TypeParametersopt LambdaParameters '->' LambdaBody LambdaParameters: Identifier '(' InferredFormalParameterList ')' '(' FormalParameterListopt ')‘ i -> { System.out.println(i+1); } (s, offset) -> { return s.charAt(offset) } () -> {}
  • 11. Lambda syntax LambdaExpression: TypeParametersopt LambdaParameters '->' LambdaBody LambdaBody: Expression Block (r) -> r *r *3.14 () -> System.out.println(i +1) (s, offset) -> s.charAt(offset) (s, offset) -> { return s.charAt(offset); }
  • 12. Invalid syntax examples • Either types/modifiers are infered or we need to specify all of them: (final x) -> {} (int x, y) -> 3.14 • Lambda body is either an expression (no brackets) or a block (brakcets and return statement needed): () -> { 3.14; } • Only unary lambda may omit parentheses: i, j -> i*j • There is no nilary syntax: -> "foo"
  • 13. What is the type of a lambda? • There will be no function types in Java 8 • We need to define how lambdas interact with other parts of Java • We need ways to store, pass and execute them • We need to define how closure conversion is performed ▫ Greatly influences lambda flexibility e.g. referencing local mutalbe variables
  • 14. Functional interfaces • Previously known as SAM interfaces ▫ SAM = Single Abstract Method • Interfaces that define one method ▫ Public methods defined by Object do not count interface Runnable { void run(); } interface Callable<T> { T call(); } interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
  • 15. Closure conversion • Lambda expresion is converted to an instance of a functional interface • It can appear in assignment, invocation and casting contexts • The type lambda is converted to is infered from the context ▫ Target typing • Parameter types of the lambda are also inferred
  • 16. Type inference interface Processor<T> { void process(Context c, T item); } Processor<Integer> p = (Context c, Integer i) -> { ... }; Processor<Integer> p = (c, i) -> { ... };
  • 17. Local variable capture • Lambda expressions can refer to effectively final local variables from the enclosing scope int getAdultCount(List<Person> people, int threshold) { return Collections.filter(people, p -> p.getAge() > threshold).size(); } void registerNotifier(JButton button, JLabel label) { button.addActionListener(e -> label.setText("")); }
  • 18. Local variable capture • Cannot do this: int accumulatedExperience = 0; people.forEach(p -> accumulatedExperience += p.getEmploymentYears()); • Don’t even try this: /* final */ int[] accumulatedExperience = { 0 }; people.forEach(p -> accumulatedExperience[0] += p.getEmploymentYears()); • Try this: /* final */ AtomicInteger accumulatedExperience = new AtomicInteger(); people.forEach(p -> accumulatedExperience.addAndGet(p.getEmploymentYears())); • Best solution: people.reduce(0, (value, p) -> value +p.getEmploymentYears()); people.reduce(0, Math::add);
  • 19. Lexical scoping • All identifiers retain their meaning inside lambda expression • The meaning of this does not change. • Lambda formals cannot shadow variables from enclosing scope. • There is no non-local control flow
  • 20. Lexical scoping interface ConfigFilter { String KEY = "configuration.source"; boolean matches(Properties properties); } class FileConfigurator { String VALUE = "file://"; public void configure(List<Properties> list) { configure(list, p -> p.getProperty(ConfigFilter.KEY).startsWith(VALUE)); } void configure(List<Properties> l, ConfigurationFilter f) { ... } }
  • 21. Lambda self reference • Definite assignment rules say when a variable is definitely assigned ▫ e.g. if it is a local variable it can be safely used • Definite uassignment say when a variable is definitely unassigned ▫ e.g. so that it can be assigned if it is final • Function fib = n -> { n == 0 ? 1 : n *fib.apply(n -1) };
  • 22. Method references • Method reference is a shorthand for a lambda invoking just that method • Static methods simply translate like lambda with same arguments and return type: class Math { public static int max(int a, int b) { ... } } interface Operator<T> { T eval(T left, T right); } Operator<Integer> lambda = (a, b) -> Math.max(a, b); Operator<Integer> methodRef = Math::max;
  • 23. Method references class Reducer { <T> static reduce(T base, Operator<T> op, T... items) { for(T item : items) { base = op.eval(base, item); } } } // result is 9 Reducer.reduce(0, Math::max, 1, 6, 9, 8); // result is 24 Reducer.reduce(0, Math::add, 1, 6, 8, 9);
  • 24. Method references • Non static method reference of type T translates like lambda with an additional argument of type T: interface Mapper<T, U> { U map(T t); } Mapper<String, Integer> lambda = s -> s.length; Mapper<String, Integer> methodRef = String::length; int getMaxTenure(List<Pereson> people) { return Collections.mapreduce(people, Person::getEmploymentTime, 0, Math::max); }
  • 25. Method references • Instance method reference translates like lambda with same arguments and return type (and implicit receiver) Callable<Integer> lambda = () -> "test".length(); Callable<Integer> c = "test"::length;
  • 26. Method references ExecutorService exec = Executors.newFixedThreadPool(4); ServerSocket socket = new ServerSocket(); socket.bind(new InetSocketAddress(61000)); Callable<Socket> callable = socket::accept; Future<Socket> socket = exec.submit(callable); URL url = new URL("http://www.google.com"); URLConnection connection = url.openConnection(); Future<InputStream> s = exec.submit(url::openStream);
  • 27. Constructor references • Basically same as method references Callable<Person> p = Person::new; • Generic type constructor LinkedList<Integer>::new • Raw type constructor LinkedList::new • Generic constructor with type argument Foo::<Integer>new
  • 28. Constructor references MapMaker maker = new MapMaker(); ConcurrentMap<String, Integer> map; map = maker.<String, Integer> makeComputingMap(Integer#new);
  • 29. Exception transparency • Generic exceptions are cumbersome to use • Libraries either use interface with methods that throw Exception or throw nothing interface Runnable { } interface Callable<V> { V call() throws Exception } interface Callable<V, E extends Exception> { V call() throws E }
  • 30. Exception transparency interface Callable<V, throws E> { V call() throws E } class Executor { static <V, throws E> execute(Callable<V, E>) throws E; } Callable<Integer, IOException> c = ... Executor.execute(c); // Throws IOException Callable<Integer> d = ... Executor.execute(d); // Throws nothing Callable<Integer, ExecutionException, BadBreathException> e = ... Executor.execute(e); // Throws ExecutionException, BadBreathException
  • 31. Translation to inner classes public class SimpleLambda { Runnable r = new Runnable() { public void run() { } }; } public class SimpleLambda { Runnable r = () -> {}; } • Compiling this source files will each time generate two classes: ▫ SimpleLambda.cass ▫ SimpleLambda$1.class • In both situations classes are almost identical
  • 32. Translation to method handles • Try compiling with option -XDlambdaToMethod • This will generate one class file. • It will contain additional elements: ▫ Static method called lambda$0 with compiled lambda body ▫ Bootstrap method that will call ProxyHelper to generate interface proxy ▫ Calls to Runnable.run() will be dispatched through MethodHandle ▫ InvokeDynamic instruction at instantiation callsite
  • 34. Extension methods • Programming style would be different if Java had closures from day one • Different library designs, different collection classes • Adding closures without library support would be dissapointing • When interface is published it is effectively freezed – adding new methods will break existing implementations
  • 35. Extension methods • We would like to be able to write: list.sortBy(Person::getFirstName).filter(Person:: isEmployed).filter(p -> p.getAge() <30).forEach(System.out::println); students.map(s -> s.getScore()).reduce(0.0, Math::max);
  • 36. Static extension methods • In C# they enable adding methods to existing types without recompiling or creating a new type. • Special kind of static method, called as if it was an instance method on the extended type. • Use site extension – user is in control • Create illusion of adding a method • Not reflectively discoverable • No way to override
  • 37. Extension methods • Mechnism for interface evolution • Library developer is in control • Main use case: java collections • A.k.a. public defender methods: “if you cannot afford an implementation of this method, one will be provided for you”
  • 38. Virtual extension methods public interface List<E> extends Collections<E> { public void sort(Comparator<? super E> c) default Collections.<E>sort; } public class Collections { public static <T extends Comparable<? super T>> void sort(List<T> list) { ... } } List<Person> jddAtendee = ... jddAtendee.sort(...);
  • 39. Virtual extension methods • Compiled to regular invokeinterface call • Caller is unaware of special call dispatch • Target method is resolved by JVM at runtime • Adds multiple inheritance of behavior not state! • Changes are (mostly) soruce and binary compatible
  • 40. Method resolution • Inheritance of methods from classes and interfaces is treated separately • First JVM performs standard method implementation search – from the receiver class upwards through inheritance hierarchy to Object
  • 41. Method resolution Which method is called? interface List void foo() default Collections.foo; new C().foo(); class D implements List void foo() { ... } class C extends D implements List
  • 42. Method resolution • List interfaces implemented by C (directly or indirectly) which provide a default for the method in question • Remove all items that are superinterface of any other one from this list • Create a set of distinct defaults provided by interfaces on the list • Resolution is succesful if this set has a single item • Throw a linkage exception otherwise
  • 43. Method resolution Which method is called? interface Collection void foo() default Collections.foo; new C().foo(); interface List implements class C extends D Collection implements Collection void foo() default Lists.foo; class D implements List
  • 44. Method resolution interface Collection void foo() default Collections.foo; interface List implements interface Queue implements Collection Collection class LinkedList implements List, Queue • When using this method resolution rules diamonds are not a problem (there is no state inheritance!)
  • 45. Manual method disambiguation • Compile time disambiguation of conflicting defaults is done using new syntax: A.super.method() interface A { void foo() default As.foo; } interface B { void foo() default Bs.foo; } class C implements A, B { public void foo() { A.super.foo(); } }
  • 46. Source and binary compatibility Operation Source Compatible Binary Compatible Add default to a method yes yes Remove default from a no no method Add new method with yes yes* default Remove a method with no no default Modify the default yes yes * As long as adding the method itself does not create an invalid overloading
  • 48. Collection enhancements public interface Predicate<T> { boolean eval(T t); } public interface Block<T> { void apply(T t); } public interface Mapper<T, U> { U map(T t); }
  • 49. Iterable public interface Iterable<T>{ Iterable<T> filter(Predicate<? super T> predicate) default Iterables.filter; Iterable<T> forEach(Block<? super T> block) default Iterables.forEach; <U> Iterable<U> map(Mapper<? super T, ? extends U> mapper) default Iterables.map; T reduce(T base, Operator<T> reducer) default Iterables.reduce; }
  • 50. Collection public interface Collection<E> extends Iterable<E> { boolean retainAll(Predicate<? super E> filter) default CollectionHelpers.retainAll; boolean removeAll(Predicate<? super E> filter) default CollectionHelpers.removeAll; void addAll(Iterable<? extends E> source) default CollectionHelpers.addAll; }
  • 51. Iterator public interface Iterator<E> { boolean hasNext(); E next(); void remove() default Iterators.removeUnsupported; } public final class Iterators { public static <T> void removeUnsupported(Iterator<T> t) { throw new UnsupportedOperationException("remove"); } }
  • 52. Enumeration interface Enumeration<E> extends Iterator<E> { boolean hasMoreElements(); E nextElement(); // { return hasMoreElements(); } boolean hasNext() default Enumerations.hasNext; // { return nextElement(); } E next() default Enumerations.next; }
  • 53. Collections enhancements Collections.sort(list, (p1, p2) -> p1.getName().compareTo(p2.getName()) ); public void<T, U extends Comparable<? super U>> sortBy(Collection<T> coll, Mapper<T, U> ext); Collections.sortBy(people, Person::getName); people.sortBy(Person::getName);
  • 54. Development status • Started in december 2009 • Compiler implemented as part of an OpenJDK • Early Draft Review recently published ▫ http://www.jcp.org/en/jsr/summary?id=335 • No VM support for extension methods yet
  • 55. Resources • Compiler prototype binaries available at: ▫ http://jdk8.java.net/lambda/ • State of the lambda document: ▫ http://cr.openjdk.java.net/~briangoetz/lambda/lambd a-state-3.html • Extension methods draft: ▫ http://cr.openjdk.java.net/~briangoetz/lambda/Defend er%20Methods%20v3.pdf • Extension methods weaving agent availbale at: ▫ hg.openjdk.java.net/lambda/defender-prototype/
  • 56. Resources • JDK Enchancement Proposals: ▫ http://openjdk.java.net/jeps/0 • Brian Goetz’s Oracle Blog ▫ http://blogs.oracle.com/briangoetz • Neal Gafter’s blog (interesting for historical purposes) ▫ http://gafter.blogspot.com • lambda-dev discussion list ▫ http://mail.openjdk.java.net/pipermail/lambda-dev

Notas del editor

  1. It would be ambiguous with a cast (is this a lambda with on argument or cast of a nilary lambda to x?):(x)-&gt;{ 3.14; }
  2. Closure is a function together with referencing environment for the free variables of that function.
  3. Promotes side effect free programming modelNo wunderbars
  4. interface Converter { int convert(String s); }classInteger { publicstaticString toString(inti) { ... }}Converter lambda = i -&gt; Integer.toString(i);Converter methodRef = Integer::toString;