This blog is no longer being maintained, please go to The missing link of Agile instead

Thursday, June 26, 2008

Scala bez kontraktów...

Pisząc w Scali mam wrażenie, że ciężko byłoby mi w tym języku znaleźć konstrukcji czy rozwiązań, które mi znacząco przeszkadzają - nawet jeśli sam język przeraża po pierwszym czytaniu specyfikacji. W pewnym stopniu zgadzam się z poniższą opinią Steva Yegge:
"The... the the the... the language spec... oh, my god. I've gotta blog about this. It's, like, ninety percent [about the type system]. It's the biggest type system you've ever seen in your life, by 5x. Not by an order of magnitude, but man! There are type types, and type type types; there's complexity..."

Jestem jednak chyba większym od niego optymistą i uważam, że o ile można uznać Scalę za "onieśmielającą" to spójność języka pozwala na sukcesywne jego opanowywanie. Nie sądzę też, że programy stworzone za jego pomocą będą magiczne i niezrozumiałe.. Przede wszystkim uwzględnić trzeba w tym równaniu ekspresywność języka, która pozwoli zmniejszyć LOC tworzonych rozwiązań conajmniej dwukrotnie ("The Scala Experiment", system obsługi konferencji).

Mogę jednak z całą pewnością stwierdzić, że jest element, który został przy implementacji języka pominięty - a ja jestem bardzo niemile zaskoczony, że Odersky nie zdecydował się na jego zawarcie. Mowa o znanym z Eiffel'a i lubianym DBC (Design by Contract).

Brak zainteresowania DBC przez twórców języków dziwi mnie niesamowicie od czasu przeczytania "Object Oriented Software Construction" 2nd edition, Bertranda Meyera. Pamiętam, że rozdział o powyższym mechanizmie czytałem niemalże z wypiekami na twarzy.. Na początku, kiedy uczyłem się programowania obiektowego - interfejsów, klas abstrakcyjnych, kontrakt oparty o te konstrukcje wydawał mi się nadzwyczaj abstrakcyjny. Meyer pokazał, że moje obawy były jak najbardziej uzasadnione - bo przecież ile wart jest kontrakt bez opisu semantyki?! (Tyle ile waży ;])

Po latach pomysł wprowadzenia DBC pojawił się w Javie - okrojony i brzydszy - jako JSR 305 Annotations for Software Defect Detection. Mogę ostatecznie zaakceptować, że Java kontynuując strategię wstecznej zgodności przyjęła takie rozwiązanie. Nie potrafię jednak zrozumieć dlaczego DBC nie jest wbudowanym mechanizmem językowym w Scali. Scala już jest językiem przepełnionym konstrukcjami - ale co ważne spójnym! I tak długo jak spójność będzie zachowana warto dodać przełomowe według mnie rozwiązanie, jakim jest DBC. Niech stoją za mną słowa Meyera:
"This comment is relevant because Ada, although undoubtedly a “big language”, differs from others in that category by clearly showing (even to its critics) that it was designed and has little gratuitous featurism. As with other serious languages, the whole design is driven by a few powerful ideas, and every feature has a rational justification. You may disagree with some of these ideas, contest some of the justifications, and dislike some of the features, but it would be unfair to deny the consistency of the edifice. Consistency is indeed the key here: size, however defined, is a measure, but consistency is the goal."

Należy wspomnieć, że istnieje biblioteka umożliwiająca DBC dla Scali. Jest to jednak według mnie absolutnie niewystarczające (1). Przede wszystkim DBC powinno być wreszcie porządnie rozreklamowane.. choćby na przykładzie Ruby'ego widać, że bez dobrego marketingu (jakim dla niego był Ruby on Rails) nawet bardzo dobra technologia nie ma dużych na szans na popularyzację. Druga rzecz, że DBC można zbudować nawet na asercjach... to co jednak zaoferował w Eiffel'u Meyer - czyli silne wyabstrahowanie koncepcji poprzez wyróżnienie warunków pre i post oraz inwariantów, łącznie z ich dziedziczeniem (!!) jest ważnym krokiem w zapewnianiu jakości przy użyciu kontraktów.

DBC ma swoje wady i zalety (co nie ma ...) jednak czas wreszcie zauważyć, że w kolejce na listę popularnych konstrukcji językowych stoi już długo i jak najbardziej zasługuje żeby się tam dostać.

P.S. Tak sobie jeszcze pomyślałem - czy BDD nie ma więcej wspólnego z DBC niż by się nam zdawało....

Thursday, June 12, 2008

XML considered harmful

Albo udziela mi się nastrój sesji, albo po prostu od czasu do czasu muszę na coś ponarzekać.. mam jednak nadzieję, że do powstania poniższego 'ranta' przyczynił się raczej 'przewlekłe uprzedzenie' do formatu XML.

Kilka dni temu napisałem w Scali małą aplikację do generowania danych testowych i wypełniania nimi bazy danych. Wybór Scali także jako formatu specyfikacji danych bynajmniej nie był spowodowany niechęcią do XML'a. Powodem mojej decyzji był najzwyklejszy w świecie pragmatyzm. Potrzebowałem języka ekspresywnego, zwięzłego i elastycznego (1) - piwo dla osoby, która udowodni obecność w XML'u choćby jednej z wymienionych cech. Najwyraźniej mówi się o tym zbyt rzadko, bo tęże technologię wybrał autor rozwiązania na którym w dużej mierze się oparłem (2). Podczas gdy specyfikacja w Scali:

  • zajmuje 2x mniej linii kodu (3)

  • jest o niebo czytelniejsza

  • udostępnia dodatkową funkcjonalność (niemożliwe do zapisu w XML !)


Wydaje się, że jedynym powodem dla którego wybieramy XML'a w każdym-kolejnym-projekcie jest jego popularność. Tej "zalety" z całą pewnością nie można mu zarzucić: Ant, Maven, Spring, Web-Service'y itd., etc... lista z pewnością zajęłaby więcej niż drugie wydanie "Object-oriented software construction" Meyer'a. Nie zdziwił bym się nawet gdyby od jutra tabelki wartości odżywczych na opakowaniach zaczętoby zapisywać w XML'u...

Z czasem okazuje się, że zrozumienie builda ant'owego dla większego projektu graniczy z cudem (jego maintenance wymaga wielkiego męstwa i odwagi), a edycja xml'i spring'owych bez plugin'a zasługuje na medal. Żeby XML wciąż spełniał nasze oczekiwania zaczyna się go wypełniać dodatkowymi elementami - np. OpenLaszlo i JavaScript - po czym okazuje się, że stosowany przez nas format danych to Java z duża ilością operatorów relacyjnych i jeszcze bardziej rozwlekłą składnią (a jednak się da !).

To zabrzmi jak truizm, ale: XML nie jest najlepszym rozwiązaniem dla wszystkich problemów.. powiem więcej, sądzę, że w 80% przypadków (liczba dobrana celowo) mógłby być z ogromną korzyścią dla projektów zastąpiony inną technologią. Pomyśleć tylko o projektach na użytek własny, specyfikacjach (do generacji kodu, translacji), projektach wymagających dużej ekspresywności (Ant vs Gant !!).

Życzę wszystkim programistom, by przy wyborze technologii towarzyszyło Wam hasło: "Wszędzie gdzie można wykorzystać XML'a, użyć można n+1 technologii bardziej wydajnych/wygodnych/seksownych (niepotrzebne skreślić)."

1. Przyjmuję, że w ocenie elastyczności uwzględnia się także proces parsowania języka.
2. Porównanie wyłącznie w celach dramatycznych - nie ma na celu krytyki autora aplikacji.
3. Zastosowałem standardowe wcięcia - priotytem dla obu formatów była czytelność.

Thursday, June 05, 2008

Scala Frenzy

W nocy z wtorku na środę miałem plan, aby wreszcie podgonić zaległości z projektu (Projektowanie Systemów Informatycznych). Niestety.. o 18 'na chwilkę' włączyłem projekt w Scali i na tym skończyły się moje ambitne plany :). W rezultacie tejże nocy powstała mała biblioteka do wypełniania danymi testowymi bazy danych, z której stworzeniem nosiłem się od pewnego czasu.

Jest to mój pierwszy projekt w Scali i muszę powiedzieć, że tkwi w tym języku niewiarygodny potencjał. Całość powstała bez ani jednej linijki kodu testowego - co samo w sobie nie jest powodem do dumy :P - ale dzięki temu udało mi się docenić łatwość z jaką można tworzyć w Scali bezbłędny (!) wysokiej jakości kod. Jest coś w tym języku (mój wykładowca dr Spławski twierdził, że to cecha funkcyjnych językow w ogóle), że jeśli już uda się program skompilować to z dużym prawdopodobieństwem będzie on działał poprawnie. Co jak co, ale trudno mi taką opinię wyrazić o Javie ;)

Poniżej zamieszczam bodaj najciekawszy fragment biblioteki, pokazujący piękno Scali.

def newTuple = { table.columns.transform { (k, v) => v.generateValue } }
var tuple = newTuple;

while (
constraintFunctions.
map ( f => f(list, tuple) ).
reduceLeft ( _ || _ ))
{ tuple = newTuple; }

Celem powyższego jest generowanie krotek tak długo, aż wszystkie podane przez użytkownika funkcje sprawdzające czy naruszono ograniczenie zwrócą 'fałsz'. Może być w tym jakieś szaleństwo (czy narcyzm ;] ), ale nie mogę się napatrzeć na powyższy fragment kodu, który niemalże zabija prostotą.

Po całej nocy kodowania udało mi się stworzyć stosunkowo spójną całość. Przerzuciłem istniejący kod generujący dane testowe z wyżej wspomnianego projektu do własnego rozwiązania, dodając kilka funkcjonalności których nie mogłem uzyskać we wcześniej używanym narzędziu. Efekt okazał się na tyle zadowolający, że postanowiłem udostępnić narzędzie jako Open Source i dalej rozbudowywać jego możliwości :)

Projekt jest dostępny na SourceForge:
http://sourceforge.net/projects/dage/.