SlideShare a Scribd company logo
Closures for Java
       …and other thoughts on language evolution




Neal Gafter
Google
1680
2


Goals for Language Change

> Simplify programs
  – More concise
  – Don’t Repeat Yourself (DRY)
  – Make reading, writing easier


> Fewer bugs


> Adapt to changing requirements
  – Multicore and concurrency
  – Enable programmer flexibility (expressiveness)
3


What is a Closure

> A closure is an anonymous function expression


> Like
  – Block in Smalltalk, Ruby, Scala
  – Lambda in Lisp
  – Anonymous function in Javascript
4


DRY (Don’t Repeat Yourself)

InputStream s = openStream();
try {
    doSomething(s);
} finally {
                                        where
    try { s.close(); }
    catch(IOException ex) {
                                        <T extends Closeable>
        LOGGER.log(…);
                                        void with(T s, {T => void} block) {
    }                                       try {
}                                               block.invoke(s);
                                            } finally {
   becomes                                      try ( s.close(); }
                                                catch(IOException ex) {
                                                    LOGGER.log(…);
with (InputStream s : openStream()) {
                                                }
    doSomething(s);
                                            }
}                                       }
5


DRY (Don’t Repeat Yourself)

long t0 = System.nanoTime();
boolean success = false;
try {
    doSomething();
                                          where
    success = true;
} finally {                               void time(String key, Block block) {
    recordTime(“doSomething”, success,        long t0 = System.nanoTime();
               System.nanoTime() – t0);       boolean success = false;
                                              try {
}
                                                  block.invoke();
                                                  success = true;
   becomes                                    } finally {
                                                  recordTime(
time (“doSomething”) {                                key, success,
                                                      System.nanoTime() – t0);
    doSomething();
                                              }
}
                                          }
6


DRY (Don’t Repeat Yourself)

for (Map.Entry<String,Thing> e : myMap.entrySet()) {
    String name = e.getKey();
    Thing thing = e.getValue();
    doSomething(key, value);
}


   becomes

for each(String name, Thing thing : myMap) {
    doSomething(name, thing);
}


             <K,V> void for each(Map<K,V> map, {K,V => void} block) {
                 for (Map.Entry<K,V> e : myMap.entrySet()) {
   where
                     block.invoke(e.getKey(), e.getValue());
                 }
             }
7


Make reading, writing easier

void addListener(final ItemSelectable is) {
    is.addItemListener(
         new ItemListener() {
             public void itemStateChanged(ItemEvent e)
                 { doSomething(e, is); }
         }
    );
}
                                   becomes

void addListener(ItemSelectable is) {
    is.addItemListener(
         { ItemEvent e => doSomething(e, is); }
    );
}
8


Make reading, writing easier

void launch(Executor ex) {
    ex.execute(new Runnable() {
          public void run() {
              doSomething();
          }
    });
}
                                  becomes

void launch(Executor ex) {
    ex.execute({ =>
          doSomething();
    });
}
9


Benefits of being DRY

> Less boilerplate


  – Programs easier to read


  – Fewer bugs


> Hard things become easy
  – Fork- join concurrency
10


Multicore and Concurrency

> Need concurrency to exploit Moore’s Law
11


Multicore and Concurrency

> Need concurrency to exploit Moore’s Law


> Thread- based concurrency is hard
12


Multicore and Concurrency

> Need concurrency to exploit Moore’s Law


> Thread- based concurrency is hard


> Fork- Join concurrency is easier
  – Concurrent Loops
13


Multicore and Concurrency

> Need concurrency to exploit Moore’s Law


> Thread- based concurrency is hard


> Fork- Join concurrency is easier
  – Concurrent Loops


> But more will be needed in the future
  – Actors
  – Functional Programming
  – Software Transactional Memory
14


Enable Programmer Flexibility
(expressiveness)
> Programmers “grow” a language by adding APIs


> See Guy Steele’s “Growing a Language”
        If you give a person a fish, he can eat for a day.
        If you teach a person to fish, he can eat his whole life long.
15


Enable Programmer Flexibility
(expressiveness)
> Programmers “grow” a language by adding APIs


> See Guy Steele’s “Growing a Language”


> Support more flexible “language extension” by API


> Reduce the need for future language change
16


There is more to Java (SE) than Java (PL)

> The VM


> Deployment


> Other languages


>…
Neal Gafter   http:/ / www.javac.info/
Google        neal@gafter.com

More Related Content

Closures for Java

  • 1. Closures for Java …and other thoughts on language evolution Neal Gafter Google 1680
  • 2. 2 Goals for Language Change > Simplify programs – More concise – Don’t Repeat Yourself (DRY) – Make reading, writing easier > Fewer bugs > Adapt to changing requirements – Multicore and concurrency – Enable programmer flexibility (expressiveness)
  • 3. 3 What is a Closure > A closure is an anonymous function expression > Like – Block in Smalltalk, Ruby, Scala – Lambda in Lisp – Anonymous function in Javascript
  • 4. 4 DRY (Don’t Repeat Yourself) InputStream s = openStream(); try { doSomething(s); } finally { where try { s.close(); } catch(IOException ex) { <T extends Closeable> LOGGER.log(…); void with(T s, {T => void} block) { } try { } block.invoke(s); } finally { becomes try ( s.close(); } catch(IOException ex) { LOGGER.log(…); with (InputStream s : openStream()) { } doSomething(s); } } }
  • 5. 5 DRY (Don’t Repeat Yourself) long t0 = System.nanoTime(); boolean success = false; try { doSomething(); where success = true; } finally { void time(String key, Block block) { recordTime(“doSomething”, success, long t0 = System.nanoTime(); System.nanoTime() – t0); boolean success = false; try { } block.invoke(); success = true; becomes } finally { recordTime( time (“doSomething”) { key, success, System.nanoTime() – t0); doSomething(); } } }
  • 6. 6 DRY (Don’t Repeat Yourself) for (Map.Entry<String,Thing> e : myMap.entrySet()) { String name = e.getKey(); Thing thing = e.getValue(); doSomething(key, value); } becomes for each(String name, Thing thing : myMap) { doSomething(name, thing); } <K,V> void for each(Map<K,V> map, {K,V => void} block) { for (Map.Entry<K,V> e : myMap.entrySet()) { where block.invoke(e.getKey(), e.getValue()); } }
  • 7. 7 Make reading, writing easier void addListener(final ItemSelectable is) { is.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent e) { doSomething(e, is); } } ); } becomes void addListener(ItemSelectable is) { is.addItemListener( { ItemEvent e => doSomething(e, is); } ); }
  • 8. 8 Make reading, writing easier void launch(Executor ex) { ex.execute(new Runnable() { public void run() { doSomething(); } }); } becomes void launch(Executor ex) { ex.execute({ => doSomething(); }); }
  • 9. 9 Benefits of being DRY > Less boilerplate – Programs easier to read – Fewer bugs > Hard things become easy – Fork- join concurrency
  • 10. 10 Multicore and Concurrency > Need concurrency to exploit Moore’s Law
  • 11. 11 Multicore and Concurrency > Need concurrency to exploit Moore’s Law > Thread- based concurrency is hard
  • 12. 12 Multicore and Concurrency > Need concurrency to exploit Moore’s Law > Thread- based concurrency is hard > Fork- Join concurrency is easier – Concurrent Loops
  • 13. 13 Multicore and Concurrency > Need concurrency to exploit Moore’s Law > Thread- based concurrency is hard > Fork- Join concurrency is easier – Concurrent Loops > But more will be needed in the future – Actors – Functional Programming – Software Transactional Memory
  • 14. 14 Enable Programmer Flexibility (expressiveness) > Programmers “grow” a language by adding APIs > See Guy Steele’s “Growing a Language” If you give a person a fish, he can eat for a day. If you teach a person to fish, he can eat his whole life long.
  • 15. 15 Enable Programmer Flexibility (expressiveness) > Programmers “grow” a language by adding APIs > See Guy Steele’s “Growing a Language” > Support more flexible “language extension” by API > Reduce the need for future language change
  • 16. 16 There is more to Java (SE) than Java (PL) > The VM > Deployment > Other languages >…
  • 17. Neal Gafter http:/ / www.javac.info/ Google neal@gafter.com