W tym poście postaram się podsumować wybrane z najważniejszych cech Scali – ekspresyjnego i wydajnego języka działającego na wirtualnej maszynie Javy.

Scala to język statycznie typowany, który umożliwia płynną integrację programowania obiektowego z funkcyjnym. Jest bardzo szybka, zazwyczaj tak szybka, jak Java na JVM, w niektórych przypadkach wolniejsza, lecz nadal o rząd wielkości szybsza niż większość z pozostałych języków na wirtualnej maszynie Javy takich jak JRuby. Scala jest kompatybilna z Javą w tym sensie, że można wywoływać Javę ze Scali i odwrotnie. Ta druga możliwość jest w szczególności istotna, jako że zmniejsza ryzyko biznesowe związane z brakiem programistów znających Scalę – projekt X pisany w Scali może w dowolnym momencie powrócić do pisania kodu w Javie i po prostu wywoływać istniejący kod Scali z poziomu Javy.

Czy Scala nie jest czasem jedynie przejściową zajawką? Nie do końca. Ma ona już 10 lat, nieco więcej niż Groovy. Ale dopiero teraz nabiera rozpędu, a ja postaram się poniżej odpowiedzieć dlaczego.

Do Scali można podejść dwojako.

1) Scala jako „łata dla Javy”.

Dla wielu współczesnych firm ten punkt widzenia będzie najważniejszy. Java była fajnym językiem w latach dziewięćdziesiątych, ale teraz jest już przestarzała i wykazuje ogromne niedociągnięcia. Robi bardzo niewiele, żeby zachęcić programistę do programowania w dobrym stylu i rozkłada wiele pułapek dla kogokolwiek, kto chciałby w niej napisać np. dobry kod współbieżny (podobnie dla ‘final’ i niemutowalności, equals i hashCode, etc.). Java jest również bardzo rozwlekła przez co cierpi jej czytelność. Dodatkowo pozwala na koncepcje nieobiektowe (wartości prymitywne, statyczne), które czasami prowadzą do kiepsko zaprojektowanego kodu w tym języku.

W związku z tym branża IT oczekuje czegoś, co zastąpiłoby Javę. O Scali mówi się, że jest „jak Java, tylko lepsza”. Co to oznacza? Na pierwszy rzut oka Scala jest bardzo podobna do Javy i faktycznie wystarczy mechanicznie przekonwertować kod Javy do Scali i kod ten zadziała. Scala “zachęca” do programowania w dobrym stylu i wiele zadań upraszcza. Weźmy na przykład wzorzec Singleton. Jeżeli zadeklarujesz klasę jako ‘object’ zamiast jako ‘class’, Scala utworzy tylko jeden obiekt tej “klasy”. Od tego momentu jest odpowiedzialnością języka i JVM, aby nie powstał więcej niż jeden obiekt, niezależnie od wielowątkowego środowiska, w którym działa Twój program. Leniwa inicjalizacja jest również możliwa za pośrednictwem słowa kluczowego ‘lazy’.

Problem Javy związany z mutowalnością oraz słowem kluczowym ‘final’ (które ma jej zapobiegać) jest w Scali rozwiązany poprzez wartości ‘val’ oraz zmienne ‘var’. Za każdym razem każdą jednostkę programu trzeba zadeklarować jako jedno albo drugie co skłania do zastanowienia się „czy ta wartość zmieni się w trakcie wykonania programu?”. Okazuje się, że zwykły program nie potrzebuje wielu zmiennych, co jest dużym zaskoczeniem dla programistów Javy, którzy prawie zawsze używają zmiennych zamiast wartości. Dzieje się tak dlatego, że nikomu się nie chce pamiętać wszędzie o słowie ‘final’ – niniejszym poświadczam, że tak właśnie było na wszystkich komercyjnych projektach, w których brałem udział. Podczas jednego z nich zdecydowaliśmy się usunąć regułę sprawdzającą czy słowo final pojawia się we właściwych miejscach z naszej wtyczki sprawdzającej jakość kodu! Dodawanie final wszędzie kosztowało po prostu za dużo wysiłku. To oczywiście bardzo niedobrze, jako że niemutowalność to część dobrego stylu programowania, chroni programistę przed efektami ubocznymi, które są źródłem bugów. Jest również kluczowa w programowaniu współbieżnym. Praktyczną zasadą w Scali jest używać ‘val’ wszędzie tam, gdzie się da i tylko tam gdzie się nie da – używać ‘var’. Można również łatwo przeszukać swój kod w poszukiwaniu zmiennych (jest to niemożliwe w Javie – jak znaleźć instancję nieposiadania słowa ‘final’?!).

Współbieżność w Scali jest realizowana poprzez model z aktorami, który jest bezpieczny i łatwy do zakodowania (czego nie można powiedzieć o modelu współbieżnym Javy). Jest również wydajny – istnieją symulacje z milionami aktorów / wątków pracujących współbieżnie i wydajnie ze sobą. Model aktora jest łatwy do użycia z poziomu samej Scali, istnieje również akka.io – w pełni funkcjonalna biblioteka oparta na modelu z aktorami dla Javy oraz dla Scali (właściwie wspiera ona nie tylko aktorów – również STM i Futures).

Scala znacząco redukuje konieczność pisania kodu tzw. boilerplate. Nie ma tutaj setek getterów i setterów (tylko kilka tych, których naprawdę potrzebujesz). Jest za to znacznie więcej dla kogoś, kto chciałby się w Scalę zagłębić – zachęcam.

2) Scala jako coś więcej – elegancki, zwięzły, ekspresyjny, obiektowo-funkcyjny język przyszłości.

Scala ma do zaoferowania znacznie więcej, włączając w to programowania funkcyjne, które zyskuje sobie coraz większą aprobatę jako atrakcyjny paradygmat programowania, głównie ze względu na „czystość” (brak skutków ubocznych), jaka wiąże się z programowaniem funkcyjnym oraz zaletami, jakie ono oferuje programistom współbieżnym. Venkat Subramaniam opisuje współbieżność w Scali w swojej książce.

Poniżej niewyczerpująca lista tego, co Scala ma do zaoferowania:

1. Rozszerzone API dla podstawowych typów takich jak Integer, Double, etc.

2. Rozszerzone API dla kolekcji.

3. Inferencja typów.

4. Programowanie funkcyjne płynnie zintegrowane z obiektowym (domknięcia, funkcje jako obiekty itd.).

5. Dopasowanie do wzorca (ang. pattern matching).

6. Wielo-linijkowe ciągi (heredoc).

7. Krotki (ang. tuples).

8. Lepsze typy generyczne.

9. REPL – interaktywna konsola, przydatna do sprawdzania małych rzeczy, dla których musielibyśmy uruchomić metodę „public static void main(String[] args)” klasy publicznej zawartej w jej dedykowanym pliku w Javie.

10. Przeładowanie operatorów (które jest w rzeczywistości przeładowaniem funkcji, ponieważ + i – i inne są w rzeczywistości funkcjami w Scali).

11. Kompatybilność i wsparcie dla prawie wszystkich interesujących projektów takich jak MongoDB, akka.io, Play! framework, JavaFX 2.0 i innych.

12. Przejrzyste programowanie obiektowe z cechami (ang. traits) (łatwy sposób na dostarczenie uniwersalnej implementacji metod, które mogą być potem ponownie wykorzystane w dowolnych klasach, a nawet dowolnych obiektach).

13. Wsparcie dla języków dziedzinowych (ang. Domain Specific Languages – DSLs).

14. Wiele więcej.

Co więc zastosowanie Scali może oznaczać dla Twojego projektu? Wiele, a najważniejsze to – produktywność. Wszystkie te powyższe cechy Scali mają w sobie potencjał, aby uczynić programistę bardziej wydajnym przy pisaniu kodu, czytaniu czyjegoś kodu, refaktoryzacji kodu oraz naprawianiu bugów.

Krótkie porównanie z Groovym

Scala wydaje się więc obiecującym zastępnikiem dla Javy. Ale Scala nie jest jedynym nowym językiem na JVM. Spośród wielu wyłania się Groovy – oparty na Javie język skryptowy z imponującymi właściwościami podobnie jak Scala. Groovy jest również bardziej rozpowszechnionym obecnie językiem na rynku. Dlaczego więc należałoby wybrać Scalę ponad Grooviego? Odpowiedź na to pytanie mogłaby z pewnością być tematem serii wielu podobnych temu postów, ale postaram się szybko i zwięźle rozważyć kilka kategorii.

  • Kompatybilność z Javą.

Oba języki są kompatybilne z Javą, ponieważ działają one na JVM i zostały stworzone z myślą o JVM (w przeciwieństwie do JRuby na przykład). Tutaj znajduje się podsumowanie kompatybilności dla Grooviego, a tutaj dla Scali. Groovy jest bardziej kompatybilny z Javą, jako że jest on prawie że nadzbiorem Javy. To oznacza, że jeżeli wykonasz kopiuj-wklej kodu Javy do kodu Grooviego, to skompiluje się on i wykona poprawnie w 99% przypadków. Z drugiej jednak strony Scala daje Ci o tyle więcej niż Java, że wymaga ona istotnych przeróbek w tych miejscach. Zauważ jednak, że te kwestie pojawiają się tylko wtedy, gdy wywołujemy kod Scali z Javy – w przeciwnym kierunku problem prawie nigdy się nie pojawia. Niemniej Groovy wygrywa w tej kategorii rzutem na taśmę.

  • Typowanie.

Jest to największa różnica pomiędzy tymi dwoma językami. Wpływa ona na składnię i semantykę, projektowanie, testowanie i wydajność. Ludzie często popadają w skrajne opinie, gdy przychodzi do dyskusji „static vs. dynamic”. Nie zamierzam jej podejmować tutaj, zamiast tego zapytam “co jest lepsze dla firmy, w której dotychczas projekty realizowano w Javie?”. I wówczas odpowiedź brzmi „static”. Taka firma posiada wiedzę i doświadczenie w pracy z językiem statycznym, i projektowaniem oprogramowania inspirowanym statycznym programowaniem. Statyczne typowanie wydaje się być bardziej stosowne w dużych projektach, gdzie wielu programistów pracuje nad tym samym kodem. Statyczne również oznacza więcej możliwości optymalizacji na JVM i ogólnie. Również przy statycznym typowaniu potrzeba mniej testów, jako że chociażby nie trzeba testować typów (kompilator robi to za nas). Więc Scala zwycięża w tej kategorii.

  • Web development.

Oba języki mają w tej kategorii wiele do zaoferowania. Grails jest dobrze zadomowioną platformą dla Grooviego podobną do Ruby on Rails. Jest też mnóstwo innych dla tego języka. Z drugiej strony również Scala ma z czego wybierać. W szczególności Play! framework (innym wartym wspomnienia jest Vaadin, który oferuje wsparcie dla obu tych języków). Grails wydaje się być najbardziej dojrzałym frameworkiem, ale jest jeszcze jeden aspekt programowania webowego – współbieżność. Scala wydaje się trochę bardziej dojrzała w tym aspekcie poprzez jej model z aktorami – zarówno wbudowany, jak i poprzez akka.io. Remis.

  • Wydajność.

Bezpośrednio ze względu na statyczne typowanie, wydajność Scali jest niezrównana przez żaden inny nowoczesny język na JVM. Można bezpiecznie założyć, że Scala jest tak szybka jak Java lub odrobinę wolniejsza, ale zawsze o wiele szybsza niż Groovy, czy cokolwiek innego. Zerknij tutaj, tutaj, tutaj i tutaj. Scala wygrywa bezkonkurencyjnie.

  • Konsensus w branży.

Mimo że oba języki pojawiły się w mniej więcej tym samym czasie (2003), mają inne rozpoznanie na rynku. Groovy wydaje się być bardziej popularny w tym momencie. Dlaczego? Wydaje mi się, że dzieje się tak, ponieważ Groovy jest bezpieczniejszym wyborem. Jest o wiele bardziej podobny do Javy – przeszkolenie programisty Javy tak, żeby mógł używać Grooviego jest o wiele łatwiejsze, mniejsze jest również ryzyko braku programistów Grooviego, którzy mieliby utrzymywać kod – programiści Javy są zazwyczaj w stanie wykonać to zadanie bez przeszkolenia. Wydaje mi się, że rynek potrzebuje więcej czasu, żeby przyjąć taki język jak Scala. Ale Scala już złapała rozpęd wraz z istotnym zaadoptowaniem programowania funkcyjnego i potrzeby lepszej współbieżności. Niemniej tutaj punkt uzyskuje Groovy.

A więc kto jest zwycięzcą?

Wygląda na to że mamy remis, więc jak go wybiorę :P. Jak z pewnością zgadliście, dla mnie jest nim Scala. Wybaczcie wszyscy miłośnicy Grooviego, ale jakkolwiek Groovy się nowoczesnym językiem nr 1 na JVM obecnie, to Scala jest przyszłością i stanie się one teraźniejszością niebawem. Nie tylko zremisowała z Groovym w powyższym porównaniu, ale też była zdecydowanym zwycięzcą w dwóch kategoriach, podczas gdy Groovy zwyciężył znacznie mniej zdecydowanie w pozostałych dwóch. Polecam również posta twórcy Grooviego James Strachana „Scala as the long term replacement for java/javac”, gdzie przyznaje on, że prawdopodobnie nie stworzyłby Grooviego, gdyby znał Scalę.

Dla wszystkich tych z Was, którzy dotarli tak daleko i nie mogą się doczekać, żeby zagłębić się w Scali, poniżej zamieszczam listę zasobów związanych z tym językiem posortowaną według ich długości:

1) Tutorial o Scali.

2) Nagrany wykład o Scali dany przez jej twórcę – Martina Oderskiego.

3) Jeszcze jeden wykład dany przez „wesołego Hindusa”.

4) Seria blogów „Java to Scala with the Help of Experts” (wśród nich „Scala for Java Refugees”, który poleca sam Martin Odersky).

5) Książka „Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine” napisana przez Venkata Subramaniama.

6) Książka „Scala for the Impatient” od Typesafe (firma sprawująca patronat nad Scalą).

7) Książka „Programming Scala” wydawnictwa O’Reilly.

Nr 5 jest najlepsza, jeżeli masz do niej dostęp (wszystkie pozostałe są za darmo, poza nr. 6, który jest prawie za darmo). Sprawdź również oficjalne podsumowanie zasobów o Scali.

Have fun!