SlideShare ist ein Scribd-Unternehmen logo
1 von 39
1Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Lambda: A peek under the
hood                                                                     Insert Picture Here

Brian Goetz
Java Language Architect, Oracle




 2Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
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.



3Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
About this talk


           This talk outlines the technical details of how lambda expressions are
               implemented in Java SE 8 at the bytecode level
                     – This will be a highly technical talk!
                     – We assume some familiarity with JVM and bytecode
                     – Including JSR-292 facilities




4Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Lambda expressions for Java


           A lambda expression is like an “anonymous method”
                     – Has an argument list, a return type, and a body
                                              – people.forEach((Person e) ->
                                                     names.add(e.getName());
                     – Many of these can be inferred by the compiler
                                              – people.forEach(e -> names.add(e.getName());

           Lambda expressions can capture values from the enclosing context
                                              – people.removeAll(e -> e.getAge() < minAge);


5Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why lambdas for Java?


          Provide libraries a path to multicore
                 – Parallel-friendly APIs need internal iteration
                 – Internal iteration needs a concise code-as-data mechanism
          Empower library developers
                 – Enable a higher degree of cooperation between libraries and client code
          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
          Inner classes give us some of these benefits, but are too clunky
                 – Clunkiness is not entirely syntactic!
          How to represent lambda expressions at runtime is not a trivial question
                 – That’s what this talk is about



6Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Lambda expressions for Java


          Big question #1: what is the type of a lambda expression?
                  – Most languages with lambdas have some notion of a function type
                  – Java has no concept of function type

                  – JVM has no native (unerased) representation of function type in VM type signatures

          Adding function types would create many questions
                  – How do we represent functions in VM type signatures?
                  – How do we create instances of function-typed variables?
                  – How do we deal with variance?
          Want to avoid significant VM changes



7Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Functional interfaces


           We have historically modeled functions using single-method interfaces, such
            as Runnable or Comparator
           Rather than complicate the type system, let’s just formalize that
                   – Give them a name: “functional interfaces”
                   – Always convert lambda expressions to instance of a functional interface

                         interface Predicate<T> { boolean test(T x); }
                         people.removeAll(p -> p.getAge() >= 18);

                   – Compiler figures out the types – lambda is converted to Predicate<Person>
           How does the lambda instance get created?

8Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why not “just” use inner classes?


           We could say that a lambda is “just” an inner class instance
           Then for the lambda p -> p.getAge() >= minAge we generate
                         class Foo$1 implements Predicate<Person> {
                             private final int $v0;
                             Foo$1(int v0) { this.$v0 = v0; }
                             public boolean test(Person p) {
                                 return p.age < $v0;
                             }
                         }

           This means (among other things) one class per lambda expression

9Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why not “just” use inner classes?


            If we translate lambdas to inner classes, then capturing a lambda is
                invoking a constructor
                list.removeAll(p -> p.getAge() >= minAge);




                list.removeAll(new Foo$1(minAge));




10Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why not “just” use inner classes?


            Inner class constructor invocation translates as
                list.removeAll(p -> p.getAge() >= minAge);




                aload_1                                                  // list
                new #2                                                   // class Foo$1
                dup
                iload_2                                                  // minAge
                invokespecial #3                                         // Method Foo$1."<init>":(I)V
                invokeinterface #4                                       // java/util/List.removeAll:(Ljava/util/functions/Predicate;)Z




11Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why not “just” use inner classes?


            Translating to inner classes means we inherit most of their problems
                     – Performance issues
                     – One class per lambda expression

                     – Type profile pollution

                     – Complicated “comb” lookup
            Whatever we do becomes a binary representation for lambdas in Java
                     – Would be stuck with it forever
                     – Would rather not conflate implementation with binary representation



12Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Bytecode invocation modes


            Prior to Java SE 7, the JVM had four bytecodes for method
                invocation
                      – invokestatic: for static methods
                      – invokevirtual: for class methods
                      – invokeinterface: for interface methods
                      – invokespecial: for constructors, private methods, and super-calls
            aload_1 specifies a// list name, method name, and method signature
             Each                class
                new #2                                                   // class Foo$1
                dup
                iload_2                                                  // minAge
                invokespecial #3                                         // Method Foo$1."<init>":(I)V
                invokeinterface #4                                       // java/util/List.removeAll:(Ljava/util/functions/Predicate;)Z
13Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
New bytecode tool: MethodHandle


            Java SE 7 adds VM-level method handles
                    – Can store references to methods in the constant pool and load with LDC
                    – Can obtain a method handle for any method (or field access)
                    – VM will happily inline through MH calls
                    – MH API contains combinators for manipulating method handles
                    – Add, remove, reorder arguments

                    – Adapt (box, unbox, cast) arguments and return types

                    – Compose methods

                    – Compiler writers swiss-army knife!


14Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why not “just” use MethodHandle?


            At first, translating lambdas to MethodHandle seems obvious
                      – Lambda is language-level method object
                      – MethodHandle is VM-level method object
            We could
                      – Desugar lambdas expressions to methods
                      – Represent lambdas using MethodHandle in bytecode signatures




15Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why not “just” use MethodHandle?


            If we represented lambdas as MethodHandle, we’d translate:
                list.removeAll(p -> p.getAge() >= minAge);




                MethodHandle mh = LDC[lambda$1];
                mh = MethodHandles.insertArguments(mh, 0, minAge);
                list.removeAll(mh);

                private static boolean lambda$1(int capturedK, Person p) {
                    return p.getAge() >= capturedK;
                }




16Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Why not “just” use MethodHandle?


            If we did this, the signature of List.removeAll would be:
             void removeAll(MethodHandle predicate)
            This is erasure on steroids!
                      – Can’t overload two methods that take differently “shaped” lambdas
                      – Still would need to encode the erased type information somewhere
            Also: is MH invocation performance yet competitive with bytecode
             invocation?
            Again: conflates binary representation with implementation


17Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Stepping back…


            We would like a binary interface not tied to a specific implementation
                    – Inner classes have too much baggage
                    – MethodHandle is too low-level, is erased
                    – Can’t force users to recompile, ever, so have to pick now
            What we need is … another level of indirection
                    – Let the static compiler emit a declarative recipe, rather than imperative code, for
                          creating a lambda
                    – Let the runtime execute that recipe however it deems best
                    – And make it darned fast
                    – This sounds like a job for invokedynamic!


18Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
New bytecode tool: invokedynamic


            Java SE 7 adds a fifth invocation mode: invokedynamic (indy)
            Behavior of invoke{virtual,static,interface} are fixed and Java-like
                      – Other languages need custom method linkage
            Basic idea: let some “language logic” determine call target
                      – And then get out of the way
                      – Language and VM become partners
                             in flexible and efficient method
                             dispatch


19Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
New bytecode tool: invokedynamic


            The canonical use case for invokedynamic is something like
               def add(a, b) { a+b }
            Here, the types of a and b are not known at compile time
                      – And can change from call to call … but probably don’t so often
                      – Good chance that if called with two ints, next call will be with two ints
                      – We win by not having to re-link the call site for every invocation




20Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
New bytecode tool: invokedynamic


            The first time the JVM executes an invokedynamic
                      – Consults the bootstrap method for the call site (the “language logic”)
                      – Bootstrap returns a linked call site
                      – Call site can embed conditions under which it needs relinking
                      – Such as the argument types changing

                      – Otherwise, JVM does not have to consult bootstrap again

            After linkage, JVM can inline through linked indy callsites



21Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
New bytecode tool: invokedynamic


            An indy callsite has three groups of operands
                    – A bootstrap method (the “language logic”)
                    – Called by the VM for linking the callsite on first invocation

                    – Not called again after that

                    – A static argument list, embedded in the constant pool
                    – Available to the bootstrap method

                    – A dynamic argument list, like any other method invocation
                    – Not available to the bootstrap, but their static types and arity are

                    – Passed to whatever method the callsite is linked to


22Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Its not just for dynamic languages anymore


            So, if indy is for dynamic languages, why is the Java compiler using it?
                    – All the types involved are static
                    – What is dynamic here is the code generation strategy
                    – Generate inner classes?

                    – Use method handles?

                    – Use dynamic proxies?

                    – Use VM-private APIs for constructing objects?

            Indy lets us turn this choice into a pure implementation detail
                    – Separate from the binary representation


23Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Its not just for dynamic languages anymore


            We use indy to embed a recipe for constructing a lambda at the capture
                site, including
                     – The desugared implementation method
                     – The functional interface we are converting to
                     – Values captured from the lexical scope
                     – Additional metadata, such as serialization information
            The capture site is called the lambda factory
                     – Invoked with indy, returns an instance of the desired functional interface
                     – Subsequent captures bypass the (slow) linkage path

24Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Desugaring lambdas to methods


            First, we desugar the lambda to a method
                      – Signature matches functional interface method
                      – Plus captured arguments prepended (must be effectively final)
                      – Simplest lambdas desugar to static methods
                      – But some need access to receiver, and so are instance methods
               Predicate<Person> olderThanK = p -> p.getAge() >= k;



               private static boolean lambda$1(int capturedK, Person p) {
                   return p.getAge() >= capturedK;
               }
25Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Factories and metafactories


            We generate an indy call site which, when called, returns the lambda
                      – This is the lambda factory
                      – Bootstrap for the lambda factory                                 list.removeAll(p -> p.getAge() >= minAge);
                             selects the translation strategy
                      – Bootstrap is called the lambda metafactory
                                                                              Predicate $p = indy[bootstrap=LambdaMetafactory,
                      – Part of Java runtime                                                      staticargs=[Predicate, lambda$1],
                                                                                                  dynargs=[minAge])
                      – Captured args passed                                  list.removeAll($p);

                             to lambda factory                           private static boolean lambda$1(int capturedK, Person p) {
                                                                             return p.getAge() >= capturedK;
                                                                         }

26Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Translation strategies


            The metafactory could spin inner classes dynamically
                   – Generate the same class the compiler would, just at runtime
                   – Link factory call site to constructor of generated class
                   – Conveniently, dynamic args and ctor args will line up

                   – Our initial strategy until we can prove that there’s a better one
            Alternately could spin one wrapper class per interface
                   – Constructor would take a method handle
                   – Methods would invoke that method handle
            Could also use dynamic proxies or MethodHandleProxy
            Or VM-private APIs to build object from scratch, or…


27Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Indy: the ultimate lazy initialization


            For stateless (non-capturing) lambdas, we can create one single instance of
               the lambda object and always return that
                    – Very common case – many lambdas capture nothing
                    – People sometimes do this by hand in source code – e.g., pulling a Comparator into
                           a static final variable
            Indy functions as a lazily initialized cache
                    – Defers initialization cost to first use
                    – No overhead if lambda is never used
                    – No extra field or static initializer
                    – All stateless lambdas get lazy init and caching for free


28Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Indy: the ultimate procrastination aid


            By deferring the code generation choice to runtime, it becomes a
                pure implementation detail
                      – Can be changed dynamically
                      – We can settle on a binary protocol now (metafactory API) while delaying
                             the choice of code generation strategy
                      – Moving more work from static compiler to runtime

                      – Can change code generation strategy across VM versions, or even days
                             of the week


29Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Indy: the ultimate indirection aid


            Just because we defer code generation strategy to runtime, we don’t
                have to pay the price on every call
                      – Metafactory only invoked once per call site
                      – For non-capturing case, subsequent captures are FREE
                      – VM optimizes to constant load

                      – For capturing case, subsequent capture cost on order of a constructor
                             call / method handle manipulation
                      – MF links to constructor for generated class



30Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Performance costs


            Any translation scheme imposes costs at several levels:
                      – Linkage cost – one-time cost of setting up capture
                      – Capture cost – cost of creating a lambda
                      – Invocation cost – cost of invoking the lambda method
            For inner class instances, these correspond to:
                      – Linkage: loading the class
                      – Capture: invoking the constructor
                      – Invocation: invokeinterface


31Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Performance example – capture cost


            Oracle Performance Team measured capture costs
                      – 4 socket x 10 core x 2 thread Nehalem EX server
                      – All numbers in ops/uSec
            Worst-case lambda numbers equal to inner classes
                                  Single-threaded   Saturated
                      – Best-case numbers much better                            Scalability

          –
Inner class                  And this is 160 our “fallback” strategy
                                         just                  1407              8.8x
Non-capturing lambda                                           636       23201   36.4x

Capturing lambda                                               160       1400    8.8x


32Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Not just for the Java Language!


            The lambda conversion metafactories will be part of java.lang.invoke
                    – Semantics tailored to Java language needs
                    – But, other languages may find it useful too!
            Java APIs will be full of functional interfaces
                    – Collection.forEach(Block)
            Other languages probably will want to call these APIs
                    – Maybe using their own closures
                    – Will want a similar conversion
            Since metafactories are likely to receive future VM optimization attention, using
               platform runtime is likely to be faster than spinning your own inner classes

33Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Possible VM support


            VM could intrinsify lambda capture sites
                     – Capture semantics are straightforward properties of method handles
                     – Capture operation is pure, therefore freely reorderable
                     – Can use code motion to delay/eliminate captures
            Lambda capture is like a “boxing” operation
                     – Essentially boxing a method handle into lambda object
                     – Invocation is the corresponding “unbox”
                     – Can use box elimination techniques to eliminate capture overhead
                     – Intrinsification of capture + inline + escape analysis


34Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Serialization


           No language feature is complete without some interaction with serialization 
                  – Users will expect this code to work

                interface Foo extends Serializable {
                    public boolean eval();
                }
                Foo f = () -> false;
                // now serialize f

           We can’t just serialize the lambda object
                  – Implementing class won’t exist at deserialization time
                  – Deserializing VM may use a different translation strategy
                  – Need a dynamic serialization strategy too!
                  – Without exposing security holes…



35Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Serialization


            Just as our classfile representation for a lambda is a recipe, our serialized
               representation needs to be to
                   – We can use readResolve / writeReplace
                   – Instead of serializing lambda directly, serialize the recipe (say, to some well defined
                         interface SerializedLambda)
                   – This means that for serializable lambdas, MF must provide a way of getting at the recipe
                   – We provide an alternate MF bootstrap for that
            On deserialization, reconstitute from recipe
                   – Using then-current translation strategy, which might be different from the one that originally
                         created the lambda
                   – Without opening new security holes


36Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Summary


            We use invokedynamic to capture lambda expressions
                      – Gives us flexibility and performance
                      – Free to change translation strategy at runtime
            Even using the “dumb” translation strategy…
                      – No worse than inner classes in the worst case
                      – 5-20x better than inner classes in a common case




37Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
For more information


            Project Lambda: http://openjdk.java.net/projects/lambda/
                      – Lambda spec EDR #2: http://
                             jcp.org/aboutJava/communityprocess/edr/jsr335/index2.html
                      – Lambda Overview: http://cr.openjdk.java.net/~
                             briangoetz/lambda/lambda-state-4.html
                      – Binary builds: http://jdk8.java.net/lambda/




38Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Graphic Section Divider




39Copyright © 2012, Oracle and/or its affiliates. All rights reserved.

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
camel-scala.pdf
camel-scala.pdfcamel-scala.pdf
camel-scala.pdf
 
Java 8 Feature Preview
Java 8 Feature PreviewJava 8 Feature Preview
Java 8 Feature Preview
 
Java8
Java8Java8
Java8
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
 
Actors model in gpars
Actors model in gparsActors model in gpars
Actors model in gpars
 
A Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to ScalaA Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to Scala
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini india
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
 
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
 
JavaScript Programming
JavaScript ProgrammingJavaScript Programming
JavaScript Programming
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
 
Objective-c for Java Developers
Objective-c for Java DevelopersObjective-c for Java Developers
Objective-c for Java Developers
 
JAVA BASICS
JAVA BASICSJAVA BASICS
JAVA BASICS
 
Java SE 8 library design
Java SE 8 library designJava SE 8 library design
Java SE 8 library design
 
Java SE 8 best practices
Java SE 8 best practicesJava SE 8 best practices
Java SE 8 best practices
 
Functional Java 8 - Introduction
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - Introduction
 

Andere mochten auch

Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Norito Agetsuma
 
Java 7 invokedynamic の概要
Java 7 invokedynamic の概要Java 7 invokedynamic の概要
Java 7 invokedynamic の概要Taku Miyakawa
 
JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”Norito Agetsuma
 
ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月Taku Miyakawa
 
JSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjpJSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjpToshiaki Maki
 

Andere mochten auch (6)

Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点)
 
Java 7 invokedynamic の概要
Java 7 invokedynamic の概要Java 7 invokedynamic の概要
Java 7 invokedynamic の概要
 
Project Lambdaの基礎
Project Lambdaの基礎Project Lambdaの基礎
Project Lambdaの基礎
 
JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”
 
ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月
 
JSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjpJSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjp
 

Ähnlich wie Lambda: A Peek Under The Hood - Brian Goetz

Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Simon Ritter
 
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
 
Functional programming with_jdk8-s_ritter
Functional programming with_jdk8-s_ritterFunctional programming with_jdk8-s_ritter
Functional programming with_jdk8-s_ritterSimon Ritter
 
Functional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhFunctional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhHarmeet Singh(Taara)
 
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
 
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
 
What's New in Java 8
What's New in Java 8What's New in Java 8
What's New in Java 8javafxpert
 
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
 
Alive and Well with Java 8
Alive and Well with Java 8Alive and Well with Java 8
Alive and Well with Java 8Adam Pelsoczi
 
10 Tips for Java EE 7 with PrimeFaces - JavaOne 2013
10 Tips for Java EE 7 with PrimeFaces - JavaOne 201310 Tips for Java EE 7 with PrimeFaces - JavaOne 2013
10 Tips for Java EE 7 with PrimeFaces - JavaOne 2013Martin Fousek
 
Functional Programming In Jdk8
Functional Programming In Jdk8 Functional Programming In Jdk8
Functional Programming In Jdk8 Bansilal Haudakari
 
JavaOne - 10 Tips for Java EE 7 with PrimeFaces
JavaOne - 10 Tips for Java EE 7 with PrimeFacesJavaOne - 10 Tips for Java EE 7 with PrimeFaces
JavaOne - 10 Tips for Java EE 7 with PrimeFacesMert Çalışkan
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8jclingan
 
Intro Java Rev010
Intro Java Rev010Intro Java Rev010
Intro Java Rev010Rich Helton
 

Ähnlich wie Lambda: A Peek Under The Hood - Brian Goetz (20)

Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3
 
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 SE 8
Java SE 8Java SE 8
Java SE 8
 
Functional programming with_jdk8-s_ritter
Functional programming with_jdk8-s_ritterFunctional programming with_jdk8-s_ritter
Functional programming with_jdk8-s_ritter
 
Functional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhFunctional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singh
 
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
 
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
 
What's New in Java 8
What's New in Java 8What's New in Java 8
What's New in Java 8
 
Java 8-revealed
Java 8-revealedJava 8-revealed
Java 8-revealed
 
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
 
Alive and Well with Java 8
Alive and Well with Java 8Alive and Well with Java 8
Alive and Well with Java 8
 
10 Tips for Java EE 7 with PrimeFaces - JavaOne 2013
10 Tips for Java EE 7 with PrimeFaces - JavaOne 201310 Tips for Java EE 7 with PrimeFaces - JavaOne 2013
10 Tips for Java EE 7 with PrimeFaces - JavaOne 2013
 
Functional Programming In Jdk8
Functional Programming In Jdk8 Functional Programming In Jdk8
Functional Programming In Jdk8
 
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
 
JavaOne - 10 Tips for Java EE 7 with PrimeFaces
JavaOne - 10 Tips for Java EE 7 with PrimeFacesJavaOne - 10 Tips for Java EE 7 with PrimeFaces
JavaOne - 10 Tips for Java EE 7 with PrimeFaces
 
Towards Improving Interface Modularity in Legacy Java Software Through Automa...
Towards Improving Interface Modularity in Legacy Java Software Through Automa...Towards Improving Interface Modularity in Legacy Java Software Through Automa...
Towards Improving Interface Modularity in Legacy Java Software Through Automa...
 
Java 8
Java 8Java 8
Java 8
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8
 
Intro Java Rev010
Intro Java Rev010Intro Java Rev010
Intro Java Rev010
 

Mehr von JAX London

Everything I know about software in spaghetti bolognese: managing complexity
Everything I know about software in spaghetti bolognese: managing complexityEverything I know about software in spaghetti bolognese: managing complexity
Everything I know about software in spaghetti bolognese: managing complexityJAX London
 
Devops with the S for Sharing - Patrick Debois
Devops with the S for Sharing - Patrick DeboisDevops with the S for Sharing - Patrick Debois
Devops with the S for Sharing - Patrick DeboisJAX London
 
Busy Developer's Guide to Windows 8 HTML/JavaScript Apps
Busy Developer's Guide to Windows 8 HTML/JavaScript AppsBusy Developer's Guide to Windows 8 HTML/JavaScript Apps
Busy Developer's Guide to Windows 8 HTML/JavaScript AppsJAX London
 
It's code but not as we know: Infrastructure as Code - Patrick Debois
It's code but not as we know: Infrastructure as Code - Patrick DeboisIt's code but not as we know: Infrastructure as Code - Patrick Debois
It's code but not as we know: Infrastructure as Code - Patrick DeboisJAX London
 
Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerJAX London
 
Worse is better, for better or for worse - Kevlin Henney
Worse is better, for better or for worse - Kevlin HenneyWorse is better, for better or for worse - Kevlin Henney
Worse is better, for better or for worse - Kevlin HenneyJAX London
 
Java performance: What's the big deal? - Trisha Gee
Java performance: What's the big deal? - Trisha GeeJava performance: What's the big deal? - Trisha Gee
Java performance: What's the big deal? - Trisha GeeJAX London
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John StevensonJAX London
 
HTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias Wessendorf
HTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias WessendorfHTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias Wessendorf
HTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias WessendorfJAX London
 
Play framework 2 : Peter Hilton
Play framework 2 : Peter HiltonPlay framework 2 : Peter Hilton
Play framework 2 : Peter HiltonJAX London
 
Complexity theory and software development : Tim Berglund
Complexity theory and software development : Tim BerglundComplexity theory and software development : Tim Berglund
Complexity theory and software development : Tim BerglundJAX London
 
Why FLOSS is a Java developer's best friend: Dave Gruber
Why FLOSS is a Java developer's best friend: Dave GruberWhy FLOSS is a Java developer's best friend: Dave Gruber
Why FLOSS is a Java developer's best friend: Dave GruberJAX London
 
Akka in Action: Heiko Seeburger
Akka in Action: Heiko SeeburgerAkka in Action: Heiko Seeburger
Akka in Action: Heiko SeeburgerJAX London
 
NoSQL Smackdown 2012 : Tim Berglund
NoSQL Smackdown 2012 : Tim BerglundNoSQL Smackdown 2012 : Tim Berglund
NoSQL Smackdown 2012 : Tim BerglundJAX London
 
Closures, the next "Big Thing" in Java: Russel Winder
Closures, the next "Big Thing" in Java: Russel WinderClosures, the next "Big Thing" in Java: Russel Winder
Closures, the next "Big Thing" in Java: Russel WinderJAX London
 
Java and the machine - Martijn Verburg and Kirk Pepperdine
Java and the machine - Martijn Verburg and Kirk PepperdineJava and the machine - Martijn Verburg and Kirk Pepperdine
Java and the machine - Martijn Verburg and Kirk PepperdineJAX London
 
Mongo DB on the JVM - Brendan McAdams
Mongo DB on the JVM - Brendan McAdamsMongo DB on the JVM - Brendan McAdams
Mongo DB on the JVM - Brendan McAdamsJAX London
 
New opportunities for connected data - Ian Robinson
New opportunities for connected data - Ian RobinsonNew opportunities for connected data - Ian Robinson
New opportunities for connected data - Ian RobinsonJAX London
 
HTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun GuptaHTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun GuptaJAX London
 
The Big Data Con: Why Big Data is a Problem, not a Solution - Ian Plosker
The Big Data Con: Why Big Data is a Problem, not a Solution - Ian PloskerThe Big Data Con: Why Big Data is a Problem, not a Solution - Ian Plosker
The Big Data Con: Why Big Data is a Problem, not a Solution - Ian PloskerJAX London
 

Mehr von JAX London (20)

Everything I know about software in spaghetti bolognese: managing complexity
Everything I know about software in spaghetti bolognese: managing complexityEverything I know about software in spaghetti bolognese: managing complexity
Everything I know about software in spaghetti bolognese: managing complexity
 
Devops with the S for Sharing - Patrick Debois
Devops with the S for Sharing - Patrick DeboisDevops with the S for Sharing - Patrick Debois
Devops with the S for Sharing - Patrick Debois
 
Busy Developer's Guide to Windows 8 HTML/JavaScript Apps
Busy Developer's Guide to Windows 8 HTML/JavaScript AppsBusy Developer's Guide to Windows 8 HTML/JavaScript Apps
Busy Developer's Guide to Windows 8 HTML/JavaScript Apps
 
It's code but not as we know: Infrastructure as Code - Patrick Debois
It's code but not as we know: Infrastructure as Code - Patrick DeboisIt's code but not as we know: Infrastructure as Code - Patrick Debois
It's code but not as we know: Infrastructure as Code - Patrick Debois
 
Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael Barker
 
Worse is better, for better or for worse - Kevlin Henney
Worse is better, for better or for worse - Kevlin HenneyWorse is better, for better or for worse - Kevlin Henney
Worse is better, for better or for worse - Kevlin Henney
 
Java performance: What's the big deal? - Trisha Gee
Java performance: What's the big deal? - Trisha GeeJava performance: What's the big deal? - Trisha Gee
Java performance: What's the big deal? - Trisha Gee
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John Stevenson
 
HTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias Wessendorf
HTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias WessendorfHTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias Wessendorf
HTML alchemy: the secrets of mixing JavaScript and Java EE - Matthias Wessendorf
 
Play framework 2 : Peter Hilton
Play framework 2 : Peter HiltonPlay framework 2 : Peter Hilton
Play framework 2 : Peter Hilton
 
Complexity theory and software development : Tim Berglund
Complexity theory and software development : Tim BerglundComplexity theory and software development : Tim Berglund
Complexity theory and software development : Tim Berglund
 
Why FLOSS is a Java developer's best friend: Dave Gruber
Why FLOSS is a Java developer's best friend: Dave GruberWhy FLOSS is a Java developer's best friend: Dave Gruber
Why FLOSS is a Java developer's best friend: Dave Gruber
 
Akka in Action: Heiko Seeburger
Akka in Action: Heiko SeeburgerAkka in Action: Heiko Seeburger
Akka in Action: Heiko Seeburger
 
NoSQL Smackdown 2012 : Tim Berglund
NoSQL Smackdown 2012 : Tim BerglundNoSQL Smackdown 2012 : Tim Berglund
NoSQL Smackdown 2012 : Tim Berglund
 
Closures, the next "Big Thing" in Java: Russel Winder
Closures, the next "Big Thing" in Java: Russel WinderClosures, the next "Big Thing" in Java: Russel Winder
Closures, the next "Big Thing" in Java: Russel Winder
 
Java and the machine - Martijn Verburg and Kirk Pepperdine
Java and the machine - Martijn Verburg and Kirk PepperdineJava and the machine - Martijn Verburg and Kirk Pepperdine
Java and the machine - Martijn Verburg and Kirk Pepperdine
 
Mongo DB on the JVM - Brendan McAdams
Mongo DB on the JVM - Brendan McAdamsMongo DB on the JVM - Brendan McAdams
Mongo DB on the JVM - Brendan McAdams
 
New opportunities for connected data - Ian Robinson
New opportunities for connected data - Ian RobinsonNew opportunities for connected data - Ian Robinson
New opportunities for connected data - Ian Robinson
 
HTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun GuptaHTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun Gupta
 
The Big Data Con: Why Big Data is a Problem, not a Solution - Ian Plosker
The Big Data Con: Why Big Data is a Problem, not a Solution - Ian PloskerThe Big Data Con: Why Big Data is a Problem, not a Solution - Ian Plosker
The Big Data Con: Why Big Data is a Problem, not a Solution - Ian Plosker
 

Kürzlich hochgeladen

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 

Kürzlich hochgeladen (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 

Lambda: A Peek Under The Hood - Brian Goetz

  • 1. 1Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 2. Lambda: A peek under the hood Insert Picture Here Brian Goetz Java Language Architect, Oracle 2Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 3. 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. 3Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 4. About this talk  This talk outlines the technical details of how lambda expressions are implemented in Java SE 8 at the bytecode level – This will be a highly technical talk! – We assume some familiarity with JVM and bytecode – Including JSR-292 facilities 4Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 5. Lambda expressions for Java  A lambda expression is like an “anonymous method” – Has an argument list, a return type, and a body – people.forEach((Person e) -> names.add(e.getName()); – Many of these can be inferred by the compiler – people.forEach(e -> names.add(e.getName());  Lambda expressions can capture values from the enclosing context – people.removeAll(e -> e.getAge() < minAge); 5Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 6. Why lambdas for Java?  Provide libraries a path to multicore – Parallel-friendly APIs need internal iteration – Internal iteration needs a concise code-as-data mechanism  Empower library developers – Enable a higher degree of cooperation between libraries and client code  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  Inner classes give us some of these benefits, but are too clunky – Clunkiness is not entirely syntactic!  How to represent lambda expressions at runtime is not a trivial question – That’s what this talk is about 6Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 7. Lambda expressions for Java  Big question #1: what is the type of a lambda expression? – Most languages with lambdas have some notion of a function type – Java has no concept of function type – JVM has no native (unerased) representation of function type in VM type signatures  Adding function types would create many questions – How do we represent functions in VM type signatures? – How do we create instances of function-typed variables? – How do we deal with variance?  Want to avoid significant VM changes 7Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 8. Functional interfaces  We have historically modeled functions using single-method interfaces, such as Runnable or Comparator  Rather than complicate the type system, let’s just formalize that – Give them a name: “functional interfaces” – Always convert lambda expressions to instance of a functional interface interface Predicate<T> { boolean test(T x); } people.removeAll(p -> p.getAge() >= 18); – Compiler figures out the types – lambda is converted to Predicate<Person>  How does the lambda instance get created? 8Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 9. Why not “just” use inner classes?  We could say that a lambda is “just” an inner class instance  Then for the lambda p -> p.getAge() >= minAge we generate class Foo$1 implements Predicate<Person> { private final int $v0; Foo$1(int v0) { this.$v0 = v0; } public boolean test(Person p) { return p.age < $v0; } }  This means (among other things) one class per lambda expression 9Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 10. Why not “just” use inner classes?  If we translate lambdas to inner classes, then capturing a lambda is invoking a constructor list.removeAll(p -> p.getAge() >= minAge); list.removeAll(new Foo$1(minAge)); 10Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 11. Why not “just” use inner classes?  Inner class constructor invocation translates as list.removeAll(p -> p.getAge() >= minAge); aload_1 // list new #2 // class Foo$1 dup iload_2 // minAge invokespecial #3 // Method Foo$1."<init>":(I)V invokeinterface #4 // java/util/List.removeAll:(Ljava/util/functions/Predicate;)Z 11Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 12. Why not “just” use inner classes?  Translating to inner classes means we inherit most of their problems – Performance issues – One class per lambda expression – Type profile pollution – Complicated “comb” lookup  Whatever we do becomes a binary representation for lambdas in Java – Would be stuck with it forever – Would rather not conflate implementation with binary representation 12Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 13. Bytecode invocation modes  Prior to Java SE 7, the JVM had four bytecodes for method invocation – invokestatic: for static methods – invokevirtual: for class methods – invokeinterface: for interface methods – invokespecial: for constructors, private methods, and super-calls  aload_1 specifies a// list name, method name, and method signature Each class new #2 // class Foo$1 dup iload_2 // minAge invokespecial #3 // Method Foo$1."<init>":(I)V invokeinterface #4 // java/util/List.removeAll:(Ljava/util/functions/Predicate;)Z 13Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 14. New bytecode tool: MethodHandle  Java SE 7 adds VM-level method handles – Can store references to methods in the constant pool and load with LDC – Can obtain a method handle for any method (or field access) – VM will happily inline through MH calls – MH API contains combinators for manipulating method handles – Add, remove, reorder arguments – Adapt (box, unbox, cast) arguments and return types – Compose methods – Compiler writers swiss-army knife! 14Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 15. Why not “just” use MethodHandle?  At first, translating lambdas to MethodHandle seems obvious – Lambda is language-level method object – MethodHandle is VM-level method object  We could – Desugar lambdas expressions to methods – Represent lambdas using MethodHandle in bytecode signatures 15Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 16. Why not “just” use MethodHandle?  If we represented lambdas as MethodHandle, we’d translate: list.removeAll(p -> p.getAge() >= minAge); MethodHandle mh = LDC[lambda$1]; mh = MethodHandles.insertArguments(mh, 0, minAge); list.removeAll(mh); private static boolean lambda$1(int capturedK, Person p) { return p.getAge() >= capturedK; } 16Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 17. Why not “just” use MethodHandle?  If we did this, the signature of List.removeAll would be: void removeAll(MethodHandle predicate)  This is erasure on steroids! – Can’t overload two methods that take differently “shaped” lambdas – Still would need to encode the erased type information somewhere  Also: is MH invocation performance yet competitive with bytecode invocation?  Again: conflates binary representation with implementation 17Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 18. Stepping back…  We would like a binary interface not tied to a specific implementation – Inner classes have too much baggage – MethodHandle is too low-level, is erased – Can’t force users to recompile, ever, so have to pick now  What we need is … another level of indirection – Let the static compiler emit a declarative recipe, rather than imperative code, for creating a lambda – Let the runtime execute that recipe however it deems best – And make it darned fast – This sounds like a job for invokedynamic! 18Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 19. New bytecode tool: invokedynamic  Java SE 7 adds a fifth invocation mode: invokedynamic (indy)  Behavior of invoke{virtual,static,interface} are fixed and Java-like – Other languages need custom method linkage  Basic idea: let some “language logic” determine call target – And then get out of the way – Language and VM become partners in flexible and efficient method dispatch 19Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 20. New bytecode tool: invokedynamic  The canonical use case for invokedynamic is something like def add(a, b) { a+b }  Here, the types of a and b are not known at compile time – And can change from call to call … but probably don’t so often – Good chance that if called with two ints, next call will be with two ints – We win by not having to re-link the call site for every invocation 20Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 21. New bytecode tool: invokedynamic  The first time the JVM executes an invokedynamic – Consults the bootstrap method for the call site (the “language logic”) – Bootstrap returns a linked call site – Call site can embed conditions under which it needs relinking – Such as the argument types changing – Otherwise, JVM does not have to consult bootstrap again  After linkage, JVM can inline through linked indy callsites 21Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 22. New bytecode tool: invokedynamic  An indy callsite has three groups of operands – A bootstrap method (the “language logic”) – Called by the VM for linking the callsite on first invocation – Not called again after that – A static argument list, embedded in the constant pool – Available to the bootstrap method – A dynamic argument list, like any other method invocation – Not available to the bootstrap, but their static types and arity are – Passed to whatever method the callsite is linked to 22Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 23. Its not just for dynamic languages anymore  So, if indy is for dynamic languages, why is the Java compiler using it? – All the types involved are static – What is dynamic here is the code generation strategy – Generate inner classes? – Use method handles? – Use dynamic proxies? – Use VM-private APIs for constructing objects?  Indy lets us turn this choice into a pure implementation detail – Separate from the binary representation 23Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 24. Its not just for dynamic languages anymore  We use indy to embed a recipe for constructing a lambda at the capture site, including – The desugared implementation method – The functional interface we are converting to – Values captured from the lexical scope – Additional metadata, such as serialization information  The capture site is called the lambda factory – Invoked with indy, returns an instance of the desired functional interface – Subsequent captures bypass the (slow) linkage path 24Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 25. Desugaring lambdas to methods  First, we desugar the lambda to a method – Signature matches functional interface method – Plus captured arguments prepended (must be effectively final) – Simplest lambdas desugar to static methods – But some need access to receiver, and so are instance methods Predicate<Person> olderThanK = p -> p.getAge() >= k; private static boolean lambda$1(int capturedK, Person p) { return p.getAge() >= capturedK; } 25Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 26. Factories and metafactories  We generate an indy call site which, when called, returns the lambda – This is the lambda factory – Bootstrap for the lambda factory list.removeAll(p -> p.getAge() >= minAge); selects the translation strategy – Bootstrap is called the lambda metafactory Predicate $p = indy[bootstrap=LambdaMetafactory, – Part of Java runtime staticargs=[Predicate, lambda$1], dynargs=[minAge]) – Captured args passed list.removeAll($p); to lambda factory private static boolean lambda$1(int capturedK, Person p) { return p.getAge() >= capturedK; } 26Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 27. Translation strategies  The metafactory could spin inner classes dynamically – Generate the same class the compiler would, just at runtime – Link factory call site to constructor of generated class – Conveniently, dynamic args and ctor args will line up – Our initial strategy until we can prove that there’s a better one  Alternately could spin one wrapper class per interface – Constructor would take a method handle – Methods would invoke that method handle  Could also use dynamic proxies or MethodHandleProxy  Or VM-private APIs to build object from scratch, or… 27Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 28. Indy: the ultimate lazy initialization  For stateless (non-capturing) lambdas, we can create one single instance of the lambda object and always return that – Very common case – many lambdas capture nothing – People sometimes do this by hand in source code – e.g., pulling a Comparator into a static final variable  Indy functions as a lazily initialized cache – Defers initialization cost to first use – No overhead if lambda is never used – No extra field or static initializer – All stateless lambdas get lazy init and caching for free 28Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 29. Indy: the ultimate procrastination aid  By deferring the code generation choice to runtime, it becomes a pure implementation detail – Can be changed dynamically – We can settle on a binary protocol now (metafactory API) while delaying the choice of code generation strategy – Moving more work from static compiler to runtime – Can change code generation strategy across VM versions, or even days of the week 29Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 30. Indy: the ultimate indirection aid  Just because we defer code generation strategy to runtime, we don’t have to pay the price on every call – Metafactory only invoked once per call site – For non-capturing case, subsequent captures are FREE – VM optimizes to constant load – For capturing case, subsequent capture cost on order of a constructor call / method handle manipulation – MF links to constructor for generated class 30Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 31. Performance costs  Any translation scheme imposes costs at several levels: – Linkage cost – one-time cost of setting up capture – Capture cost – cost of creating a lambda – Invocation cost – cost of invoking the lambda method  For inner class instances, these correspond to: – Linkage: loading the class – Capture: invoking the constructor – Invocation: invokeinterface 31Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 32. Performance example – capture cost  Oracle Performance Team measured capture costs – 4 socket x 10 core x 2 thread Nehalem EX server – All numbers in ops/uSec  Worst-case lambda numbers equal to inner classes Single-threaded Saturated – Best-case numbers much better Scalability – Inner class And this is 160 our “fallback” strategy just 1407 8.8x Non-capturing lambda 636 23201 36.4x Capturing lambda 160 1400 8.8x 32Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 33. Not just for the Java Language!  The lambda conversion metafactories will be part of java.lang.invoke – Semantics tailored to Java language needs – But, other languages may find it useful too!  Java APIs will be full of functional interfaces – Collection.forEach(Block)  Other languages probably will want to call these APIs – Maybe using their own closures – Will want a similar conversion  Since metafactories are likely to receive future VM optimization attention, using platform runtime is likely to be faster than spinning your own inner classes 33Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 34. Possible VM support  VM could intrinsify lambda capture sites – Capture semantics are straightforward properties of method handles – Capture operation is pure, therefore freely reorderable – Can use code motion to delay/eliminate captures  Lambda capture is like a “boxing” operation – Essentially boxing a method handle into lambda object – Invocation is the corresponding “unbox” – Can use box elimination techniques to eliminate capture overhead – Intrinsification of capture + inline + escape analysis 34Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 35. Serialization  No language feature is complete without some interaction with serialization  – Users will expect this code to work interface Foo extends Serializable { public boolean eval(); } Foo f = () -> false; // now serialize f  We can’t just serialize the lambda object – Implementing class won’t exist at deserialization time – Deserializing VM may use a different translation strategy – Need a dynamic serialization strategy too! – Without exposing security holes… 35Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 36. Serialization  Just as our classfile representation for a lambda is a recipe, our serialized representation needs to be to – We can use readResolve / writeReplace – Instead of serializing lambda directly, serialize the recipe (say, to some well defined interface SerializedLambda) – This means that for serializable lambdas, MF must provide a way of getting at the recipe – We provide an alternate MF bootstrap for that  On deserialization, reconstitute from recipe – Using then-current translation strategy, which might be different from the one that originally created the lambda – Without opening new security holes 36Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 37. Summary  We use invokedynamic to capture lambda expressions – Gives us flexibility and performance – Free to change translation strategy at runtime  Even using the “dumb” translation strategy… – No worse than inner classes in the worst case – 5-20x better than inner classes in a common case 37Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 38. For more information  Project Lambda: http://openjdk.java.net/projects/lambda/ – Lambda spec EDR #2: http:// jcp.org/aboutJava/communityprocess/edr/jsr335/index2.html – Lambda Overview: http://cr.openjdk.java.net/~ briangoetz/lambda/lambda-state-4.html – Binary builds: http://jdk8.java.net/lambda/ 38Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 39. Graphic Section Divider 39Copyright © 2012, Oracle and/or its affiliates. All rights reserved.