wtorek, 9 marca 2010

Wyginanie Javy



Dzisiejsza prezentacja Wojtka Gomoła o wyrażeniach Lambda (C# i "emulacja" w Javie) na Lubelskim JUG przypomniała mi o kilku ciekawych zabawkach, które jakiś czas temu znalazłem i zapomniałem o nich napisać.

Ciekawą cechą dynamicznych języków funkcyjnych jest:
- możliwość tworzenia konstrukcji zbliżonych do języka naturalnego
- możliwość rozszerzania standardowych, często używanych klas (zwykle kolekcji, kontenerów) o wygodne metody
- nazwijmy to w sumie roboczo "techniczny DSL"

Przykładowo takie oto sprawiające radość uproszczenia:

kolekcja.wyrzucZNullemWPolu("name").posortuj({e1.age >e2.age}).wytnijPierwszych(10);


Jak dla mnie nie ma się czym ekscytować ponieważ jest to jedynie lukier składniowy i w statycznych językach z silną kontrolą typów jest to tylko kwestia stworzenia jakiegoś starego, dobrego, proceduralnego Utilsa z interfejsem strategii komparacji:

MyAlmightyUtils28.wyrzucZNullemWPolu(kolekcja, "name")

oraz odpowiednia sekwencja wywołań.

/*Oczywiście wszyscy wiemy, że Utilsy są złe i brzydkie, ale co zrobić*/

No ale już nie będzie tak pięknie jak we wcześniejszym przykładzie z jakiegoś sexi-skryptowego-języka.


Na szczęście istnieje kilka ciekawych zabawek zaimplementowanych w Javie. Dzięki cwanym trikom na generykach i zastosowaniu odpowiedniego nazewnictwa dają nam coś więcej niż namiastkę konstrukcji znanych z dynamicznych, słabo otypowanych języków.

op4j - genialna biblioteka, która sprawia, że żmudny kod staje się bardziej czytelny i zwięzły jednocześnie zachowując typowanie.
Bardzo podstawowy przykład:

String[] emailArray = Op.on(userEmails).toArrayOf(Types.STRING).forEach().exec(FnString.toLowerCase()).get();


lambdaj - podobna zabawka ze stajni google. Można rzucić okiem również na google collections.

Mockito - nasza rodzima produkcja. Kto jeszcze nie używał, ten powinien spróbować. Warto zajrzeć choćby do kodu ponieważ stanowi on przykład wzorcowej dokumentacji. Cały manual wraz z przykładami znajduje się w JavaDocu głównej "klaski"! Wzór do naśladowania dla innych twórców bibliotek - bo na pewno nie dla developerów komercyjnych produktów;)

//==================

Czekamy na Javę 1.7 z jej nową konstrukcję closures. Ale forma w jakiej pojawi się ona w nowym wydaniu języka będzie praktycznie niczym innym niż uproszczonym wydaniem anonimowej klasy wewnętrznej. Czyżby ukłon w stronę tych hakerów, którzy nie mogą połapać się w konstrukcji anonimowych klas albo Wzorca Strategii?

No i na pewno na certyfikatach pojawią się kolejne arcyistotne pytania mające na celu sprawdzenie czy delikwent jest w stanie odróżnić: domknięcie od klasy wewnętrznej i od niekompilującego się kodu;P

5 komentarzy:

BorryS pisze...

Obawiam się, że Java7 nie będzie miała jeszcze domknięć. Swoje obawy opieram na informacji o nowych "ficzerach" z tego bloga
Chyba, że masz jakieś bardziej aktualne i konkretne informacje na ten temat.

Co do sposobu, w jaki ostatecznie mają być wprowadzone domknięcia, to faktycznie będą to głównie klasy anonimowe, ale z dużo prostszym zapisem (programy skompilowane prototypowym komilatorem można uruchamiać na starej maszynie wirtualnej).
Z trzech propozycji domknięć wybrano najbardziej rozbudowaną. Wg mnie jest to trochę nietrafiony wybór. Domknięcia miały służyć przede wszystkim uproszczeniu zapisu. Natomiast BGGA wprowadza możliwość tworzenia własnych struktur kontrolnych, co daje jeszcze większe możliwości zaciemnienia kodu.
Moim zdaniem dużo bezpieczniejszy (a jednocześnie bardzo elastyczny) byłby wybór FCM a nawet minimalistyczne CICE

Sławek Sobótka pisze...

@BorryS: racja, nie sprawdzałem tego ostatnio, ale tak jak piszesz - wycofali się z domknięć w 7. Mój błąd.

Heh niektórzy boleją w swoich artykułach, że Java bez nich jest martwa. Ja jednak nie widzę nowej wartości, która wpłynęłaby na model programistyczny. Po prostu lukier.

I tak jak piszesz - zaciemnienie. Poza tym z tego na ile znam mentalność programistów, to część z nich zostanie "sprowokowana" do programowanie metodą Kopiego-Pasty bo nie będą wiedzieli jak sobie te domknięcia wyciągnąć we wspólne miejsca aby ich reużywać;)

iirekm pisze...

Najciekawszą cechą języków funkcyjnych jest nie tyle możliwość tworzenia DSL - to i w Javie jakośtam utworzę za pomocą techniki "fluent interface". Największa zaleta języków funkcyjnych to brak "side effects" - wszystkie obiekty są immutable. Dzięki temu jest mniejsza szansa na stworzenie efektu spaghetti w kodzie (ktoś po coś ustawił pole X, które coś rozwaliło w innym miejscu programu). Do tego programy funkcyjne dają się bardzo łatwo zrównoleglać, czego nie można powiedzieć o zwykłych imperatywnych.
Jak na mnie fajnie byłoby mieć rozszerzenia funkcyjne w Javie (np. closures, metody jako obiekty, itp), ale nie ma co rozpaczać, to już jest w języku Scala.

Sławek Sobótka pisze...

Z tym immutable to mam mieszane odczucia.
Od strony technicznej - owszem, niezaprzeczalne jest o niebo łatwiejsze skalowanie wynikające z braku współdzielenia stanu.
Ale od strony koncepcyjnej... kurcze ja lubię sobie obmyślać stanowe byty, które niejako w trakcie trwania całej sztuki zmieniają się.
Wszystko zależy oczywiście od konkretnego problemu i uważałbym aby nie wylać dziecka z kąpielą.

piotrga pisze...

Swego czasu napisalem taka mala biblioteke:
http://code.google.com/p/closures/
ktora umie robic np. to:
import static closures.Closures.*;
...
List list = asList(new User("Adam"), new User("Ola"), new User("Alex"));
each(collect(list, "'Hello '+it.name"),"print it")