1 / 55

Closures for Java

YOUR LOGO HERE. Closures for Java. Neal Gafter Google. TS-2294. Why add Closures?. "In another thirty years people will laugh at anyone who tries to invent a language without closures, just as they'll laugh now at anyone who tries to invent a language without recursion." -Mark Jason Dominus.

damian
Download Presentation

Closures for Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. YOUR LOGO HERE Closures for Java Neal Gafter Google TS-2294

  2. Why add Closures? "In another thirty years people will laugh at anyone who tries to invent a language without closures, just as they'll laugh now at anyone who tries to invent a language without recursion." -Mark Jason Dominus

  3. Outline Goals, Definitions Existing solutions Requirements Specification Examples New APIs

  4. Outline Goals,Definitions Existing solutions Requirements Specification Examples New APIs

  5. Goals • Concise “function” literals • without the pain of anonymous instances • Interoperate with existing APIs • Enable control APIs • Functional and Aggregate Operations • Simple but powerful

  6. Definition: Closure A closure is a function that refers to free variables in its lexical context. A function is a block of code with parameters. It may produce a result value. A free variable is an identifier used but not defined by the closure.

  7. Definition: Control API • API-specific statement forms • “special” methods, invocations • On par with built-in statements

  8. Outline Goals, Definitions Existing solutions Requirements Specification Examples New APIs

  9. Example: For-Each Using anonymous instances interface OneArg<A> { void invoke(A arg); } <T> void forEach(Collection<T> c, OneArg<T> block) { for (Iterator<T> it = c.iterator(); c.hasNext();) { block.invoke(it.next()); } }

  10. Example: For-Each desired for (String s : strings) doThing(s); actual forEach(strings, new OneArg<String>() { public void invoke(String s) { doThing(s); } });

  11. Example: For-Each desired String toString(Thing t) { … } for (Thing t : things) println(toString(t)); actual forEach(things, new OneArg<Thing>() { public void invoke(Thing t) { println(toString(t)); // error! } });

  12. Example: For-Each desired for (String s : strings) if (…) throw new MyException(); actual forEach(strings, new OneArg<String>() { public void invoke(String s) { if (…) throw new MyException(); // error! } });

  13. Example: For-Each desired for (String s : strings) if (…) return computeResult(s); actual forEach(strings, new OneArg<String>() { public void invoke(String s) { if (…) return computeResult(s); // error! } });

  14. Example: For-Each desired String found = null; for (String s : strings) if (…) found = s; actual forEach(strings, new OneArg<String>() { public void invoke(String s) { if (…) found = s; // error! } });

  15. Anonymous Instances • Verbose, extra wordy, clumsy, redundant • Closures are concise • Incomplete capture of lexical context • this, toString, etc. • return, break, continue • non-final local variables • Force irrelevant refactoring • Control APIs not possible • can’t wrap an arbitrary block of code

  16. Outline Goals, Definitions Existing solutions Requirements Specification Examples New APIs

  17. interface Candidate { Set<Qualification> qualifications(); } interface CandidatePool extends Collection<Candidate> { Object lock(); } Candidate recruit(CandidatePool candidates, Set<Qualification> requirements) { synchronized (candidates.lock()) { for (Candidate c : candidates) { if (c.qualifications() .containsAll(requirements)) { candidates.remove(c); return c; } } } return recruitForeign(requirements); } Program to be refactored

  18. interface Candidate { Set<Qualification> qualifications(); } interface CandidatePool extends Collection<Candidate> { Lock lock(); } Candidate recruit(CandidatePool candidates, Set<Qualification> requirements) { withLock (candidates.lock()) { for (Candidate c : candidates) { if (c.qualifications() .containsAll(requirements)) { candidates.remove(c); return c; } } } return recruitForeign(requirements); } Program refactored

  19. interface Candidate { Set<Qualification> qualifications(); } interface CandidatePool extends Collection<Candidate> { Lock lock(); } Candidate recruit(CandidatePool candidates, Set<Qualification> requirements) { withLock (candidates.lock()) { for (Candidate c : candidates) { if (c.qualifications() .containsAll(requirements)) { candidates.remove(c); return c; } } } return recruitForeign(requirements); } Program refactored

  20. An app-specific example: time long t0 = System.nanoTime(); boolean success = false; try { doSomething(); success = true; } finally { recordTime(“doSomething”, success, System.nanoTime() – t0); }

  21. An app-specific example: time time(“doSomething”) { doSomething(); }

  22. Requirements for Closures • Simplify vs anonymous instances • Interoperate with existing APIs • Concise • Wrapped code not changed • Support Control APIs • API-specific control statements • On par with built-in statement forms

  23. Outline Goals, Definitions Existing solutions Requirements Specification Examples New APIs

  24. Closures Specification • Syntax and Semantics • closure expressions • function types • control statements • Transparency • local variables • exceptions • control transfers • completion (reachable)

  25. Syntax: Closure Expressions {int x => x+1} {int x, int y => x+y} {String x => Integer.parseInt(x)} {=> System.out.println(“hello”);}

  26. Syntax: Closure Expressions Primary:Closure Closure: { FormalParameterDeclsopt => BlockStatementsoptExpressionopt }

  27. Semantics: Closure Expressions • Creates an object that represents • code of the body • lexical context • Few restrictions • May access locals, this • May return from enclosing method

  28. Semantics: Closure Expressions • The closure conversion turns a closure into an instance of some interface • Provides interoperability with existing APIs. • You can restrict the closure’s operations • If no target type,use the natural function type

  29. Syntax: Function Types {int => int} {int, int => int} {String => int throws NumberFormatException} { => void} {T => U}

  30. Syntax: Function Types Type:{TypeListopt=> Type FunctionThrowsopt}

  31. Semantics: Function Types {String => int throws NumberFormatException} is shorthand for java.lang.function.IO<String,NumberFormatException> where package java.lang.function; public interface IO<A, X extends Exception> { int invoke(A a0) throws X; }

  32. Semantics: Function Types • “Ordinary” interface types • with an invoke method • You can extend, implement them • Declare variables, parameters, return types, etc. • Covariant results, etc. • (No special type rules)

  33. Syntax: Control Statements withLock(lock, {=> doSomething(); });

  34. Syntax: Control Statements withLock(lock) { doSomething(); }

  35. Syntax: Control Statements ControlStatement:foroptPrimary(Formals : ExpressionListopt)StatementforoptPrimary(ExpressionListopt)Statement Is translated to Primary( ExpressionList, { Formals=>Statement });

  36. Outline Goals, Definitions Existing solutions Requirements Specification Examples New APIs

  37. Example: Control APIs Perform some operation while holding a java.util.concurrent.Lock (today) void incrementBalance(int deposit) { myLock.lock(); try { balance += deposit; } finally { myLock.unlock(); } }

  38. Example: Control APIs Using a proposed new closure-based API void incrementBalance(int deposit) { Locks.withLock(myLock, { => balance += deposit; }); }

  39. Example: Control APIs Using the control statement syntax void incrementBalance(int deposit) { Locks.withLock(myLock) { balance += deposit; } }

  40. Example: Aggregate Operations Make a new list by applying a function to each element of an existing list List<Integer> parseInts(List<String> strings) throws NumberFormatException { return Collections.map( strings, {String s => Integer.decode(s)}); }

  41. Example: Interaction w/ Existing APIs Launch a task using an Executor (today) void launch(Executor ex) { ex.execute(new Runnable() { public void run() { doSomething(); } }); }

  42. Example: Interaction w/ Existing APIs Launch a task using an Executor (closure) void launch(Executor ex){ ex.execute({ => doSomething(); }); }

  43. Example: Interaction w/ Existing APIs Or, using the control statement syntax void launch(Executor ex) { ex.execute() { doSomething(); } }

  44. Example: Interaction w/ Existing APIs Add a swing listener (today) void addListener(final ItemSelectable is){ is.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent e) { doSomething(e, is); } } ); }

  45. Example: Interaction w/ Existing APIs Add a swing listener (closure) void addListener(final ItemSelectable is){ is.addItemListener( { ItemEvent e => doSomething(e, is); } ); }

  46. Example: Interaction w/ Existing APIs Or, using the control statement syntax void addListener(final ItemSelectable is){ is.addItemListener(ItemEvent e :) { doSomething(e, is); } }

  47. Outline Goals, Definitions Existing solutions Requirements Specification Examples New APIs

  48. New APIs • API-specific control constructs • Collections • Concurrency • Closables • Aggregate operations • Functional Primitives

  49. Map-specific iteration Map<Key,Value> map = …; for eachEntry(Key k, Value v : map) { // operate with k, v here }

  50. Locking Lock lock = …; withLock(lock) { // lock held here }

More Related