O nápadu prosadit closures (uzávěrách?) do Javy jsem se dočetl poměrně nedávno. Odkaz na původní článek najdete zde. Mojí první reakcí bylo: „Proboha proč?!“. Čím více o tomto návrhu přemýšlím, tím více motivaci jeho tvůrce chápu. Stále si s nimi ale dovoluji nesouhlasit. Pokusím se uvést několik argumentů proti jejich akceptaci.
- Většina programátorů je nepotřebuje. Přiznejte si, jak často si při práci říkáte „tady by to chtělo closure“. Já pracuji s Javou denně a na mysl my to přišlo jedině u listenerů ve Swingu (bohužel jen u některých). Porovnáme-li closures s rozšířeními v Javě 5 jako jsou generics nebo autoboxing, vidíme právě v tomto aspektu veliký rozdíl. Po tom, abych mohl mapě říci co má obsahovat, vzdychám skoro denně a neustále psaní new Integer(3) mi občas leze na nervy a znepřehledňuje kód.
- Java ztrácí svojí objektovost. Připadá mi, že closures jsou stejným problémem jako primitivní typ. Je to takový degenerovaný objekt. Zatímco na primitivní typ se můžeme zjednodušeně dívat jako na objekt bez metod, closure je metoda bez dat. Z čistě objektového hlediska je to paskvil. K primitivním typům přistoupili tvůrci Javy z důvodu efektivity výsledné aplikace, nejsem si jist, že máme stejně silnou motivaci v případě closures.
- Přicházíme o znovupoužitelnost kódu. Kód
int(int) plus2b = (int x) {return x+2; };
nemám šanci použít kdekoliv jinde. Ano, to samé platí i pro anonymní třídy. Ale tím, že do deklarace své metody dám jako jeden z parametrů closure, nutím klienta mého API používat kód, který není znovupoužitelný! - Kód se může i znepřehlednit. Možná je to tím, že nejsem zvyklý tento zápis číst, ale například toto:
void(int) throws InterruptedException closure = (int t){ Thread.sleep(t); }
ve mně vyvolává smíšené pocity. - Do jazyka se zavlékají kontroverzní konstrukce. Zde nemám na mysli closures samotné. V návrhu se například objevuje i nová syntaxe klíčového slova return pro návrat z metody, která closure používá! (kapitola Non-local transfer). Mělo by dokonce jít i napsat něco takového:
int(int) brrr = (int x) {if (x==13) break; };
Zde doufáme, že je naše funkce volána z cyklu, který můžeme přerušit. (Konkrétně u této kapitoly doufám, že jsem ji nepochopil a že to je všechno jinak. Budu rád, když mě někdo z mého omylu vyvede)
Na druhou stranu je dobře, že autoři tuto diskuzi vyvolali. Je na komunitě, aby si rozhodla, jestli chce mít z Javy další Ruby nebo Perl, nebo jestli chce mít jazyk, který se programátora snaží nutit psát čistě, přehledně a objektově.