Dlaczego Kotlin jeszcze nie wyparł Javy?

0

Tak jak w tytule. Dlaczego Kotlin, język dużo lepszy od Javy i którego można z Javą mieszać, jeszcze jej nie wyparł z rynku albo robi to bardzo powoli? Oczywiście chodzi mi o backend, apki webowe. Wiem, że Kotlin już jest oficjalnym językiem Androida.

11

Bo:

  • nie wszyscy programiści znają się na Kotlinie
  • firmy nie rzucą się na Kotlina tylko dlatego, że jest fajny
  • Kotlin jest z reguły mniej wydajny niż Java

Uważam Kotlin za fajny język i do większości zastosowań lepszy od Javy.
Nie uważam jednak, żeby "mieszanie" Kotlina i Javy lub wdrażanie Kotlina przynosiło większe zyski niż koszty przy większości projektów.

3

Bo na rynku jest miliony programistów Java i promil tego programistów Kotlina. Bo jest do utrzymania softu za tryliardy dolarów napisanego w Javie (niektóry soft pewnie ma już ze 20 lat i więcej). Mieszanie technologi naprawdę musi być dobrze uzasadnione, żeby miało sens. Jakoś tego nie widze w krytycznych systemach.
Przed Kotlinem było już kilka języków na JVMa których już prawie nie ma. Tak że przed ketchupem jeszcze długa drogo w podbijaniu świata.

2
Sampeteq napisał(a):

Dlaczego Kotlin, język dużo lepszy od Javy i którego można z Javą mieszać, jeszcze jej nie wyparł z rynku?

A po co? :)

1

Dodam że różnice maleją. Na przykład - lepsze switche, wprowadzanie powoli pattern matchingu, recordy, sealed classy - to już jest w Javie.
Project Loom to będę pewnie lepsze coroutines i to jeszcze bezpośrednio wspierane na platformie JVM...

4

język dużo lepszy od Javy

citation needed

Bo nie jest "dużo lepszy od javy". Ma dosłownie kilka ciekawych ficzerów których jeszcze nie ma w Javie i bardzo daleko tu do jakiegoś game changera. Popularność zdobył na Androidzie bo tam przez długi czas nie dało się użyć Javy powyżej 1.7 i faktycznie tam robiło to różnicę.

4

Bo firmy z projektami które nie powstały wczoraj nie rzucają się na nowe technologie tylko dlatego że coś wyszło. Produkt musi być przede wszystkim stabilny.
Dodatkowo to są koszty, bo trzeba zatrudnić kotliniarzy i/lub przeszkolić istniejących jawowców.

0

Podepnę się pod temat.

  • Czy Kotlin to najpopularniejszy język JVM po Javie?
  • Jaki język JVM polecacie się nauczyć i dla czego? Czy to właśnie Kotlin? Szczególnie chodzi o Tworzenie aplikacji webowych- czy są języki które mają jakieś lepsze frameworki do tego (chociaż domyślam się że skoro to JVM to powinno działać w każdym języku)?
1

Od strony programowania ten język nie zmienia sposbu myślenia więc trochę mi szkoda życia, aby go poznać.

Od strony pracy. Język ułatwia pracę, ale jej nie upraszcza, w jakimś stopniu trzeba wiedzieć co się działo w java, inaczej bieda.

Od strony firm. Ciężko wskazać biznesowi gdzie kotlin powoduje różnicę przekładającą się na $. Kotlin pewnie robi różnice w utrzymaniu, łatwiej zarządzać kodem, gdy jest mniej kodu, gdy jest mniej przypadków gdzie można się spażyć, ale to trochę za mało, aby przekonać. To tak jakbyśmy się przyznali, że jesteśmy za słabi już na starcie.

Może kiedyś JetBrains stworzy jakieś ulta-szerokie środowisko o którym świat się dowie, które pozwoli pisać jedną apkę kod, który będzie działał praktycznie od razu pod backend, front i mobilne i będzie to po prostu zarówno efektywne i przyjemne, a przede wszystkim oszczędne.

0

To tak jakbyśmy się przyznali, że jesteśmy za słabi już na starcie.

Wszyscy są "słabi", róznicą jest jak dużo kupy możemy mieć w cache w głowie, ale po co trzymać kupę w głowie, jak można trzymać wymagania biznesowe?

12

Shalom:

Shalom napisał(a):

język dużo lepszy od Javy

citation needed

Bo nie jest "dużo lepszy od javy".

Jedziemy:

  • spójna prosta składnia kotlina. Java w kolejnych wersjach przypomina coraz bardziej potwora C# / Frankenstaina. Normalka - nagar dziejów i próba pudrowania.
    Taki var jest najlepszym przykładem : w javie działa w konkretnych przypadkach i całkiem nie pasuje do reszty języka. W kotlinie pola, metody, argumenty - wszystkie lecą wg jednego schematu - var x:OpcjonalniePodawanyTyp = wyrażenie;. Elegancja ma znaczenie, albo raczej - jak pracujesz w języku kupie to trudno pisać w nim elegancki kod.

  • wyrażenia: w kotlinie wszystko da się zapisać za pomocą wyrażeń. fun add(x:Int,y:Int) = x+y. if, when, try są wyrażeniami - to zupełnie zmienia sposób pisania bezpiecznego kodu (nie ma potrzeby używania return, trudniej coś rypnąć przez brak else i tym podobne błędy),

  • data class - javowe rekordy się nie umywają, bo nie mają (jeszcze) copy() (czy tam with()) - to jest duża, niedoceniana różnica

  • spójniejszy i prostszy system typów - Any, Unit, Nothing - zamiast koszmarów w stylu zupełnie z dupy typy prymitywne

  • Null Safety - killer feature generalnie dla mnie

  • function types - można napisać val x:(Int,Float)->String jako pole (zamiast tworzy dziwolągi typu Function2<Int, Float, String> (można nawet po takich typach dziedziczyć).

  • KotlinJS - to jest jeszcze mocno niedoceniane, ale prosta możliwość zrzucania kodu do JS jest naprawdę przydatna (kotlin native natomiast nie wiem czy kiedyś będzie sensowny w dobie graal).

  • extensions functions daje duży power w pisaniu czytelnego kodu (!!!). Czytaj - można robić sensowne DSLe czyli pisać kod domenowy tak, żeby dało się czytać jak tekst.

Są jeszcze smaczki - nie aż tak ważne, ale istotne:

  • declaration site variance - bardziej intuicyjne w programowaniu bibliotek od javowego use site variance,

  • nie trzeba pisać final var bo jest val,

  • nie trzeba robić catch bo kompilator i tak wie, że nie umiesz pisać obsługi wyjątków,

  • wbudowane listy w kotlinie są kijowe, ale nie tak kijowe w użyciu jak te w javie (strumienie), (ale tu remis - i w jednym i w drugim najlepiej użyć vavr).

Oczywiście w kotlinie tony rzeczy brakuje - względem scali (choć obecnie to Scala 3 trochę odgapiła od kotlina (tylko lepiej).

W javie mamy tony javowych architektów i korpostandardów, które tak naprawdę o wiele bardziej mnie od tego języka odstraszają niż przestarzała składnia.
Stary kod javowy mnie nie odstrasza - konieczność pisania nowego kodu, żeby wyglądał jak stary już tak.
Do tego dochodzą oczywiście kontrowersyjne frameworki javowe - w kotlinie tez jest spring i ma sie dobrze, ale przynajmniej alternatywy są częsciej używane.

Natomiast nie jest tak, że język lepszy wypiera gorszy - wręcz odwrotnie. Javowi architekci, którzy nauczyli się jak się pisze systemy 20. lat temu nie dadzą się tak łatwo odstawić na boczny tor. A zmiana języka w firmie by tym groziła (zresztą dlatego java >9 nie wyparła też javy 8 - chociaż tu powoli się poprawia).

Czy Kotlin to najpopularniejszy język JVM po Javie?

Zależy jak liczyć. Niektórzy powiedzą, że Groovy. Ale jeśli chodzi o język pisania aplikacji to raczej kotlin.

Jaki język JVM polecacie się nauczyć i dla czego? Czy to właśnie Kotlin? Szczególnie chodzi o Tworzenie aplikacji webowych- czy są języki które mają jakieś lepsze frameworki do tego (chociaż domyślam się że skoro to JVM to powinno działać w każdym języku)?

Zależy, od Ciebie. Ja zdecydowanie od Javy wolę Kotlina, ale od Kotlina wolę Scale: ze względu na frameworki i programowanie funkcyjne.
Kotlin jest bardziej mainstream friendly. Scala jest bardziej prawilna. Ale wybór to kwestia osobista - jak komuś nie po drodze z funkcyjnym to Scala to średni wybór.

EDIT:
zanim ktoś podniesie ten argument -
obecnie już często nie trzeba znać Javy żeby pisac w Kotlinie.
od dawna nie trzeba znać Javy, żeby pisać w Scali (znam trochę programistów Scali co javy nigdy się nie uczyli (młodych), albo takich co już lata temu zapomnieli).

2

Dla mnie jedynie KotlinJS i Kotlin Native są jakimś tam argumentem żeby wybierać Kotlina do przyszłych projektów (jeśli tego akurat potrzebują).
A przede wszystkim jest to jakiś argument dla osób decyzyjnych, które nie tylko nie odróżniają var od val ale również for od while.

Język może przyjemniejszy, ale mało jest pracodawców którzy dbają o komfort pracownika w tym względzie (albo ja ciągle źle trafiam).

1
Shalom napisał(a):

język dużo lepszy od Javy

citation needed

Shalom, Ty tak serio? :P

1

zamiast koszmarów w stylu zupełnie z d**y typy prymitywne

Nigdy mi jakoś nie robiły wielkich problemów, ale ja nie mam OCD. No i też prawie nigdy nie żongluje typami prymitywnymi.

extensions functions

O tak, monkey patching to jest to czego brakuje do pisania czytelnego kodu :D Ktoś czasem kiedyś nie mówił, ze jak nie jesteś w stanie ogarnąć kodu bez wsparcia IDE to coś jest nie tak? Chętnie zobacze jak ktoś ogarnia projekt pełny extension functions, próbując znaleźć gdzie są pododawane ;)

var / val

To trochę argument podobny do tego wyżej. Nie wiem czemu ludzie się tym tak podniecają, bo to jest akcja w stylu o patrzcie, mogę sobie napisać var i nie muszę podawać typu! a za chwilę ojej, panie IntelliJ proszę mi pokazać co za typ tam siedzi.

2

To trochę argument podobny do tego wyżej. Nie wiem czemu ludzie się tym tak podniecają, bo to jest akcja w stylu o patrzcie, mogę sobie napisać var i nie muszę podawać typu! a za chwilę ojej, panie IntelliJ proszę mi pokazać co za typ tam siedzi.

No zwłaszcza jak masz po prawej jakiś Future<Try<UberDlugaNazwa>> ;]

1
Shalom napisał(a):

Nigdy mi jakoś nie robiły wielkich problemów, ale ja nie mam OCD. No i też prawie nigdy nie żongluje typami prymitywnymi.

Taki komentarz : nie mam OCD powinieneś był wrzucić na koniec dyskusji, jak już by Ci się skończyły argumenty.

extensions functions

O tak, monkey patching to jest to czego brakuje do pisania czytelnego kodu :D Ktoś czasem kiedyś nie mówił, ze jak nie jesteś w stanie ogarnąć kodu bez wsparcia IDE to coś jest nie tak? Chętnie zobacze jak ktoś ogarnia projekt pełny extension functions, próbując znaleźć gdzie są pododawane ;)

Tu jest dokładnie taki sam case jak import static w javie. Dramat, bo potem nie wiadomo skąd się ten shouldBe bierze. Ale jednak ludzie w javie stosują. Jeśli raz na dzień trzeba dopytać IDE po to żeby ileś linii kodu nie wyglądało jak rzygi to jednak warto.

var / val

To trochę argument podobny do tego wyżej. Nie wiem czemu ludzie się tym tak podniecają, bo to jest akcja w stylu o patrzcie, mogę sobie napisać var i nie muszę podawać typu! a za chwilę ojej, panie IntelliJ proszę mi pokazać co za typ tam siedzi.

To trochę argument jak po co ludzie interfejsy stosują, a potem olaboga instanceof, albo getClass, bo nie wiem co tam za obiekt siedzi. Mnie wkurza akurat pokazywanie typu (ale czasem faktycznie muszę włączać, bo inni sa do tego nieprzyzwyczajeni i faktycznie im czegoś brakuje jak w moje IDE paczają).

1

Według mnie pytanie jest źle sformułowane. Powinno brzmieć: "Dlaczego programowanie funkcyjne jeszcze nie wyparło obiektowego?", gdyby to się stało - automatycznie więcej osob doceniloby kotlina czy scale. :)

1

@jarekr000000:

Tu jest dokładnie taki sam case jak import static w javie. Dramat, bo potem nie wiadomo skąd się ten shouldBe bierze. Ale jednak ludzie w javie stosują. Jeśli raz na dzień trzeba dopytać IDE po to żeby ileś linii kodu nie wyglądało jak rzygi to jednak warto.

No ale dla mnie czytelniejsze jest: isNull() niż Objects.isNull()

3

Problem jest złożony i powodów jest zapewne wiele.

  1. Klepacze kodu.
    Choć ciężko w to uwierzyć, to serio wiele, a może nawet znakomita większość ludzi żyjących z programowania, nie interesuje się programowaniem. 8h klepania w pracy i nara, idziemy do domu. Taki człowiek raz nauczył się Javy, dostaje za to (ogromne jak na polskie warunki) pieniądze, jest mu z tym dobrze to po co wiedzieć więcej.

  2. Błędne koło popularności
    Java jest popularna, co sprawia, że jest popularna. I tak w kółko. Jest to dosyć zrozumiałe, bo popularność daje poczucie bezpieczeństwa. Można być pewnym, że za 20 lat Java będzie się miała relatywnie dobrze, będzie miała support community. Co do Kotlina nie byłbym 100% pewny.

  3. Ciężko się przebić z nową technologią.
    Dopóki technologia nie wywraca wszystkiego do góry nogami (w dobrym kierunku) to jest po prostu ciężko. Analogiczny case to JavaScript i TypeScript. Dla mnie ten pierwszy się nadaje co najwyżej do kosza, a drugi jest całkiem spoko. Mimo to TS jest nadal jakimś planktonem w porównaniu do JSa.
    Generalnie to marketing jest ważniejszy niż produkt. Nikt nie wpakuje w taki język jak Kotlin tyle $$ co Sun wpakował w rozreklamowanie Javy. Organiczny wzrost jest i będzie powolny bez agresywnego marketingu.

  4. Ludzie są po prostu głupi
    Serio, po prostu. Natrafiłem kiedyś na ten artykuł - https://blog.allegro.tech/2018/05/From-Java-to-Kotlin-and-Back-Again.html. Argumenty w miarę sensowne, mimo wszystko raczej się nie zgadzam. Kontrargumentów pokazujących, że Kotlin > Java można pewnie kilkukrotnie więcej pokazać. Jednak nie artykuł jest tutaj istotny, a komentarze. Tam takie kwiatki:

With the new additions to Java there's little reason to switch to Kotlin to get all the useful modern features other than the 'hip' factor.

Java - Code is like paragraphs. It is like reading a 4 line for loop at once and you know what the code does. It almost becomes second nature.
Kotlin - Smaller sentences instead of a paragraph. Read a sentence at once but still it is slower to know the intent of the code.

Over a period of time, we have made most of our variables nullable! Because the business logic requires it. In some scenario, a field of an entity may be null so it is to be made nullable. The whole purpose of null safety is mostly defeated. It is the responsibility of programmer to handle this and not language.

To ostatnie zasługuje na wyróżnienie, bo głupszej rzeczy nie widziałem od dawna.

Trochę też takich agresywnych wysrywów, ociekających ignorancją:

Monads are pseudo-intellectual garbage that are impossible to explain logically and coherently even by those "well versed" in FP(an entire pseudo-paradigm that appeals to pseudo-intellectual folks that love to pretend that cryptic nonsensical stuff is "cool" and "smart")

A language promoted by Google to exert pressure on Oracle. As Bartosz indicated - we would still be hiding in caves if we had not weighed profits and costs. It should have been named "kotlet" (cutlet) by Russians in JetBrains.

Ogólnie, z czasem pewnie Kotlin/Scala będą miały większy udział w rynku kosztem Javy, ale będzie się to działo powoli. Java jednak na tyle mocno się osadziła, że chociażby ze względu na ilość legacy kodu, który trzeba utrzymywać będzie popularniejsza od wszystkich innych języków z JVM razem wziętych.

0

@Grzyboo:

Ludzie są po prostu głupi
Serio, po prostu. Natrafiłem kiedyś na ten artykuł - https://blog.allegro.tech/201[...]to-Kotlin-and-Back-Again.html. Argumenty w miarę sensowne, mimo wszystko raczej się nie zgadzam. Kontrargumentów pokazujących, że Kotlin > Java można pewnie kilkukrotnie więcej pokazać. Jednak nie artykuł jest tutaj istotny, a komentarze. Tam takie kwiatki:

Zerknąłem na ten artykuł, przejrzałem ok 30%. Możesz konkretnie napisać z którymi argumentami się nie zgadzasz i dlaczego?

11

Zawsze chętnie pojade ten artykuł z allegro bo to fajne.

https://blog.allegro.tech/2018/05/From-Java-to-Kotlin-and-Back-Again.html

Name shadowing

Sensowna IMO krytyka. Co prawda u mnie leci błąd, ale używam opcji traktowania warningów jako errorów. Nie jest to domyślna opcja w kompilatorze. ✅

Type inference

O rany, teraz nowa (10) java ma to samo (var). Co prawda w bardzo ograniczonym zakresie i niespójnie z resztą javy. Ale jest, więc po co kotlin. 🤦

Compile time null-safety

Java nie ma żadnego null-safety, kotlin ma. Ale jak wywołasz javę z kotlina to null-safety nie działa i może się wyrąbać. 🤦
(Autor ewidentnie myśli, że przy wywoływaniu kodu javowego kotlin zawsze powinien przyjmować, że poleci tam null i kazać obsługiwac nulle,
tyle że wtedy ciężko by się pisało coś na styku z javą i byłby tu punkt, że nie da się z kotlina kodu javowego wywołać, bo trzeba wszędzie ify wstawiać).

Class literals

Autor nie wie, że jest .javaClass 😞 Czyli słabo tutorial w kotlinie musieli zrobić

Reversed type declaration

Kotlin nie jest javą i ma inną składnię niż java. Zgadzam się w pełni. Do tego czasem trzeba pisać pełną nazwę typu - jak w javie (tylko, że w javie zawsze). WTF?

Companion object

Kotlin nie jest javą i nie używa słowa static. Za to ma companion object, o którym autor wie i mu sie nie podoba, bo nie jest javą a do tego trzeba napisać więcej literek.
Kotlin ma też fun (Top Level) - gdzie trzeba pisać jeszcze mniej literek niż w javie. 🤦

Collection literals

Co prawda java jest tu zupełnie kijowa i przegrywa z wszystkimi wymienionymi jezykami, ale składnia kotlina mniej się autorowi podoba niż ta w JS.
Czyli kotlin nie jest JSem, dlatego autor woli Javę 🤦

Maybe? Nope

Autor przyzwyczaił sie do tego, że javowy Optional jest zrypany i płacze, że nie wszędzie indziej jest:
https://www.sitepoint.com/how-optional-breaks-the-monad-laws-and-why-it-matters/
Zresztą to jest powód (jeden z dwóch) dla którego nawet w Javie nie używałem Optionala, tylko Optiona z VAVR. (Nie mam ikonki współczucia).

Data classes

Autor nie wie, że w językach trochę funkcyjnych używamy do modelowania domeny Uni i Produktów typów. data class to taki produkt, a sealed class to unia. Dlatego, wbrew temu co autor pisze, data class dobrze nadaje się do modelowania domeny, po prostu modelowania nie w takim samym stylu jak w javie.
Ale życie dopisało najlepszy epilog:

  • teraz w javie są rekordy i mają takie same ograniczenia jak data class w kotlinie, nie można z nich dziedziczyć.
    screenshot-20211028103348.png

Open classes

Jedna z najdziwniejszych zwał javy - wszystko jest open by default i tona ludzi pisząc w javie rypie te finale, żeby jednak uprościć analizę kodu i ukrucić potencjalne nadużycia. Robienie klass final jest uważane raczej jako dobra praktyka (w javie).

https://medium.com/@lukleDev/how-effective-java-may-have-influenced-the-design-of-kotlin-part-2-89844d62ddf3#:~:text=Final%20classes%20by%20default,specify%20the%20class%20as%20final%20.

Kotlin przyjął tą lekcję i robi ten final domyślnie, przez to nie jest już javą 🤦

Steep learning curve

Co prawda składnia kotlina jest prostsza od javy, ale jak ktoś już zna javę to nauczenie się kotlina jest trudniejsze niż dalsze umienie javy.
Oczywiście obśmiewam, ale ten argument jest jak najbardziej prawidłowy ✅

1

@jarekr000000:

nie wiem jakie są te drobne irytacje powodowane przez vavr

Zanim o tym to tylko powiem, że moje doświadczenia z vavrem są stricte z Javy, w Kotlinie nie używałem. Jeżeli gadam jakieś głupoty to chętnie się dowiem, bo szczerze to mało jest materiałów o tym jak używać vavra dobrze.

  1. Trzeba dodać do każdego projektu wraz z modułem jacksona. Niby nic, ale wkurza. Liczyłem na to, że w Kotlinie nie będę musiał lomboka i vavra wrzucać w każdy projekt. Z lombokiem się udało, ale jak się dowiaduję to z vavrem niekoniecznie.

  2. Debuggowanie linked listy (vavrowe List) to koszmar. Poniżej 3 elementowa lista. Gdy elementów jest 15 i chcę je podejrzeć to dopiero jest zabawnie.
    screenshot-20211028210908.png
    Dla porównania ArrayLista z Javy
    screenshot-20211028211120.png

  3. Identyczne nazwy jak java.util List, Set, Map...
    Generalnie bardzo łatwo pomieszać importy. Piszę HashMap.of i intellij mi nic nie podpowiada. No tak... przez przypadek zaimportowało mi java.util.HashMap.

  4. Identyczne nazwy jak java.util v2
    Piszę testy w Spocku (Groovy), gdzie java.util.List jest importowane z automatu to moje List.of(...) zwraca nie to, czego oczekuję :D Muszę ręcznie dodać importa io.vavr.collection.List

  5. Identyczne nazwy jak java.util v3
    Jako, że vavr nie jest częścią języka to wszelkie biblioteki nie zwracają vavrowych kolekcji. Ciągle trzeba te wszystkie java.util.Listy konwertować na io.vavr.collection.Listy. A przez to, że się nazywają identycznie to jeden z tych typów musi mieć fully qualified name i powstają takie potworki:

java.util.List<Pizza> items = (java.utl.List<Pizza>) jdbcCall
   .execute(params)
   .get("pizzas");
return List.ofAll(items);
  1. Brakuje collection-builderów
    W guavie mamy np. new ImmutableList.Builder<Pizza>(). Czasami się po prostu przydaje mutowalna lista, żeby móc do niej coś pododawać i na koniec zwrócić niemutowalną. W vavrze nie ma takich bajerów, więc mam używać java.util.List do budowania niemutowalnej listy? To nie działa dobrze, patrz punkt poprzedni.

  2. Option nie ma intuicyjnej metody np. .ifPresent, zamiast tego odpowiednik .forEach. Tak, wiem... Można Option podmienić na List i nawet nie będę musiał nic innego podmieniać w kodzie, żeby działało. Bardzo fajne, nigdy się nie przydało. A zamiast tego: wkurza, jest nieczytelne, a dla osoby która nie używała vavra jest to wręcz duży WTF - dlaczego na obiekcie "0 lub 1 element" wykonuję metodę nazywającą się "forEach"

  3. Option nie ma możliwości operatora ?. z Kotlina
    A przede wszystkim tego oczekuję od tworu Option, który ma mi pomóc z nullowalnością, czyli możliwości wykonania "pobierz to wszystko tak żeby mi nie wywaliło NPE", czyli np. kotlinowe val lang = post?.author?.settings?.languageSettings?.lang ?: Lang.EN. Javowy Optional pozwala swoim zepsutym .map, vavrowy Option już nie. Od Optiona oczekuję pomocy z nullowalnością, a nie tego żeby spełniał definicję monady.

Post post = new Post(null);
Lang lang = Optional.of(post)
                .map(it -> it.author)
                .map(it -> it.settings)
                .map(it -> it.languageSettings)
                .map(it -> it.lang)
                .orElse(Lang.EN);

Lang lang = Option.of(post)
                .map(it -> it.author)
                .map(it -> it.settings) // zonk, NPE
                .map(it -> it.languageSettings)
                .map(it -> it.lang)
                .getOrElse(Lang.EN);

Mogę próbować z flatMapami, ale jeśli moje Posty, Authory i Settingsy nie przechowują/nie zwracają Optiona same z siebie (co jest raczej częste w zastanym kodzie) to podziękuję:

Lang lang = Option.of(post)
                .map(it -> it.author).flatMap(Option::of)
                .map(it -> it.settings).flatMap(Option::of)
                .map(it -> it.languageSettings).flatMap(Option::of)
                .map(it -> it.lang).flatMap(Option::of)
                .getOrElse(Lang.EN);
// lub
Lang lang = Option.of(post)
                .flatMap(it -> Option.of(it.author))
                .flatMap(it -> Option.of(it.settings))
                .flatMap(it -> Option.of(it.languageSettings))
                .flatMap(it -> Option.of(it.lang))
                .getOrElse(Lang.EN);

Więcej nie pamiętam.

0

Mogę próbować z flatMapami, ale jeśli moje Posty, Authory i Settingsy nie przechowują/nie zwracają Optiona same z siebie (co jest raczej częste w zastanym kodzie) to podziękuję

Ale to wina tych klas a nie Optiona tak troche. Scala by sie tez chyba polozyla tutaj. Chociaz faktycznie Kotlinowe ?. w tym przypadku (integracji z gowniana Java) jest lepsze. Ale uzywajac vavra nie musisz uzywac Optiona.

EDIT: to wina klasy w tym sensie, ze option nie jest wrapperem na try-catch(npe) tylko typem z efektem "moze byc a moze nie byc". W Javie nulle to taki "standard", ze implementujac Optionala i tak mieli w glowie nulle.

EDIT2: A przede wszystkim tego oczekuję od tworu Option, który ma mi pomóc z nullowalnością - tylko tam gdzie faktycznie sie uzywa optionow to nulle wcale a wcale nie wystepuja. W Scali sie nie uzywa. W Haskellu czegos takiego nawet nie ma. Typ opcjonalny nie ma sluzyc do "radzenia sobie z nullowalnoscia" a ma sie tej nullowalnosci calkowicie pozbyc. W tym sensie, ze nigdzie w kodzie nie pada "null". None/Nothing to cos innego niz Null. Chociazby dlatego, ze musi byc ZAWSZE obluzony a nie tylko wtedy jak osoba wolajaca metode sobie to owrapuje recznie w optionala. Jak nie zapomni.

Optional.ofNullable(foo.bar()) jest porownywalne do if(foo.bar() != null).

I Kotlin w wypadku javovego typu T! tez ma problem bo jak najbardziej mozesz zrobic ?. alee... Nie musisz...

I w tym sensie to zachowanie Optiona jest nawet lepsze bo jawnie kara za uzywanie nulla.

No ale jak sie musi pracowac z Java to nie poradzisz...


EDIT3: To troche sytuacja jak leki vs cieple ubrania w zimie. Leki sluza do radzenia sobie z choroba, ktora Cie dopadla a cieple ubrania maja Cie uchronic przed przeziebieniem zanim go dostaniesz. Ale jak juz sie przeziebisz to cieple ubrania Cie nie ulecza :) . Pytanie czy lepiej leczyc czy zapobiegac?

2

Jaki język JVM polecacie się nauczyć i dla czego? Czy to właśnie Kotlin? Szczególnie chodzi o Tworzenie aplikacji webowych- czy są języki które mają jakieś lepsze frameworki do tego (chociaż domyślam się że skoro to JVM to powinno działać w każdym języku)?

@Aventus jak już to Scale. Nauka Kotlina w stosunku do C# nie da tak dużej róznicy jak Scalii, język z większym wsparciem FP, z innymi bibliotekami, innym podejściem do wielu rzeczy (np. Scalowcy niezbyt lubią kontenery IoC z tego co widze). To może dać jakąś realną zmiane spojrzenia niż tylko zmiana frameworka.

0
fgh napisał(a):

Od strony programowania ten język nie zmienia sposbu myślenia więc trochę mi szkoda życia, aby go poznać.

Zgadza się, to nadal jest przypudrowana Java, ale ten puder robi różnicę. Czasami oszczędzi ci parę znaków, czasami kilkadziesiąt linii, a czasami wykorzysta twoje lenistwo, żeby zrobić coś dobrze, bo tak jest łatwiej

Od strony pracy. Język ułatwia pracę, ale jej nie upraszcza, w jakimś stopniu trzeba wiedzieć co się działo w java, inaczej bieda.

Nie da się być programistą Kotlina bez znajomości Java, tak jak nie da się być np. programistą Lombok.

Od strony firm. Ciężko wskazać biznesowi gdzie kotlin powoduje różnicę przekładającą się na $. Kotlin pewnie robi różnice w utrzymaniu, łatwiej zarządzać kodem, gdy jest mniej kodu, gdy jest mniej przypadków gdzie można się spażyć, ale to trochę za mało, aby przekonać. To tak jakbyśmy się przyznali, że jesteśmy za słabi już na starcie.

Co ma biznes do języka programowania? Wybór stacka, to decyzja techniczna a nie biznesowa. To tak jak gdyby hydraulik pytał mnie, czy do uszczelnienia rur użyć teflonu czy pakuł - koszt ten sam, ostateczny efekt ten sam, pracochłonność też ta sama, niech sobie używa czego chce, albo przedstawi mi coś, co robi różnicę od strony funkcjonalnej.

Może kiedyś JetBrains stworzy jakieś ulta-szerokie środowisko o którym świat się dowie, które pozwoli pisać jedną apkę kod, który będzie działał praktycznie od razu pod backend, front i mobilne i będzie to po prostu zarówno efektywne i przyjemne, a przede wszystkim oszczędne.

Powstało już trochę takich ultraszerokich środowisk. Masz JS w którym napiszesz backend, frontend, mobile, to samo masz w Kotlinie (nawet szerzej, bo jeszcze jest Kotlin native). Tylko nie ma to znaczenia, bo mając projekt, w którym masz wszystkie te elementy, cały zysk z unifikacji języka sprowadza się do wspólnych DTOsów, a jak ktoś np. nie ogarnia pisania aplikacji mobile, to fakt, że niby może je pisać w języku, który już zna, nic nie zmienia.

2

Czytam te komentarze i trudno mi uwierzyć, że tyle osób uważa kotlina za przypudrowaną jave. Funkcjonalności które wcześniej podał @jarekr000000 sprawiają, że kod w kotline już dużo czytelniejszy i bardziej bezpieczny niż ten w javie. Oczywiście można pisać w kotline podobnie jak w javie (często zespoły które przerzucają się na kotlina na samym początku tak robią). Tak samo w javie można pisać podobnie jak w C/C++, ale jakoś nie słyszę, aby ktoś mówił, że java to lukier składniowy do C/C++.

3

Nie da się być programistą Kotlina bez znajomości Java, tak jak nie da się być np. programistą Lombok.

Oczywiście że można być programista Kotlin bez znajomości Javy. Znajomość JVM może być przydatna jest przydatna ale JVM != Java lang.

Co ma biznes do języka programowania? Wybór stacka, to decyzja techniczna a nie biznesowa

Oczywiście że ma. Inny koszt jest zatrudnienia developerów Java, inny PHP, inne możliwości znalezienia kogoś na szybko, inna stabilność platformy etc.

1

@rad1317: Jasne, że kod jest czytelniejszy, ale nadal ~każda klasa da się przepisać 1:1 z jednego języka na drugi. Oczywiście mamy fajniejszego optionala, nazwane parametry metod, jednolinijkowe wrappery, properties i inne wynalazki, które powodują, że nie trzeba stosować Java-wynalazków rozwiązujących sztuczne problemy (np. bez sensu jest pisanie w Kotlinie buildera, wrappera, teleskopowych konstruktorów). Tylko to wciąż są lekkie różnice na poziomie składni, bo poza mocno różnym podejściem do typów generycznych, cała reszta języka jest bez zmian. Dla mnie różnica Kotlin vs Java jest niewiele większa od ten pomiędzy C#, a VB. Co nie znaczy, że mając możliwość wyboru, należy iść w stronę Javy, czy VB.

@scibi_92: Nawet w małym projekcie prędzej czy później musisz skorzystać z biblioteki standardowej Java. Albo zerknąć co się naprawdę dzieje w jakiejś bibliotece, którą dociągnąłeś do projektu. Pełna kompatybilność na poziomie kodu pomiędzy Java a Kotlin jest założeniem Kotlina.

Co do "decyzji biznesowej" - naprawdę uważasz, że decyzję o wyborze języka programowania powinien robić ktoś, kto nie odróżnia bitów od bajtów? Może jeszcze biznes mi powie jakiej bazy danych mam użyć, albo czy iść w microservice czy w monolit? Biznes ma dać wymagania biznesowe i odpowiedzieć na pytania typu wymagana skalowalność, SLA, przewidywany czas życia produktu. Development ma dobrać sobie narzędzia do spełnienia tych założeń.

3

@piotrpo: nie bardzo rozumiem co masz na myśli, pisząc, że da się przepisać kod z jednego języka do drugiego 1:1. Samo przepisanie z kotlina do javy null safety, typealias i wnioskowanie typów będzie wyglądało w javie jak totalne g*wno. A jest jeszcze cała masa innych rzeczy, które kotlin załatwia za progamistow. Więc pod względem funkcjonalności może i się uda osiągnąć podobny efekt, tylko raczej nie będzie to przyjemne przeżycie.

Ps: spróbuj w kotline odwzorować package scope, a w javie internal.

3

Chciałem pokazać na prostym przypadku co się stanie jak:

  1. weźmiemy prosty kot w kotlinie,
  2. skompilujemy,
  3. przekonwertujemy do javy (intellij umi to)
  4. przekonwertujemy z powrotem do kotlina (intellij też to umie).

Ale nie wyszło - bo już w kroku 3. dostajemy kod, który się nie kompiluje w javie....

Kotlin:

package kotlintojava

fun main() {
    data class Janusz(val x:Int, val a:String, val j:Janusz? = null)

    val j1 = Janusz(7,  "Janusz")
    val j2 = j1.copy(x = 1)
    val j3 = j2.copy(x = 2, a = "NieJanusz", j = j2)
    println(j3)
}

Java (ale nie wyszło):

package javatokotlin;

import kotlin.Metadata;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@Metadata(
        mv = {1, 4, 2},
        bv = {1, 0, 3},
        k = 2,
        d1 = {"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
        d2 = {"main", "", "kotlinoweWisnie"}
)
public final class JanuszKt {
    public static final void main() {
        @Metadata(
                mv = {1, 4, 2},
                bv = {1, 0, 3},
                k = 1,
                d1 = {"\u0000!\n\u0000\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u000f\n\u0002\u0010\u000b\n\u0002\b\u0004*\u0001\u0000\b\u008a\b\u0018\u00002\u00020\u0001B!\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005\u0012\n\b\u0002\u0010\u0006\u001a\u0004\u0018\u00010\u0000¢\u0006\u0002\u0010\u0007J\t\u0010\u000f\u001a\u00020\u0003HÆ\u0003J\t\u0010\u0010\u001a\u00020\u0005HÆ\u0003J\u0010\u0010\u0011\u001a\u0004\u0018\u00010\u0000HÆ\u0003¢\u0006\u0002\u0010\u000bJ.\u0010\u0012\u001a\u00020\u00002\b\b\u0002\u0010\u0002\u001a\u00020\u00032\b\b\u0002\u0010\u0004\u001a\u00020\u00052\n\b\u0002\u0010\u0006\u001a\u0004\u0018\u00010\u0000HÆ\u0001¢\u0006\u0002\u0010\u0013J\u0013\u0010\u0014\u001a\u00020\u00152\b\u0010\u0016\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010\u0017\u001a\u00020\u0003HÖ\u0001J\t\u0010\u0018\u001a\u00020\u0005HÖ\u0001R\u0011\u0010\u0004\u001a\u00020\u0005¢\u0006\b\n\u0000\u001a\u0004\b\b\u0010\tR\u0015\u0010\u0006\u001a\u0004\u0018\u00010\u0000¢\u0006\n\n\u0002\u0010\f\u001a\u0004\b\n\u0010\u000bR\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\r\u0010\u000e¨\u0006\u0019"},
                d2 = {"kotlintojava/JanuszKt$main$Janusz", "", "x", "", "a", "", "j", "(ILjava/lang/String;Lkotlintojava/JanuszKt$main$Janusz;)V", "getA", "()Ljava/lang/String;", "getJ", "()Lkotlintojava/JanuszKt$main$Janusz;", "Lkotlintojava/JanuszKt$main$Janusz;", "getX", "()I", "component1", "component2", "component3", "copy", "(ILjava/lang/String;Lkotlintojava/JanuszKt$main$Janusz;)Lkotlintojava/JanuszKt$main$Janusz;", "equals", "", "other", "hashCode", "toString", "kotlinoweWisnie"}
        )
        final class Janusz {
            private final int x;
            @NotNull
            private final String a;
            @Nullable
            private final Janusz j;

            public final int getX() {
                return this.x;
            }

            @NotNull
            public final String getA() {
                return this.a;
            }

            @Nullable
            public final Janusz getJ() {
                return this.j;
            }

            public Janusz(int x, @NotNull String a, @Nullable Janusz j) {
                super();
                this.x = x;
                this.a = a;
                this.j = j;
            }

            // $FF: synthetic method
            public Janusz(int var1, String var2, Janusz var3, int var4, DefaultConstructorMarker var5) {
                if ((var4 & 4) != 0) {
                    var3 = (Janusz)null;
                }

                this(var1, var2, var3);
            }

            public final int component1() {
                return this.x;
            }

            @NotNull
            public final String component2() {
                return this.a;
            }

            @Nullable
            public final Janusz component3() {
                return this.j;
            }

            @NotNull
            public final Janusz copy(int x, @NotNull String a, @Nullable Janusz j) {
                Intrinsics.checkNotNullParameter(a, "a");
                return new Janusz(x, a, j);
            }

            // $FF: synthetic method
            public static Janusz copy$default(Janusz var0, int var1, String var2, Janusz var3, int var4, Object var5) {
                if ((var4 & 1) != 0) {
                    var1 = var0.x;
                }

                if ((var4 & 2) != 0) {
                    var2 = var0.a;
                }

                if ((var4 & 4) != 0) {
                    var3 = var0.j;
                }

                return var0.copy(var1, var2, var3);
            }

            @NotNull
            public String toString() {
                return "Janusz(x=" + this.x + ", a=" + this.a + ", j=" + this.j + ")";
            }

            public int hashCode() {
                int var10000 = this.x * 31;
                String var10001 = this.a;
                var10000 = (var10000 + (var10001 != null ? var10001.hashCode() : 0)) * 31;
                Janusz var1 = this.j;
                return var10000 + (var1 != null ? var1.hashCode() : 0);
            }

            public boolean equals(@Nullable Object var1) {
                if (this != var1) {
                    if (var1 instanceof Janusz) {
                        Janusz var2 = (Janusz)var1;
                        if (this.x == var2.x && Intrinsics.areEqual(this.a, var2.a) && Intrinsics.areEqual(this.j, var2.j)) {
                            return true;
                        }
                    }

                    return false;
                } else {
                    return true;
                }
            }
        }

        Janusz j1 = new Janusz(7, "Janusz", (Janusz)null, 4, (DefaultConstructorMarker)null);
        Janusz j2 = Janusz.copy$default(j1, 1, (String)null, (Janusz)null, 6, (Object)null);
        Janusz j3 = j2.copy(2, "NieJanusz", j2);
        boolean var3 = false;
        System.out.println(j3);
    }

    // $FF: synthetic method
    public static void main(String[] var0) {
        main();
    }
}

Lecą takie błędy:

/home/jarek/dev/wisnie/kotlinoweWisnie/src/main/java/javatokotlin/JanuszKt.java:5: error: DefaultConstructorMarker is not public in kotlin.jvm.internal; cannot be accessed from outside package
import kotlin.jvm.internal.DefaultConstructorMarker;
                          ^
/home/jarek/dev/wisnie/kotlinoweWisnie/src/main/java/javatokotlin/JanuszKt.java:56: error: DefaultConstructorMarker is not public in kotlin.jvm.internal; cannot be accessed from outside package
            public Janusz(int var1, String var2, Janusz var3, int var4, DefaultConstructorMarker var5) {
                                                                        ^
/home/jarek/dev/wisnie/kotlinoweWisnie/src/main/java/javatokotlin/JanuszKt.java:49: error: call to super must be first statement in constructor
                super();
                     ^
/home/jarek/dev/wisnie/kotlinoweWisnie/src/main/java/javatokotlin/JanuszKt.java:61: error: call to this must be first statement in constructor
                this(var1, var2, var3);
                    ^
/home/jarek/dev/wisnie/kotlinoweWisnie/src/main/java/javatokotlin/JanuszKt.java:85: error: Illegal static declaration in inner class Janusz
            public static Janusz copy$default(Janusz var0, int var1, String var2, Janusz var3, int var4, Object var5) {
                                 ^
  modifier 'static' is only allowed in constant variable declarations
/home/jarek/dev/wisnie/kotlinoweWisnie/src/main/java/javatokotlin/JanuszKt.java:130: error: DefaultConstructorMarker is not public in kotlin.jvm.internal; cannot be accessed from outside package
        Janusz j1 = new Janusz(7, "Janusz", (Janusz)null, 4, (DefaultConstructorMarker)null);
                                                              

Niestety nie da się tego łatwo załatać. Kotlin na poziomie bytecode korzysta z ficzerów, których nie da się zakodować w javie.

Jako ćwiczenie proponuję napisanie klasy w javie (z palca), która po przekonwertowaniu do kotlina (intellij-em, albo jakimś innym istniejący narzędziem) dałaby coś przypominającego początkowy kod w kotlinie. To w ramach pierwszego etapu.

W drugim etapie podeśle kod, który pokaże do czego służy component1, component2 itd.

Powodzenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1