Czy i dlaczego warto nauczyć się Scali?

Nauka Scali? To najlepsze co możesz zrobić ze swoim czasem.

“Bóg stworzył Arrakis, aby ćwiczyć wiernych. 
Tym którzy wytrwali, podarował Scalę.”

- Luźny Interpretator -

Bardzo często trafia do mnie pytanie "Czy i dlaczego warto nauczyć się Scali?", "Czy nauka Scali przyda mi się w mojej karierze programisty?"

Nie potrafię odpowiedzieć na tak postawione pytanie.

Mogę za to napisać, dlaczego postanowiłem nauczyć się Scali i dlaczego uważam, że warto poznać ten język programowania (do czego będę Cię gorąco zachęcał).

Moja droga do Scali była długa i kręta (jak i moja już prawie 30-letnia kariera programisty). Przygotowałem drzewko obrazujące, jak to w pewnym przybliżeniu wyglądało.

Obecnie używam wielu różnych języków, ale to Scala jest moim językiem z wyboru i dającym mi najwięcej przyjemności i satysfakcji z kodowania.

No dobrze, ale co mi w takim razie przeszkadzało w innych językach?

(Pamiętaj tylko proszę, że poznałem się ze Scalą trochę ponad 8 lat temu, więc należy na to wszystko obrać pewną perspektywę).

More...

1

Delphi

Od wielu lat (obecnie już grubo ponad 20), tworzę projekty, a w zasadzie tak naprawdę jeden duży projekt w Delphi. Do tego z racji konieczności zachowania kompatybilności z nierozwijanym od lat Kylixem 3, muszę to robić w Delphi 7.


Napisać, że "nie sprawia mi to przyjemności" to eufemizm. Wiem, że nowe wersje Delphi są lata świetlne do przodu, ale to wciąż Object Pascal, który po prostu jest nudny (w każdym razie na pewno dla mnie). Na szczęście, tworzymy w końcu nową wersję już w całości w Scali.

2

Python

Sporo projektów tworzonych "obok" mnie, powstaje w Pythonie. Uważam, że to świetny język programowania, zwłaszcza do nauki, ale mnie odtrąca dynamiczne typowanie i brak kontroli na poziomie kompilacji.


Nigdy nie potrafiłem się przemóc i napisać w Pythonie czegoś, co miało więcej niż kilka tysięcy linii kodu. To oczywiście wyłącznie moje ograniczenie, bo wiem, że jak najbardziej jest to możliwe.


Koledzy w firmie udowadniają to na co dzień, zarządzając bardzo dużymi projektami tworzonymi w całości w Pythonie.

3

C#

Bardzo długo zastanawiałem się, czy C# nie stanie się moim językiem "z wyboru" kto wie, czy tak by się ostatecznie nie stało, gdyby nie ówczesna filozofia Microsoftu. 8-9 lat temu, krążyło wiele plotek i niepotwierdzonych informacji o możliwości zabicia projektu Mono (maszyny .NET pod Linuksa).


Ponieważ oprogramowanie, które tworzę MUSI działać pod Linuksem widmo gilotyny z logo M$ dyndającej nad moimi projektami, spowodowało, że nie poszedłem tą drogą.


W ostatecznym rozrachunku cieszę się, że tak się stało. Bawiąc się w Unity (środowisko do tworzenia gier), właśnie przy pomocy C#, mam masę frajdy, ale cały czas żałuję, że to nie Scala.

4

Java

Mamy też jeszcze Javę. Co mogę napisać. Nigdy, przenigdy nie przekonałem się do tego języka.


Ilość nadmiarowego kodu, który trzeba generować żeby wykonać proste operacje, zawsze mnie odtrącała. Zresztą podobnie jak te wszystkie "ciężkie" zwierzątka, biegnące za Javą w równym szeregu jak Tomacat czy Hibernate. 


Oczywiście, że przez te lata Java mocno poszła do przodu, ale jej podstawowa bolączka - stosunek ilości kodu do działającego programu - jest dla mnie niezmiennie nieakceptowalna.


No dobrze, a co z Ruby, PHP, JavaScript? Pozwól, że pozostanę na razie przy językach, które umożliwiają tworzenie wydajnego backendu, a frontendem zajmę się później, wymieniając zalety Scali.

Eureka

Znasz już zatem mój stan umysłu, gdy trochę ponad 8 lat temu dostałem po oczach magicznym kawałkiem kodu. Trafiłem na niego zupełnie przypadkiem.


Nie miałem nigdy wcześniej styczności z językiem funkcyjnym, więc nie do końca rozumiałem, jak działa, ale sama struktura i elegancja kodu zachwyciła mnie. W taki sposób rozpoczęła się moja nauka Scali (i jednocześnie fascynacja tym językiem).

Akka

Może na fascynacji by się skończyło, gdybym kilka miesięcy później nie trafił na kolejną Scalową perełkę.


Nawet w dzisiejszych czasach, wielu programistów utożsamia tworzenie oprogramowania wielowątkowego z semaforami, sekcjami krytycznymi, synchronizacją i wieloma innymi mechanizmami, które umożliwiają nam tworzenie kodu działającego równolegle.


Zgodzisz się ze mną zapewne, że można tak kodować, ale gdzie w tym przyjemność? Gdzie elegancja, finezja? Tylko ciągłe zastanawianie się, czy na pewno wszystko, co trzeba, jest objęte semaforem. Dlaczego ten kod nie działa i zapętla się? Dlaczego semafory mi się zakleszczają !@#$%$%^&... 


Aplikacje wielowątkowe to mój chleb powszedni. Nie lubię tworzyć aplikacji z interfejsem graficznym, nie potrafię tego dobrze robić, za to backend to mój konik 🙂 Niestety narzędzia do tego były po prostu toporne.


Właśnie wtedy, w czasie moich nieudolnych początków ze Scalą, trafiłem na bibliotekę, o egzotycznej nazwie Akka.


Wielowątkowość bez semaforów? Brzmiało jak bajka. I podobnie jak bajki miało dobre zakończenie. Praca z aktorami wymagała (i nadal wymaga) przestawienia sposobu myślenia o tworzeniu kodu.


Pisanie programu z nastawieniem na brak blokowania stanowi czasami nie lada wyzwanie, ale praktyka czyni mistrza, a efekty są genialne.

Okazja

W kilka miesięcy później trafiła mi się okazja przetestowania działania Scali i Akki na żywym projekcie (trochę więcej na ten temat, możesz znaleźć tutaj).


Miałem stworzyć narzędzie, które na średniej jakości sprzęcie, miało pobierać w czasie rzeczywistym dane z kilku tysięcy polskich bibliotek (informacje o zmianach rekordów bibliograficznych, oraz onlinowe informacje o zmianach dostępności egzemplarzy - wypożyczenia, zwroty, rezerwacje itp). 


Bardzo się cieszę, że nie musiałem tego robić metodą "tradycyjną", nie wiem, czy bym podołał. Natomiast Scala i Akka spisały się REWELACYJNIE.


AppServer (wewnętrzna nazwa tego niewidocznego dla świata narzędzia) działa już od dobrych 8 lat, działa i nieustannie zarządza informacjami o ponad 24 milionach książek w ponad 36 milionach egzemplarzy. Zmiany dostępności są widoczne natychmiast, nie ma opóźnień, nie ma padów (wszystko to pracuje na przeciętnej mocy serwerze i nie jest jedyną aplikacją na tej maszynie).


No dobra. Ściana tekstu, ale co tak naprawdę mnie w Scali zauroczyło?

1.

Statyczne typowanie działające jak dynamiczne

// można tak
val x: Int = 12

// można też tak
val x = 12

// można tak
def test(x: Int): Int = x

// albo tak (aczkolwiek, tej metody nie polecam)
def test(x: Int) = x

Jak widzisz, da się (do pewnego stopnia) używać składni języka typowanego dynamicznie (np. Python), nie tracąc jednocześnie kontroli poprawności kodu na etapie kompilacji.


Już tylko ten element powoduje, że nie mam ochoty kodować w niczym innym 🙂

2.

Skondensowana składnia

Głównie za sprawą możliwości użycia elementów funkcyjnych języka.


Przykład Scalowego fora na sterydach

val l = for {
  a <- listF
  if a % 2 == 0
  if a > 4
} yield a

I to samo funkcyjnie

// Przypisujemy funkcję do stałej
val myTest: Int => Boolean = (i: Int) => {
  i % 2 == 0 && i > 4 
}

// Teraz odpowiednik naszego fora
listF.filter(myTest)
3.

SCALowalność podczas nauki

Mogłem od początku tworzyć kod obiektowy, bazując na mojej wiedzy. Wcale nie musiałem używać elementów funkcyjnych.


Chciałem to oczywiście robić, ale mogłem w ten nowy dla mnie świat wchodzić stopniowo.


To nie tak, że Scala rzuci Cię od razu w paszczę funkcyjnego aligatora i będzie się zastanawiała, czy przetrwasz.


Nauka Scali, tempo tej nauki zależy wyłącznie od Ciebie, Twoich predyspozycji i chęci.

4.

Hybrydowość

Wspomniałem już wcześniej kilka razy o tym elemencie (między innymi w punkcie poprzednim).


To również jedna z podstawowych zalet Scali. Możliwość tworzenia kodu obiektowego i korzystanie przy okazji z możliwości funkcyjnych daje olbrzymią przewagę nad innymi językami programowania.

5.

Akka

Nie mogło zabraknąć tego elementu.


Tak, wiem, że jest również wersja Akki działająca z Javą. Mam jednak do Ciebie prośbę. Wejdź na stronę dokumentacji Akki. Poszukaj jakiś przykładowych kawałków kodu i przełącz się kilka razy pomiędzy wersją w Scali i w Javie. Jeśli to Cię nie przekona, to już nic Cię nie przekona 🙂


Np. prosty przykład użycia become.


Java:

static class HotSwapActor extends AbstractActor {
  private AbstractActor.Receive angry;
  private AbstractActor.Receive happy;

  public HotSwapActor() {
    angry =
        receiveBuilder()
            .matchEquals(
                "foo",
                s -> {
                  getSender().tell("I am already angry?", getSelf());
                })
            .matchEquals(
                "bar",
                s -> {
                  getContext().become(happy);
                })
            .build();

    happy =
        receiveBuilder()
            .matchEquals(
                "bar",
                s -> {
                  getSender().tell("I am already happy :-)", getSelf());
                })
            .matchEquals(
                "foo",
                s -> {
                  getContext().become(angry);
                })
            .build();
  }

  @Override
  public Receive createReceive() {
    return receiveBuilder()
        .matchEquals("foo", s -> getContext().become(angry))
        .matchEquals("bar", s -> getContext().become(happy))
        .build();
  }
}

I to samo w Scali

class HotSwapActor extends Actor {
  import context._
  def angry: Receive = {
    case "foo" => sender() ! "I am already angry?"
    case "bar" => become(happy)
  }

  def happy: Receive = {
    case "bar" => sender() ! "I am already happy :-)"
    case "foo" => become(angry)
  }

  def receive = {
    case "foo" => become(angry)
    case "bar" => become(happy)
  }
}
6.

Ruby, PHP, Java Script

Obiecałem, że wrócę do tego tematu i o to jestem. Nie przepadam, za żadnym z tych języków, z konieczności przez kilka lat tworzyłem kod w tandemie PHP + JS. Na szczęście teraz już nie muszę.


Dlaczego?


Dlatego, ponieważ ktoś genialny stworzył scala.js. Masz ochotę na użycie reacta? Nic nie stoi na przeszkodzie.

+1000 do zajebistości

Przepraszam, na sam koniec nie potrafiłem się powstrzymać.

Problem z tworzeniem CV mam już dawno za sobą. Od lat prowadzę działalność gospodarczą. Gwarantuje Ci jednak, że dopisanie do CV "znajomość Scali na poziomie zaawansowanym", dodaje Ci wspomniane 1000 punktów do zajebistości.

Dlaczego? Scala uchodzi za język bardzo trudny i skomplikowany. A nauka Scali za czynność niemal abstrakcyjną. Co to zatem mówi o Tobie? Że masz pasję, że masz zamiłowanie, interesują Cię wyzwania, Twoja inteligencja jest powyżej przeciętnej, masz cierpliwość, charakter i chęci. To wszystko to cechy, które bardziej interesują obecnych pracodawców od faktycznych umiejętności technicznych (bo tych się można nauczyć).

Słowo klucz w tej całej wypowiedzi to "uchodzi".

Czy Scala jest trudna do nauczenia się? Nie. Czy jest trudna do osiągnięcia mistrzostwa? Tak. Czy mistrzostwo jest konieczne do sprawnego i sprawiającego przyjemność kodowania? Nie.

Czy Scala ma jakieś wady? 

Pewnie, że ma 🙂

  1. Uzyskanie mistrzostwa w typach danych może być prawdziwym wyzwaniem.
  2. Możliwość użycia implicit czasem jest błogosławieństwem, a czasem doprowadza do szału 🙂
  3. Czas kompilacji kodu.
  4. Brak kompatybilności modułów binarnych po dużych zmianach kompilatora.

Zapewne znalazłoby się jeszcze kilka, ale te najbardziej dają mi się we znaki.

Bardzo dziękuję, jeśli udało Ci się dotrzeć do samego końca.

Mam nadzieję, że nie będzie to nasze ostatnie spotkanie 🙂

Chcesz Nauczyć Się Scali?

Jestem tutaj, by Ci pomóc.