Dlaczego Kotlin jest świetny, ale i tak pozostaniesz przy Javie?
Marcin Perlikowski
Starszy programista Java
Jeśli jesteś programistą Java, prawdopodobnie masz przynajmniej pewne doświadczenie z innymi językami programowania. Niektórzy z nas rozpoczęli swoją przygodę z programowaniem w innym języku, takim jak C/C++, JavaScript, C#, Python, a może nawet w Pascalu lub Basicu. Niektórzy jednak zaczęli od Javy i po prostu nigdy nie zwracali zbytniej uwagi na inne języki, nieprzyjemnie wspominając ten jeden raz, kiedy musieli szybko zakodować coś po stronie frontendu.
Niezależnie od tego, do której grupy należysz, istnieje powód, dla którego pozostajesz z Java. I nie obwiniam cię. Ma prawdopodobnie najbardziej rozwinięty, uniwersalny i kompletny ekosystem na całym świecie. przedsiębiorstwo świat. Język ma ładnie dopasowany zestaw możliwości, gdzieś we właściwej strefie między zbyt dużą a zbyt małą ilością. A nowe funkcje są powoli, ale stale dodawane, dzięki czemu jest on w większości na bieżąco z nowszymi trendami w świecie programowania.
Czy wiesz Lombok ale? Jeśli nie, gorąco polecam spróbować. Jeśli ci się spodoba, to mam coś specjalnie dla ciebie. Zupełnie nowy język, który swoimi cechami sprawia, że Lombok staje się przestarzały. Nazywa się Kotlin.
Kotlin? Masz na myśli język Androida?
Kotlin na Androida został pobłogosławiony przez samo Google do tego stopnia, że stał się de facto językiem wyboru dla platformy. Nie na tym skupię się w tym artykule, ale Android jest rzeczywiście miejscem, w którym po raz pierwszy spotkałem się z Kotlinem.
Mój kolega z pracy tworzył aplikację dla ówczesnego projektna własną rękę. Terminy zbliżały się jednak szybko, więc zostałem oddelegowany, by pomóc mu ich dotrzymać. Przeniosę się teraz w czasie do tamtego momentu. Aaa i... YUCK! Dlaczego on używa jakiegoś dziwnego języka, który brzmi jak marka ketchupu!? Wygląda okropnie!
Dlaczego przed każdą funkcją jest napisane "fun"? Jakbym jeszcze nie wiedział, co to jest. Poza tym, już mam zabawa z Java w każdym razie. A gdzie jest typ zwracany? Na końcu? Zwariowałeś? Co to jest, przypisujesz coś do funkcji? To nie ma żadnego sensu! To wszystko wygląda jak Java z dodatkowymi krokami! Zaraz, gdzie jest klasa, do której należy ta metoda? Gdzie ją schowałeś ty keczupie, Java imitując wymówkę języka programowania? O nie. O nie, nie zrobiłeś tego. CZY TO JEST FUNKCJA GLOBALNA? To wszystko, skończyłem, dzwonię na policję.
Uwaga spoiler: nie wezwałem organów ścigania. Czy mi się to podobało, czy nie, musiałem dostosować swój sposób myślenia skoncentrowany na Javie, aby dostosować się do innego języka. Nie będzie jednak tak źle, prawda? To wciąż język JVM, z pewnością jest to po prostu inny język. Java. Może nawet z kilkoma fajnymi dodatkowymi funkcjami? Niechętnie zacząłem pracować nad projektem.
Java z dodatkowymi krokami
Jeśli Java jest taka świetna, dlaczego nie ma Javy 2? Żarty na bok, tak sobie pomyślałem. Będę po prostu udawał, że Kotlin to Java 2. Nowa składnia i w ogóle, ale muszę tylko nauczyć się jej na tyle, by ukończyć projekt. Ależ się myliłem.
Po wypróbowaniu go przez zaledwie dzień lub dwa, szybko zdałem sobie sprawę, że zarówno Kotlin, jak i Java nie są aż tak elastyczne. Próba naginania ich do siebie nieuchronnie kończy się pęknięciem jednego z nich na pół. Stało się oczywiste, że Kotlin jest czymś samym w sobie, a fakt, że działa na JVM, prawie nic nie znaczy z punktu widzenia programisty. (Na marginesie, może również transpilować do JavaScriptlub zostać skompilowana do natywnego pliku binarnego).
W takim razie plan B. Właściwie, poznaj język. Czytanie dokumentacji po raz pierwszy wywołuje dreszcze u doświadczonego programisty Java. Na przykład: - wspomniany wcześniej kontekst najwyższy, czyli globalny - parametry i typy zwracane funkcji określone na końcu
fun sum(a: Int, b: Int): Int {
return a + b
}
ciało funkcji może być wyrażeniem (z użyciem znaku równości)
fun sum(a: Int, b: Int) = a + b
instrukcja if może dostarczyć wynik
val y = if (x == 1) {
"jeden"
} else if (x == 2) {
"dwa"
} else {
"inny"
}
Ok, po prostu muszę się do tego przyzwyczaić. Po prostu inna składnia. Co jeszcze masz do zaoferowania, panie Kotlin?
value?.method() // wykonaj, jeśli nie null
Ok, pozbycie się if (value == null)punkt dla ciebie. Co jeszcze masz?
fun check(list: List, alternative: Boolean) = when {
list is LinkedList -> print("linked")
alternative -> print("alternative")
list.size > 50 -> print("big")
else -> print("other")
}
Hmm fajne, może być przydatne, aby uniknąć, jeśli inne bloki, nadal wydaje się jednak sztuczką.
object SingularObject: Counter() {
var a = 14
fun test() = if (a > 10) "więcej" else "mniej"
}
Ok, to wygląda na przydatne, podoba mi się! Z drugiej strony, w Javie też mogę stworzyć singleton. Może nie będzie to tak eleganckie, ale to nic nowego. Jakieś asy w rękawie? Na przykład naprawdę mocne uderzenia?
var s: String = null // nie kompiluje się, typ inny niż null
Wyobraź sobie bazę kodu, w której nie musisz martwić się o bezpieczeństwo null. Wyobraź sobie, że przyjmujesz za pewnik, że każda referencja faktycznie zawiera coś znaczącego. Wyobraź sobie pewność, że każdy problem związany z nullami jest rozwiązywany z wyprzedzeniem. Nie wyobrażaj sobie więcej. Wszystkie referencje w Kotlinie nie są domyślnie nullable. Jeśli chcesz je unieważnić, musisz świadomie podjąć tę decyzję, i wyraźnie podać to w kod:
var s: String? = null
Rozumiem, że w tym momencie możesz być sceptycznie nastawiony do całego pomysłu. Jesteś przyzwyczajony do nieważnych referencji. Masz to z tyłu głowy podczas kodowania. Nauczyłeś się, gdzie musisz być ostrożny. Dokładnie tak myślę. Pochodzę z JavaNa początku rzeczywiście czułem się dziwnie. Jaki to ma sens? To nie sprawi, że wszystkie związane z tym problemy magicznie znikną. Będę musiał po prostu dodawać "?" wszędzie, brzmi jak obowiązek.
Ale postanowiłem zanurzyć się głęboko w języku, prawda? Niech będzie po twojemu, panie Kotlin. Zacząłem starać się wyeliminować jak najwięcej zmiennych, pól i parametrów z wartością null. Krok po kroku nauczyłem się korzystać z funkcji języka, które ułatwiały eliminację nieważnych referencji, np. operator safe call "?.", operator elvis "?:", delegowane właściwości, metoda "let" i inne.
Z czasem udało mi się sprawić, że niektóre klasy zawierały tylko pola i parametry metod, które nie miały wartości null. Zasadniczo wiedziałem, że jeśli klasa zostanie pomyślnie utworzona, mogę prawie zapomnieć o pustych polach w ciałach metod. To była błogość. Z czasem doceniałem to coraz bardziej. Ostatecznie jednak nie uważałem tego za zabójczą funkcję, Java wciąż czułem się jak w domu. Do czasu...
Powrót
Projekt zbliżał się do końca. Coraz lepiej poznawałem Kotlin, a dzięki tej wiedzy kod stawał się coraz bardziej uporządkowany, czytelny i zwięzły. Ulepszenia można było dostrzec gołym okiem w historii commitów. W końcu jednak nadszedł ten czas. Z nieoczekiwanie miłymi wspomnieniami z nowego języka, nadszedł czas, aby się pożegnać i wrócić do słodkiej strefy komfortu Java. A przynajmniej tak mi się wydawało.
Czy znasz to uczucie, kiedy zaczynasz doceniać coś w momencie, gdy to się kończy? Kiedy nie zdajesz sobie sprawy, jak bardzo na czymś polegasz, dopóki nie możesz już z tego korzystać? To był najlepszy przykład tego uczucia, jakiego kiedykolwiek doświadczyłem w życiu.
Gdy wróciłem do pisania kodu w JavaByłem wręcz przerażony brakiem niektórych funkcji. To było tak, jakby mój mózg podświadomie, błędnie doposażał funkcje Kotlina w Javę. Doświadczyłem sytuacji, w których faktycznie zacząłem coś implementować, tylko po to, by zdać sobie sprawę, że to nie zadziała w tym języku. W najlepszym wypadku mógłbym napisać to w Kotlinie, ale byłoby to nieporęczne, nieczytelne i/lub wymagałoby zbyt dużej ilości boilerplate.
Bezpieczeństwo zerowe było oczywiście cechą, której najbardziej mi brakowało. Ale byłem zaskoczony, jak wiele mniejszych rzeczy stało się dla mnie naturalne: nazwane parametry, właściwości zamiast getterów i setterów, "==" jako equals i "==" jako równość referencyjna, kwalifikowane "this", funkcje rozszerzające, niejawny pojedynczy parametr lambda, "_" dla nieużywanych parametrów lambda, klasy danych, funkcje zakresu, inne funkcje Kotlin stdlib, operatory i wiele więcej. I sposób, w jaki to wszystko ładnie do siebie pasuje. Dla porównania, Java wydawała się... prymitywna.
Czułem się tak źle, że zacząłem rozważać całkowite przejście na Kotlin. Teoretycznie jest on w pełni interoperacyjny z Javą, można po prostu dodać obsługę Kotlina do istniejącego projektu i zacząć pisać nowe klasy. Strona Kotlina wie jak "rozmawiać" z Javą, a strona Javy nawet nie wie, że "rozmawia" z innym językiem. A po kompilacji do kodu bajtowego nie robi to żadnej różnicy dla maszyny JVM.
Weryfikacja rzeczywistości
Więc na co czekasz? Jeśli język jest tak dobry, jak mówisz, po prostu go użyj! Może jednak nie w istniejących projektach, wiem, że powinien być interoperacyjny, ale mieszanie dwóch różnych języków w ten sposób brzmi brzydko.
Ok, więc dla nowych modułów - Kotlin. A może jednak? Pracujesz w module zespół. Musisz się z nimi skonsultować i przekonać ich o wspaniałości tego nowego języka. Co? Nie podoba im się? Wygląda na to, że po prostu nie chcą włożyć wysiłku w jego naukę. Nie możesz ich za to winić, bo na początku też byłeś sceptyczny.
Kierownik projektu! Tak! Z pewnością zrozumie, jak wielką wartość Kotlin przyniesie naszemu zespołowi. Och, wspaniałość, która nadejdzie! -Nie -Czekaj, dlaczego? -Zespół o tym nie wie. -Nauczą się! -Nie chcą się uczyć. -Możesz je zrobić! -Nie muszą się uczyć. -To prawda, ale pomyśl o możliwościach! -Tak, może najpierw pomyśl o problemach.
Legenda głosi, że istnieje pewien projekt. Projekt, który jest duży i złożony, ale ładnie napisany w każdej części. Projekt, w którym wszyscy programiści są zgodni co do stosowanych rozwiązań. Gdzie nowe funkcjonalności płynnie wypływają z klawiatur programistów. Gdzie błędy są rzadkie i łatwe do naprawienia.
Czy widziałeś taki projekt? Ja nie. Niektóre były blisko, ale większość z nich to wielki bałagan w kodzie. A jeśli nie jest, to prawdopodobnie stanie się nim w pewnym momencie w przyszłości. Wyobraź sobie teraz, że dorzucasz do tego inny język. Wprowadza to nowe sposoby popełniania błędów. Wymaga od programistów wiedzy na temat tego, co robią. Jest to co najmniej ryzykowne.
Weźmy również pod uwagę rotację deweloperów. Ludzie przychodzą i odchodzą. Czy każesz każdemu nowemu programiście uczyć się zupełnie nowego języka? Nie, to przyniesie efekt przeciwny do zamierzonego. Czy zatrudnisz programistów Kotlin w pierwszej kolejności? Powodzenia, zatrudnienie dobrego programisty Java jest wystarczająco trudne.
Ludzie próbowali. Muszę powiedzieć, że nie zgadzam się z większością zarzutów w tym artykule. Jest tam trochę słusznej krytyki, ale myślę, że nie używali Kotlina wystarczająco dużo, aby faktycznie zrozumieć "sposób Kotlina". Wielu komentujących pod tym artykułem wydaje się myśleć podobnie.
To jednak nie ma znaczenia. Założę się, że w twoim projekcie też by się to zdarzyło. "Próbowałem, nie podobało mi się". Nie sprawisz, że spędzą nad tym więcej czasu. Nie sprawisz, że spróbują ponownie. Nie sprawisz, że dadzą mu kolejną szansę. I z praktycznego punktu widzenia mogą mieć rację. Java jest tak popularna, że używanie czegokolwiek innego na JVM wydaje się zbędne.
Dlaczego więc ten artykuł?
Właśnie poświęciłeś sporo czasu na napisanie artykułu, który wydaje się nie mieć sensu. Dlaczego miałbym próbować uczyć się języka, skoro i tak twierdzisz, że to bezcelowe?
Cóż, nie uważam, że to bezcelowe. Nadal uważam, że Kotlin jest świetny. Nadal chcę go używać (i faktycznie używam go w moich prywatnych projektach). Gdybym mógł, po prostu bym się na niego przerzucił i zapomniał o ograniczeniach Javy. Ale obecna rzeczywistość mówi, że nie mogę. I chcę spróbować to zmienić.
Moją intencją dla Ciebie, drogi czytelniku, jest przynajmniej rozważenie możliwości wyjścia z przytulnej strefy komfortu Java. Ponieważ może, tylko może, pokochasz Kotlin tak bardzo jak ja. A jeśli tak się stanie, to będzie to jeszcze jeden programista znający Kotlin na platformie rynek.