Advent of Code (https://adventofcode.com) to ciekawa inicjatywa kalendarza adwentowego skierowanego do programistów. Podobnie jak w innych tego typu kalendarzach, codziennie, przez 24 dni, otwieramy kolejne „małe drzwiczki”. Wewnątrz znajdujemy do rozwiązania dwa zadania. Zaczynamy od prostych (w pierwszych dniach) a kończymy na naprawdę trudnych. Dane wejściowe i wyniki są tworzone losowo dla każdego uczestnika. Za poprawne rozwiązania przydzielane są punkty, w zależności od tego, jak szybko podamy rozwiązanie (czas liczy się od czasu opublikowania zadań na aktualny dzień, godzina 6:00). Na podstawie punktów tworzony jest ranking. Pozycja w rankingu zależy od uzyskanej ilości punktów i od tego, kto jak daleko zaszedł. Wraz z wzrastającą z dnia na dzień trudnością, powoli „wykruszają się” kolejne osoby. Brakuje czasu, dyscypliny, są ważniejsze sprawy, w sumie to tylko zabawa. Advent of Code jest od lat dosyć popularny. W tym roku pierwszy dzień ukończyło z powodzeniem 120 tyś osób, a do siódmego dnia dotarło ok 30tyś osób.
Czym jeszcze jest Advent of Code? Dla każdego czymś innym. Jedni szukają potwierdzenia, że ich język jest super bo szybko się w nim pisze. Inni chcą się sprawdzić, swój warsztat, swoje umiejętności. Pewnie też są osoby które przy okazji rozwiązywania zadań chcą nauczyć się nowego paradygmatu, nowego języka, albo nowych konstrukcji. Część osób udostępnia swój kod, daje to okazję to wymiany wiedzy.
Dlaczego o tym piszę? Po pierwsze, tak po prostu polecam każdemu kto jest w stanie wygospodarować kilkanaście, kilkadziesiąt minut a przy tym lubi wyzwania i lubi programować. Po drugie, popatrzyłem na czołówkę rankingu. Są tam osoby z tak dużą ilością punktów, że … „szacun”. Dostarczenie poprawnego rozwiązania zajmuje im często tylko sekundy. Jak to robią? Jakiego języka używają? Musi to być super język, skoro pozwala na tak szybkie programowanie. To pewne. Może się go nauczyć? Dlaczego nie? Popatrzmy na kompletne rozwiązanie jednego z zadań (pełny kod źródłowy) dostarczone przez aktualnego lidera rankingu:
a{Y3*=cÔ}š
Jest to rodzaj DSL’a, języka stworzonego specjalnie na potrzeby rozwiązywania zadań w Advent of Code. Ktoś wykonał znaczną intelektualną pracę, przeanalizował zadania z lat poprzednich, określił wymagania, stworzył implementację a teraz jest liderem rankingu. Co ważne, cała czołówka ma takie języki! Czemu to dowodzi?
Nasze języki których używamy na co dzień, są to języki ogólnego przeznaczenia. Da się w nich rozwiązać każdy problem w skończonym czasie. Ale, dla specyficznych zastosowań, tam gdzie mamy zawężony ale mocno powtarzalny zbiór wymagań, opłaca się najpierw znaleźć lub stworzyć narzędzie (DSL, MDA, LIB, …) a dopiero w nim wykonywać właściwą pracę. Jest to w tego typu kontekstach najbardziej optymalne podejście. Warto o tym pamiętać. Wiem, zaraz podniosą się głosy, że to nie jest czytelne. Odpowiedzmy sobie na pytanie co jest bardziej czytelne:
a)
a
b)
Files.lines(Paths.get(fileName)).collect(Collectors.toList());
W przykładowym DSL’u znak „a” powoduje wczytanie wszystkich linii pliku tekstowego do listy. Podobne zadanie w Java można wykonać tak jak pokazano w drugim przykładzie. Co jest bardziej czytelne? Czyż może być coś bardziej czytelnego niż jeden znak? Dla osób znających tego DSL’a jest on czytelny jak każdy inny język, a nawet czytelniejszy.
Kiedy więc jest ten moment gdy warto podjąć wysiłek i nie pisać „na pieszo”? Polecam rozważenie bardzo ważnego w programowaniu a niedocenianego pojęcia poziomu abstrakcji. Zawsze gdy nie zgadzają się nam poziomy abstrakcji powinno się nam zapalić czerwone światło. Kiedy to następuje? Rysowanie po canvasie kresek aby posiadać przycisk „submit” na formularzu to kompletny rozjazd poziomów abstrakcji. Podobnie jak komunikacja z kontrolerem dysku po to aby odczytać zawartość pliku. Ale także pisanie SQL, aby utrwalić obiekt w bazie danych to także dla wielu z nas zbyt odległe poziomy abstrakcji.
Te przykłady są oczywiste i wiadomo, tak nie robimy. Jednak na co dzień przytrafiają się nam mniejsze różnice poziomów, co wtedy? Wtedy decyduje ilość zastosowań, ilość powtórzeń. To oznacza, że jak potrzebuję często rozwiązywać podobny i specyficzny problem pewnej klasy to warto wtedy raz wykonać wysiłek na znalezienie gotowego rozwiązania, lub stworzyć własne, takie, które będzie miało dostosowany poziom abstrakcji do problemu. A potem wielokrotnie zyskiwać na używaniu go. Koszt poniesiony jeden raz na początku (forma inwestycji) zwróci się potem wielokrotnie z nawiązką (zwrot z inwestycji). Co właśnie uczyniła z sukcesem czołówka Advent of Code.
A ja, dlaczego ja się w to bawię? To proste. Mam coraz mniej okazji zawodowych do pisania kodu. Więc jest to okazja to ćwiczenia, przypomnienia, nauki nowych konstrukcji językowych, rozrywki. Człowiek powinien co jakiś czas, coś jednak napisać. Tak sadzę. No i na koniec zachęcam wszystkich piszących do zabawy w Advent of Code.
Krzysztof Olszewski
Dyrektor Technologii i Architektury Oprogramowania
Krzysztof Olszewski
Dyrektor Technologii i Architektury Oprogramowania