Closures v Jave — funkce se bouří
Málokterý materiál týkající se Javy vyvolal v poslední době takový rozruch jako návrh začlenění funkčních typů a inline funkcí nazývaných Closures, za kterým stojí čtveřice Gilad Bracha, Neal Gafter, James Gosling, Peter von der Ahé. Přímou podporu funkčních typů mají například jazyky Ruby, Scala, Smalltalk a nebo JavaScript. Co to bude pro Javu znamenat, jak vypadá syntaxe a jaký mají Closures ohlas — to všechno jsou otázky, na které se pokusíme odpovědět.
Java podporuje anonymní vntiřní třídy, všichni je známe a používáme. Ilustrační příkad pro připomenutí.
List persons = ...;
Collections.sort(persons, new Comparator() {
public int compare(Person a, Person b) {
return a.getAge() - b.getAge();
}
});
Metoda sort má dva argumenty, sortovaný list a komparátor, který implementuje vlastní porovnání. V tomto případě je komparátor implementován jako anonymní vnitřní třída.
Closures
Výše zmíněný dokument představuje koncept anonymní funkce též zvaný Closure. V našem příkladu tak bude možné anonymní vnitřní třídu komparátoru nahradit anonymní funkcí. V takovém případě může kód vypadat následovně.
List persons = ...;
Collections.sort(persons, int(Person a, Person b) { return a.getAge() - b.getAge()});
Kód int(Person a, Person b) {return a.getAge() - b.getAge();} je ona anonymní funkce (closure). V době kompilace se closure přeloží přesně na ten samý kód jako v případě použití anonymní vnitřní třídy. Zamýšlená syntaxe umožňuje využití odvození návratového typu.
Collections.sort(persons, int(Person a, Person b) : a.getAge() - b.getAge());
Collections.sort(persons, int(Person a, Person b) { a.getAge() - b.getAge()});
Syntaxe closure by měla umožnit použití zkrácené formy zápisu, v takovém případě je closure napasován jako druhý argument metody.
List persons = ...;
Collections.sort(persons) int(Person a, Person b) {
return a.getAge() - b.getAge();
}
Lokální funkce
Lokální funkce v signatuře definuje argumenty, návratový typ a případně výjimky v throws klauzuli.
int plus2(int x) { return x+2; }
Lokální funkce je zároveň referenčním typem. Následuje přiřazení do proměnné typu lokální funkce.
int(int) plus2b = plus2;
A jako takovou lze lokální funkcí zavolat.
System.out.println(plus2b(2));
Pohled na celek
public static void main(String[] args) {
int plus2(int x) { return x+2; }
int(int) plus2b = plus2;
System.out.println(plus2b(2));
}
Dopad na jazyk
Lokální funkce (closers jsou jejich anonymním vyjádřením) zavádějí do Javy nový rozměr. Pokud jsme doposud mohli vzít jako základní konstrukt objekt, zavedením lokálních funkcí musíme přibrat navíc funkci. Funkce na rozdíl od objektu nemá vnitřní stav a komunikační rozhraní je definováno vstupem a výstupem.
Můžeme tedy napsat metodu, která bude mít jako jeden z argumentů nikoliv objekt, ale funkci se kterou bude pracovat.
/**
* Obecná metoda pro hledání v seznamu osob, vlastní hledání je
* definováno na úrovni funkčního typu.
*
* @param concreteFinder funkce která implementuje hledání
* @return seznam osob
*/
public List find(boolean(Person) concreteFinder) {
List persons = ...//načtení dat např. z DB
List foundPersons = new ArrayList();
for(Person p: persons){
if(concreteFinder(p)){
foundPersons.add(p);
}
}
return foundPersons;
}
//lokální funkce, která vrací true v případě, že je osoba nezletilá
boolean(Person) teenFinder = (Person p) : p.getAge() < 19;
//použití
List teenagers = find(teenFinder);
Ohlasy
Zatím se zdá, že je část vývojářů, kteří si slastně mlaskají podstatně menší než ta, která se cítí zmateně. Pokud pominu ultrageeky, tak jsem získal pocit, že vývojářů, kteří si po něčem takovém stýskají je velice málo. Vesměs by se ten postoj dal pospat Opravdu to potřebuji?. Syntaktické veletoče (jinak se tohle nazvat nedá) mají tu nespornou nevýhodu, že boží zpětnou kompatibilitu a činí kód hůře čitelnějším. Samozřejmě musíme vzít jako bernou minci pokročilejší konstrukce (například subtyp funkce boolean(Person) teenFinder = (Female f) : f.getAge() < 19;, či přetypování) ne ilustrativní příklad komparátoru.
Budoucnost
Na přesné specifikaci closures a lokálních funkcí se stále pracuje, takže ne vše výše uvedené musí v budoucnu platit. Pokud budou closers začleněny do Javy mělo by to být ve verzi 7. Související odkazy s tímto tématem můžete najít pěkně pohromadě v článku Closures Syntax in Java 7.
Související články
Související epizody CZ Podcastu
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi a Filemon o novinkách v Javě 6 a webových frameworcích.
- #1 · Vývojová prostředí v Javě
První díl CZ Podcastu se věnuje vývojovým prostředím pro Javu.