closures for java
DESCRIPTION
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. - PowerPoint PPT PresentationTRANSCRIPT
2007 JavaOneSM Conference | Session TS-2294 |
TS-2294
Closures for Java
Neal Gafter
YOUR LOGOHERE
2007 JavaOneSM Conference | Session 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
2007 JavaOneSM Conference | Session TS-2294 | 3
Outline
Goals, DefinitionsExisting solutionsRequirementsSpecificationExamplesNew APIs
2007 JavaOneSM Conference | Session TS-2294 | 4
Outline
Goals, DefinitionsExisting solutionsRequirementsSpecificationExamplesNew APIs
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 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.
2007 JavaOneSM Conference | Session TS-2294 | 7
Definition: Control API
• API-specific statement forms
• “special” methods, invocations
• On par with built-in statements
2007 JavaOneSM Conference | Session TS-2294 | 8
Outline
Goals, DefinitionsExisting solutionsRequirementsSpecificationExamplesNew APIs
2007 JavaOneSM Conference | Session TS-2294 | 9
Example: For-EachUsing 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());
}
}
2007 JavaOneSM Conference | Session TS-2294 | 10
Example: For-Eachdesired
for (String s : strings) doThing(s);
actual
forEach(strings, new OneArg<String>() {
public void invoke(String s) {
doThing(s);
}
});
2007 JavaOneSM Conference | Session TS-2294 | 11
Example: For-Eachdesired
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!
}
});
2007 JavaOneSM Conference | Session TS-2294 | 12
Example: For-Eachdesired
for (String s : strings)
if (…) throw new MyException();
actual
forEach(strings, new OneArg<String>() {
public void invoke(String s) {
if (…) throw new MyException(); // error!
}
});
2007 JavaOneSM Conference | Session TS-2294 | 13
Example: For-Eachdesired
for (String s : strings)
if (…) return computeResult(s);
actual
forEach(strings, new OneArg<String>() {
public void invoke(String s) {
if (…) return computeResult(s); // error!
}
});
2007 JavaOneSM Conference | Session TS-2294 | 14
Example: For-Eachdesired
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!
}
});
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 16
Outline
Goals, DefinitionsExisting solutionsRequirementsSpecificationExamplesNew APIs
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 20
An app-specific example: time
long t0 = System.nanoTime();boolean success = false;try { doSomething(); success = true;} finally { recordTime(“doSomething”, success, System.nanoTime() – t0);}
2007 JavaOneSM Conference | Session TS-2294 | 21
An app-specific example: time
time(“doSomething”) { doSomething();}
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 23
Outline
Goals, DefinitionsExisting solutionsRequirementsSpecificationExamplesNew APIs
2007 JavaOneSM Conference | Session TS-2294 | 24
Closures Specification
• Syntax and Semantics• closure expressions• function types• control statements
• Transparency• local variables• exceptions• control transfers• completion (reachable)
2007 JavaOneSM Conference | Session TS-2294 | 25
Syntax: Closure Expressions
{int x => x+1}
{int x, int y => x+y}
{String x => Integer.parseInt(x)}
{=> System.out.println(“hello”);}
2007 JavaOneSM Conference | Session TS-2294 | 26
Syntax: Closure Expressions
Primary:Closure
Closure:{ FormalParameterDeclsopt => BlockStatementsopt Expressionopt }
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 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
2007 JavaOneSM Conference | Session TS-2294 | 29
Syntax: Function Types
{int => int}
{int, int => int}
{String => int throws NumberFormatException}
{ => void}
{T => U}
2007 JavaOneSM Conference | Session TS-2294 | 30
Syntax: Function Types
Type:{TypeListopt => Type FunctionThrowsopt }
2007 JavaOneSM Conference | Session TS-2294 | 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;
}
2007 JavaOneSM Conference | Session TS-2294 | 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)
2007 JavaOneSM Conference | Session TS-2294 | 33
Syntax: Control Statements
withLock(lock, {=> doSomething();});
2007 JavaOneSM Conference | Session TS-2294 | 34
Syntax: Control Statements
withLock(lock) { doSomething();}
2007 JavaOneSM Conference | Session TS-2294 | 35
Syntax: Control Statements
ControlStatement:
foropt Primary ( Formals : ExpressionListopt ) Statement
foropt Primary ( ExpressionListopt ) Statement
Is translated to
Primary( ExpressionList, { Formals => Statement });
2007 JavaOneSM Conference | Session TS-2294 | 36
Outline
Goals, DefinitionsExisting solutionsRequirementsSpecificationExamplesNew APIs
2007 JavaOneSM Conference | Session TS-2294 | 37
Perform some operation while holding a java.util.concurrent.Lock (today)
Example: Control APIs
void incrementBalance(int deposit) {
myLock.lock();
try {
balance += deposit;
} finally {
myLock.unlock();
}
}
2007 JavaOneSM Conference | Session TS-2294 | 38
Using a proposed new closure-based APIExample: Control APIs
void incrementBalance(int deposit) {
Locks.withLock(myLock,
{ => balance += deposit; });
}
2007 JavaOneSM Conference | Session TS-2294 | 39
Using the control statement syntaxExample: Control APIs
void incrementBalance(int deposit) {
Locks.withLock(myLock) {
balance += deposit;
}
}
2007 JavaOneSM Conference | Session TS-2294 | 40
Make a new list by applying a function to each element of an existing list
Example: Aggregate Operations
List<Integer> parseInts(List<String> strings)
throws NumberFormatException {
return Collections.map(
strings, {String s => Integer.decode(s)});
}
2007 JavaOneSM Conference | Session TS-2294 | 41
Launch a task using an Executor (today)Example: Interaction w/ Existing APIs
void launch(Executor ex) {
ex.execute(new Runnable() {
public void run() {
doSomething();
}
});
}
2007 JavaOneSM Conference | Session TS-2294 | 42
Launch a task using an Executor (closure)Example: Interaction w/ Existing APIs
void launch(Executor ex) {
ex.execute({ =>
doSomething();
});
}
2007 JavaOneSM Conference | Session TS-2294 | 43
Or, using the control statement syntaxExample: Interaction w/ Existing APIs
void launch(Executor ex) {
ex.execute() {
doSomething();
}
}
2007 JavaOneSM Conference | Session TS-2294 | 44
Add a swing listener (today)Example: Interaction w/ Existing APIs
void addListener(final ItemSelectable is) {
is.addItemListener(
new ItemListener() {
public void itemStateChanged(ItemEvent e)
{ doSomething(e, is); }
}
);
}
2007 JavaOneSM Conference | Session TS-2294 | 45
Add a swing listener (closure)Example: Interaction w/ Existing APIs
void addListener(final ItemSelectable is) {
is.addItemListener(
{ ItemEvent e => doSomething(e, is); }
);
}
2007 JavaOneSM Conference | Session TS-2294 | 46
Or, using the control statement syntaxExample: Interaction w/ Existing APIs
void addListener(final ItemSelectable is) {
is.addItemListener(ItemEvent e :) {
doSomething(e, is);
}
}
2007 JavaOneSM Conference | Session TS-2294 | 47
Outline
Goals, DefinitionsExisting solutionsRequirementsSpecificationExamplesNew APIs
2007 JavaOneSM Conference | Session TS-2294 | 48
New APIs
• API-specific control constructs• Collections• Concurrency• Closables
• Aggregate operations• Functional Primitives
2007 JavaOneSM Conference | Session TS-2294 | 49
Map-specific iteration
Map<Key,Value> map = …;
for eachEntry(Key k, Value v : map) {
// operate with k, v here
}
2007 JavaOneSM Conference | Session TS-2294 | 50
Locking
Lock lock = …;
withLock(lock) {
// lock held here
}
2007 JavaOneSM Conference | Session TS-2294 | 51
Closing Streams
with(InputStream s: expr) { // operate on stream}
• The stream is closed on completion
2007 JavaOneSM Conference | Session TS-2294 | 52
Aggregate Operations
List<Integer> list = …;
Integer sum = Collections.reduce( list, {Integer x, Integer y => x+y});
2007 JavaOneSM Conference | Session TS-2294 | 53
More complex APIs
• Fork-Join Concurrency (Doug Lea)• Functional and Higher-order Utilities
• AOP?• Continuations?• Multiple dispatch?
2007 JavaOneSM Conference | Session TS-2294 | 54
For More Information
• Closures in Java BOF• http://www.javac.info/• http://gafter.blogspot.com/