П’ять причин, з яких вам варто використати Kotlin

Усі статті, обговорення, новини про Mobile — в одному місці. Підписуйтеся на телеграм-канал!

Всім привіт. Я Сергій Моренець, розробник, викладач, спікер та технічний письменник. Хочу поділитися з вами досвідом роботи з такою мовою програмування як Kotlin. Він уже став де-факто стандартом розробки мобільних додатків, аде для бекенд-проєктів його частка не така висока, але постійно зростає в останні роки. Особливість цієї мови в тому, що якщо ви, наприклад, пишете на Java, то можете використовувати її разом з Kotlin на одному проєкті. А це дозволяє еволюційно розвивати та покращувати ваш додаток.

У цій статті я хочу розповісти про ті фічі Kotlin, які дозволять вам писати більш простий, безпечний і читабельний код, при цьому пояснюючи, як це код буде компілюватися і працювати всередині JVM. Ну і за останні роки у нас накопичилося достатньо досвіду роботи з таким підходом, і ми розглядаємо ці технології на тренінгах з Kotlin. Сподіваюся, що ця стаття буде корисною для всіх, хто хоче дізнатися щось нове про ООП мови та підходи.

Kotlin та Java. Історія взаємин

Kotlin з’явився у 2011 році як продукт розробки компанії JetBrains. Це були темні часи для Java, коли тільки вийшла Java 7 з мінімальними змінами, а вся команда інженерів більше займалася переходом під крило Oracle, а не власне розробкою. Дві поспіль версії Java без серйозних покращень (6 і 7), а також довгі ітерації розробки (3-4 роки) змусили багатьох джавістів подумати про перехід іншими мовами, наприклад, Scala. Можливо, бажання зробити більш досконалу мову та уникнути помилок Java і лежало в основі рішення про створення нової мови програмування — Kotlin.

Додатки на Kotlin компілювалися в Java байт-код і запускалися на JVM, тому його не можна назвати «вбивцею Java», а скоріше «натуральною еволюцією Java». Багато фіч, які розробники довгі роки просили включити в Java, з’явилися ж у перших версіях Kotlin. Щоправда, «вбивцею Java» якоюсь мірою він став. У 2017 році (після виходу 1.0) компанія Google додала його підтримку для розробки під Android, а в 2019 році офіційно віддала йому перевагу перед Java.

Сьогодні Kotlin переріс тісні штанці JVM, ви можете компілювати його як у JavaScript (для фронт-енд додатків) або Kotlin Native (нативний код, що не вимагає віртуальної машини). Але головне для розробників Java — ви можете поєднувати Java/Kotlin код в одному проєкті, викликаючи з Java коду Kotlin функції, і навпаки.

Чи варто зараз переходити з Java на Kotlin? Ситуація значно змінилася з 2011 року і не можна говорити про помітну перевагу Kotlin або технологічне відставання Java. По-перше, у рамках проєктів Panama, Loom, Valhalla та багатьох інших Java поповнилася тими фічами, якими вже були в інших мовах програмування. По-друге, інженери Oracle перейшли на 6-місячний випуск нових версій, і це дозволило швидше отримувати фідбек від розробників і знайомити їх з новими фічами.

Тим не менш, реалізовані фічі — це надбудови (іноді синтаксичний цукор), а не ідеологічні зміни. Що робить Kotlin таким привабливим для розробників? Насамперед зміни в парадигмі програмування (в порівнянні з Java), включаючи:

  • Робота з null-значеннями.
  • Immutability.
  • Функціональне програмування.

І Java поки що відстає в цьому плані. Спробуємо розповісти про найбільш затребувані фічі, які роблять ваш код простішим, зрозумілішим і безпечнішим. Але перед тим, задля пристойності, перерахуємо ті фічі Java, які з’явилися з 2011 року і дозволили уповільнити відставання від Kotlin, де ця функціональність підтримувалася спочатку:

  1. Ключове слово var — з’явилося у Java 10 для локальних змінних, а потім у Java 11 для лямбда-виразів.
  2. Switch expressions — з’явилися в Java 14, в Kotlin відомі як when expressions.
  3. Текстові блоки — з’явилися у Java 15, у Kotlin відомі як multiline strings.
  4. Pattern matching for instanceof — з’явився у Java 16.
  5. Записи — з’явилися у Java 16, у Kotlin називаються data classes.
  6. Запечатані класи — з’явилися у Java 16.
  7. String templates — з’являться в Java 21.
  8. Record patterns — з’являться у Java 21.
  9. Безіменні класи та main методи — з’являться у Java 21.
  10. Pattern matching for switch — з’явиться в Java 21.

Список досить значний, але слід зазначити, що багато фіч були реалізовані на більш простому рівні, ніж у Kotlin, знову ж таки через обмеження Java. У будь-якому випадку їх не буде у нашому порівняльному огляді Kotlin, тому що ви вже можете використовувати їх у Java. Разом з тим у Java з’явилася велика кількість інфраструктурних змін (наприклад, нові збирачі сміття), які можете використовувати в Kotlin додатках.

Отже, 5 фіч Kotlin, які принаймні переконають вас розпочати його вивчення.

1. Компактність

Коли ви переходите з Java на Kotlin, ви починаєте банально писати менше коду, а значить і читати менше коду, економити свій час. Наприклад, коли ви тільки почнете знайомитися з Kotlin, вас може здивувати відсутність крапки коми в кінці рядка, але це дрібниця. Ви можете писати класи без тіла:

class Person

Можна писати однорядкові функції (без вказівки return):

fun add(x: Int, y: Int): Int = x + y

І можна навіть не вказувати тип, що повертається, якщо компілятор може його обчислити (type inference):

fun add(x: Int, y: Int) = x + y

Не потрібно вказувати new для створення об’єкта:

val amount = Amount(10.0)

До елементів колекцій можна звертатися як до масивів за допомогою квадратних дужок:

val numbers = listOf(1, 2, 3)
val elem = numbers[0]

Зникли звичні ключові слова extends і implements, їх замінила двокрапка:

interface Logger {
    fun log(message: String)
}
class ConsoleLogger: Logger {

Простіше описувати арифметичні операції за допомогою інтервалів:

if (i in 10..20) {

Постійний головний біль Java — неможливість використовувати два класи з однаковим ім’ям без явної вказівки пакета одного з них:

public static Date convert(Date date) {
    return new java.sql.Date(date.getTime());
}

Але в Kotlin можна перевизначити назву типу при імпорті:

import java.sql.Date as SqlDate

І позбутися надокучливого пакету:

fun convert(date: Date): Date {
    return SqlDate(date.time)
}

Часто в класах разом з оголошенням полів слідує їх ініціалізація в конструкторі. У Java для того, щоб прибрати цей boilerplate код, використовують анотації Lombok:

@RequiredArgsConstructor
class DefaultExecutor<T> implements Executor<T> {
    private final Executor<T> executor;

Але все одно код виходить трохи громіздким. У Kotlin запис буде ще коротшим за допомогою первинного конструктора:

class DefaultExecutor<T>(private val executor: Executor<T>)

Цей код, до речі, генерує як властивості, так і геттера/сеттера для класу.

І мій улюблений приклад — те, як у Kotlin реалізовано делегування. Дуже часто потрібно в класі реалізувати інтерфейс і разом з тим зберігати поле цього класу для того, щоб передати йому керування. Якщо методів в інтерфейсі багато, то виходить простирадло коду, в якому не дуже багато сенсу. У Kotlin є ключове слово by, яке реалізує все перераховане:

class DefaultExecutor<T>(private val executor: Executor<T>)
    : Executor<T> by executor

2. Безпечне програмування

Kotlin повинен був вирішити одну з головних проблем Java (і багатьох інших мов) — обробку null-значень. Хоча в Java 8 був доданий тип Optional, це повністю не вирішило цю проблему:

  • Optional рекомендується використовувати тільки для значень методів, що повертаються.
  • Створення великої кількості об’єктів Optional надає підвищене навантаження на JVM і збільшує витрати пам’яті.
  • Сама змінна Optional може бути null, а отже, викликати NullPointerExcep-tion.

В Kotlin можна використовувати тип Optional, але наврядчи хтось це робитиме, хіба що якщо працювати з наявним Java-кодом. Вся справа в тому, що в Kotlin при оголошенні вказується, що змінна може бути nullable за допомогою додавання запитання після типу:

val elem: String? = null

Відповідно, якщо ви захочете далі працювати з такою змінною в Java-стилі, це викличе помилку компілятора:

val length = elem.length

Тут потрібно або вказати знак питання після elem, щоб компілятор пропустив весь наступний код у разі null:

val length = elem?.length

Можна вказати оператор Elvis (за аналогією з Optional.orElse):

val length = elem?.length ?: 0

Або вказати !!, підкреслюючи, що значення ніколи не може бути null (аналог Option-al.orElseThrow в Java)

val length = elem!!.length

Таким чином, nullability змінної є частиною її типу і відстежується компілятором.

Ще один хороший приклад — відкладена реалізація. Якщо Java потрібно реалізувати інтерфейс з великою кількістю методів, то часто можна зустріти такий код:

@Override
public void execute(Runnable runnable) {
    // TODO implement
}

Потім про це забувають, а компілятор не може нагадати про цей технічний обов’язок. У Kotlin є спеціальний метод TODO, який викидає NotImplementedError, а значення такої функції, що повертається, — Nothing, що дозволяє відразу зрозуміти, що з нею не все в порядку:

class ConsoleLogger: Logger {
    override fun log(message: String): Nothing {
        TODO("Add implementation")
    }
}

3. Функціональне програмування

У Java 8 була зроблена серйозна робота для того, щоб розробники почали застосовувати функціональне програмування. По-перше, з’явились лямбда-вирази, які можуть замінити анонімні класи. З’явилися посилання на методи і, нарешті, Streams API, де обробка даних здійснюється шляхом виклику ланцюжка проміжних та термінальних функцій.

Але що ви не можете зробити в Java, так це написати просто функцію або передати функцію кудись. Навіть у випадку лямбд ви можете використовувати її тільки для функціонального інтерфейсу. У Kotlin ви можете просто написати функцію:

fun minus(x:Int, y: Int) = x - y

Зрозуміло, у Java байт-коді це буде обернуто до класу, але всі ці деталі ховаються Kotlin компілятором. Ви можете передати функцію як аргумент, і тут вже немає потреби використовувати функціональний інтерфейс.:

fun log(msg: String) = println(msg)
fun handle(msg: String, log: (msg: String) -> String) {
    log(msg);    
}

Як же вся ця магія працюватиме у JVM? У Kotlin SDK є інтерфейси з Function1 до Function22 (за кількістю аргументів), відповідно в байт-коді другий аргумент буде перетворено на об’єкт типу Function1:

public interface Function1<in P1, out R> : Function<R> {
    public operator fun invoke(p1: P1): R
}

Але це ще не все. Завдяки дефолтним значенням аргументів ви можете значно скоротити кількість методів. Якщо навіть взяти JDK і клас String, то можна зустріти два схожі методи:

public byte[] getBytes(Charset charset) {
public byte[] getBytes() {
   

Насправді вони відрізняються лише одним аргументом — кодування (charset). Якщо ви його не передали, то використовується дефолтний. У Kotlin можна обійтися однією функцією:

fun getBytes(charset: Charset = Charset.defaultCharset()): Array<Byte> {

Ще одна корисна фіча — іменовані аргументи у функціях. Коли у вас всі аргументи одного типу, дуже зручно вказати їх назви при виклику:

fun regexpMatches(msg: String, pattern: String): String {

щоб не заплутатися в порядку:

val matches = regexpMatches(msg = "ABCD", pattern = "[A-C]")

Особливо зручно це у data classes. Уявімо наступний клас:

data class Product(val name: String, val price: Double,
                   val description: String, val notes: String,
                   val weight: Double)

Серед властивостей цього є як і обов’язкові, так і опціональні, значення яких який не завжди відомі. У Java доводиться перевантажувати конструктори, щоб ініціалізувати опціональні аргументи, в Kotlin це завдання вирішується простіше за допомогою дефолтних значень.:

data class Product(val name: String, val price: Double,
    val description: String = "", val notes: String = "",
    val weight: Double = 0.0)

Уявімо, що ми хочемо клонувати об’єкт цього класу, але при цьому трохи його змінити. У Java метод clone() не підтримує такий API, доведеться реалізовувати патерн Builder, ускладнюючи код, тоді як у Kotlin це виглядає просто і витончено завдяки іменованим параметрам:

val product = Product("PC", 1000.0)
val copy = product.copy(price = 1200.0)

4. Immutability

ООП стоїть на трьох китах: інкапсуляція, поліморфізм, успадкування. Іноді до списку додають абстракцію. Інкапсуляція є дуже важливою для безпеки наших даних. Невипадково рекомендують поля класів робити за замовчанням private (як і методи). Проте у Java локальні змінні та аргументи методів не захищені від повторного присвоєння.

У Kotlin все набагато суворіше. По-перше, аргументи функцій насправді є final і захищені від повторного присвоювання. По-друге, коли ви оголошуєте локальну змінну або поле класу, ви повинні вказати, чи вона змінюється чи ні (за допомогою ключових слів var/val). Таким чином, розробник не може «забути» про це, як він може забути поставити final в Java.

Принцип «composition over inheritance» каже нам, що краще використовувати композицію класів, а не об’єднувати в ієрархії. У Java класи за замовчуванням не захищені від успадкування, якщо не поставити модифікатор final.

У Kotlin же ситуація зворотна. Будь-який клас є за замовчуванням final, і потрібно спеціально додати модифікатор open для його відкриття:

open class Employee {
    fun getCategory() = "Employee"
}
class Developer() : Employee() {
    
}

Тим не менш, навіть у цьому випадку всі функції в класі Employee є final і для їх перевизначення потрібно також додати модифікатор open:

open class Employee {
    open fun getCategory() = "Employee"
}

А в класі-спадкоємці ще й обов’язкове ключове слово override:

class Developer() : Employee() {
    override fun getCategory() = "Developer"
}

Це дуже важливо, тому що в Java анотація @Override є опціональною, а її відсутність може призвести до проблем.

Одна з найбільших проблем Java — відсутість API для immutable колекцій, хоча самі такі колекції існують:

List<String> numbers = Arrays.asList("1", "2");
List<String> numbers = List.of("1", "2");

На жаль, але тут в останні роки та десятиліття немає покращень. І якщо ви передаєте в інший метод змінні List, Set або Map, то в ньому ніяк не можна визначити, чи ця колекція змінюється, хіба що спробувати щось змінити (отримавши виняток).

У Kotlin було дуже грамотно реалізовано ієрархію колекцій. У ній List, Collection, Set — це типи для незмінних колекцій, які спадкоємці — MutableList, MutableCollection, MutableSet — типи змінюваних. Це відразу дозволило вирішити багато фундаментальних проблем Java.

При переході з Java деякі речі можуть бути незвичними. Наприклад, в Java для сортування списків є метод sort(). Для MutableList він і залишився, а ось для immutable колекцій його не можна застосувати, зате з’явився метод sorted (), який повертає новий відсортований список. Тобто для однієї операції є два методи, які різняться за типом (змінністю) колекції.

5. Extensions

Одне з найпоширеніших завдань у програмуванні — це розширення функціональності чинного юніта. Його можна вирішити зміною або спадкуванням такого юніту. Але що якщо він (клас) final, а вихідники нам недоступні? Доводиться створювати нові утилітні класи, які беруть він це завдання. У Kotlin це можна зробити набагато простіше. Наприклад, потрібно додати метод, який повертає рядок випадкових символів:

fun String.random(size: Int): String {

Ми декларуємо та використовуємо цю функцію так, ніби вона поміщена до класу String:

val randomText = "".random(10)

Зрозуміло, Kotlin компілятор не змінює байт-код JDK, він просто створює нову функцію, яка приймає першим аргументом той об’єкт, який ми використовуємо, а потім усі аргументи виклику:

fun random(string: String, size: Int) {

Так само і з інтерфейсами:

interface Logger {
    fun log(message: String)
}

Ви можете додати до нього будь-яку функцію, але вона має бути дефолтною:

fun Logger.log(message: String, level: Level) = println("$level.$message")

Абстрактні методи додавати не можна:

fun Logger.log(message: String, level: Level)

Якщо ви додаєте метод для класу і в ньому хочете використовувати його приватні властивості:

class DatabaseLogger(private val dbName: String, private val server: String) : Logger {
 
fun DatabaseLogger.log(message: String, level: Level) {
    println(dbName)    
}

Такий код не компілюватиметься, оскільки компілятор спробує звернутися до приватної властивості ззовні його об’єкта (що заборонено)

fun log(logger: DatabaseLogger, level: Level) {
    println(logger.dbName)
}

Тут потрібно або змінювати модифікатор видимості, або створювати окремі гетери. Ну і приклад, який комусь може здатися вищим пілотажем. Уявімо, що у вас є перелік:

enum class Season {
    WINTER, SPRING, SUMMER, AUTUMN
}

Вам потрібен універсальний метод, який зможе поєднати всі його значення. Але потім вам здалося гарною ідеєю додати метод не в Season, а створити його для всіх класів-перерахувань. Немає нічого простішого. Ви додаєте метод join у тип KClass (аналог Class у Java), при цьому вказуючи, що метод буде доступний тільки для тих класів, які успадковують клас Enum (тобто перерахувань):

 fun <T : Enum<*>> KClass<T>.join(): String {
    return this.java
        .enumConstants.joinToString { e -> e.name }
}

І потім використовуєте його у будь-якому перерахуванні:

val text = Season::class.join()

Висновки

Як ви бачите, функціональність Kotlin багатша за Java, адже ми не розглянули ті його фічі, які спочатку були перевагою Kotlin, але потім були перенесені в Java в останні 12 років. І ще одна перевага, яка не виділена окремо, але постійно згадувалася в цій статті — можливість використовувати Java код у проєктах Kotlin і навпаки. Це дозволяє гармонійно поєднувати Java та Kotlin код в одному додатку без будь-яких серйозних колізій.

👍ПодобаєтьсяСподобалось13
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Я не маю нічого проти Котлін і використовую Котлін або Джава залежно від вимог проекту, але це дивно спостерігати рекламу Котлін. Майже у всіх дискусіях на Реддіті присутні персонажі які доречно і не до речі згадують Котлін і пропонують перейти на нього. Це вже викликає усмішку :-) Хто б так Го рекламував для мікросервісів!!

Ну, якщо ти писав на Java, то Kotlin дійсно полегшує багато речей, тому і такий хайп.

крауд маркетинг ?

Раст також дуже часто згадують. І як на мене досить не в тему.

Все це вже давно є в Scala. Чим Kotlin кращий за Scala?

Тут більше питання чим Scala краща за Котлін? За майже всіма аспектами гірша.

— Армяне все равно лучше чем грузины!
— Ну чэм они лучше, чэм?!
— Чэм грузины.

Всем лучше — областью применения, разработчиками, перспективами.

На доу вакансій, де згадується Scala аж 5 штук. Якщо брати чисту скалу то 2. Нормальні такі перспективи:)

Як мінімум:
-Чудова інтеграція з іде.
-зрозуміла і доступна білд система.
-Сумісність версій мови.
-краща інтеграція із жабкою (особливо зворотня інтеграція)
-відсутність імплісітів і інших фіч синтаксису, що можна зробити код проекту непридатний для підтримки.
-Кращий перформанс.

Маю великий досвід використання альтернативної мови програмування у галузі, де багато років панують інші інструменти. Що постійно довелося долати:

1. Коли виникає проблема і ти шукаєш рішення в інтернеті, пошуковик наполегливо ігнорує нерелевантне з його т.з. слово (назву альтернативної мови) навіть якщо воно в лапках. Видає тобі мільйон посилань, де проблема вирішується базовою мовою, а не твоєю. Сильно бісить.

2. Якщо знайшов баг в інструментарії, виправляти чи шукати воркароунд доведеться самотужки, бо в карликовому ком’юніті з цим ще ніхто із активних юзерів не стикався. А усі три мейтейнера проекту саме зараз зайняті здачею сесії.

3. Біндінги до API нейтівних ліб не повні, відстають на декілька версій, подекуди сильно забаговані.

4. Через різницю підходів взаємодія із нейтівними класами часто потребує неочевидних і багатострокових акробатичних етюдів. В результаті витрачаєш години і дні на те, що «конформісти» роблять за п’ять хвилин десятком рядків коду.

5. Докумунтація майже гарантовано буде дуже слабка порівняно із «рідною» мовою та її лібами. Часто буде просто написано, що метод selectNeighbour(level) «дозволяє обрати сусіда». Якого сусіда? Навіщо його обирати? Що таке level? Розбирайся сам по коду метода чи тиком.

6. Якщо мова про компілятор, він скоріше за все буде давати набагато менш оптимальний машинний код.

7. Тобі просто немає про що говорити із колегами по галузі, що використовують нейтівні інструменти. А технічні інтерв’юери на співбесідах мають дивний вираз обличчя.

Я в жодному разі не наполягаю, що все це можна сказати про сабж, просто досвід із зовсім іншої галузі.

А з якої саме галузі, і про які мови йдеться?

Декілька було.
iOS+Xamarin (2013 рік, тоді все було сильно гірше ніж зараз)
dotNET+Oxygen
WebAssembly+PureC

Я ще розумію коли Kotlin використовують для андроід розробки, але навіщо давати росіянам компілювати свій код для всіх інших технологій мені взагалі не зрозуміло.

Тим більше що основну проблему джави — алокацію на кучі — він аж ніяк не вирішує, тому в продакшені доведеться так само як і раніше длубатися з GC і мати паузи по 50мс якщо хочеться хоч щось закешувати.

А замість синтаксичного цукру я піду краще тістечко в найближчий кав’ярні з’їм.

А замість синтаксичного цукру я піду краще тістечко в найближчий кав’ярні з’їм.

Не підете, бо будете як дурень писати гетери/сетери та тести на них.
Усі тістечка з’їсть ваш ПМ.

А POJO ще хтось згадує, чи це вже не актуально?

Я колупався в JVM останній (надіюся, що не крайній) раз в 2013-му, робив дічь з CPS

то мені ШІ напише і гетери і сетери і тести до них
Немає цієї проблеми у Java.
verbosity це типу велика проблема для бекенду.

думаю, у вас з бекендом ніяких проблем взагалі нема, бо вам ШІ і гроші заробе

Закопайте вже нарешті стюардесу.

Ми використовуємо kotlin на server side.

І для цього є єдина причина: корутини.
Це дуже велика killing feature. Яка в Java відсутня. Project Loom обіцяє альтернативу. Але це трохи інше і ще не пробували його в проектах.

Далі я б вказав null safety, string interpolation та equals в String.

Решта фіч теж цікаві ... але тут я б почав перераховувати недоліки.

1. Погана підтримка java modules. Ця штука вже є з java 9. І я, якщо чесно, очікував, що всі великі важливі бібліотеки це будуть підтримувати. Не впевнений що там зараз, але коли я останній раз дивився ktor — він не працював з java modules. Чому? Хз ... напевно, тому що ліньки порефакторити і випустити для цього мажорний реліз.

2. Той самий ktor ... давайте подивимось приклад:
github.com/...​FileListingApplication.kt
Подивіться стрічки 30-40 та 45-161. З моєї суб’єктивної точки зору, навіть якщо мова програмування дозволяє таке писати — то це точно антипаттерн і йому не місце в офіційних семплах. Такий стиль дуже схожий на зловживання define-ами в C, C++. Воно виглядає гарно. І можна навіть здогадатись що воно робить. Але що конкретно відбувається (в якого об’єкту і що викликається) — абсолютно не ясно. Тобто щоб зрозуміти що тут написано треба не просто знати котлін. Потрібно вивчати також «псевдомову» кожного конкретного фреймворку.

3. Чомусь Kotlin позиціонуть як щось для розробки під Android. Це трохи дивно. Це те ж саме, що сказати, що Java — це розробка під Android )) Це я до того, що Kotlin не зав’язаний на мобілках і може використовуватись кругом де і Java.

4. Статичні методи як companion object — це відверто дивне рішення.

В цілому, додати б в Java корутини та null-safety, і вагомих причин працювати з котліном майже не залишиться.

В цілому, додати б в Java корутини та null-safety, і вагомих причин працювати з котліном майже не залишиться.

Перше Project Loom вже фактично зробив найкращим чином.
Друге не вважаю скільки-небудь критичним.

Друге не вважаю скільки-небудь критичним.

Я б з вами погодився ... але тут є до певної міри справа звички. Зараз якийсь час вже працюю з Dart. Там відносно нещодавно впровадили null safety схожим чином як в котліні. Міграція там була дууже масштабна (це трохи біль). Але після досвіду використання такого підходу, коли повертаєшся до проекту на Java, відсутність такого механізму «дуже чешиться».

В цілому, я слабо собі уявляю nullable типи в Java (занадто багато міняти). З іншої сторони, не бачу жодної проблеми зробити оператори ?? та ?. — це легко зробити, і значно спростило б життя.

З іншої сторони, не бачу жодної проблеми зробити оператори ?? та ?.

Так справа не в операторі. А в налл сейфеті — шоб компілятор не дозволяв налл де це не можна — цього в жвбі не зроблять хочаб із причин сумісності.

Я, власне, це і мав на увазі, що null safety — там проблема.

Про оператори — це я про про те, що їх додати легко, і хоч null safety це не зробить, але код стане значно чистішим.

По 4 пункту, зараз відбувається активна дискусія в ком’юніті котліну на рахунок додавання в мову підтримки «адекватної» статики у вигляді або static-блоків (схоже по синтаксису до init-блоків, чи тих же companion), або ж у вигляді ключового слова static, як це зроблено у тій же джаві

Подивіться стрічки 30-40 та 45-161. З моєї суб’єктивної точки зору, навіть якщо мова програмування дозволяє таке писати — то це точно антипаттерн і йому не місце в офіційних семплах.

Так а шо не так? лайтовий дсль для раутінгу. ВИмагає знати котлін: kotlinlang.org/...​s/type-safe-builders.html А не з жабки фігак фігак і в прадакшен. Але це значно краще ніж наприклад люблять робити в тій самій скалі в якійсь акка-хттп

Насправді, оці поінти та холівари на рахунок яка мова чи фреймворк вирішуються дуже просто: на якій мові вести розробку бізнесу дешевше, та і буде популярніша, чи то навіть краще. Наприклад взяти той же Rust, який всім наче дуже подобається але спеціалістів та проектів відносно небагато, тому спеціалісти дорогі, а той же С/С++ через величезну кількість проектів та навчальних матеріалів поки що популярніше.

P.S. Питання чого в Котліні може випасти NullPointerException для типу, який не позначений як Nullable одне з найпоширеніших на співбесідах. Причому там навіть не треба дуже складних маніпуляцій з кодом.

Kotlin > Java
Впадлу розписувати чому саме. Повірте на слово.

Не вірим. Бо лажа. Котлін вмре.

Ще би зрозуміти що означає

Kotlin > Java

А чому то вже пофіг

Ще би зрозуміти що означає

Kotlin > Java

assertTrue( "Kotlin" > "Java" )

Ще би зрозуміти що означає

Kotlin > Java
А чому то вже пофіг

За кількістю літер

Це означає, що після котліна перейдеш до джави :) Повір на слово ;)

Добре що я котлін і не пробував 😅

«Це вже було» © :) На справді вже проходили теж саме десь років 8 тому зі Scala. Власне від чого і пішли Swift та Kotlin.
Як там не було, а все ж таки Kotlin трішки інакше компілюжться у байткод. Конкаренсі має інший (Coroutines). Якщо правильно використувати Lombok — то нічого і виграється.
Мабуть, що nullable тип у Kotlin — це його добра риса, чого не має у самій Java. В решту решт — є анотації та валідації.
Як на мене — то якщо буде якийсь стандарт, тоді це буде мати сенс — але його не буде. Тому що кожна компанія розвиває свій тулкіт і PL.

В Java років зі 5 використовують Optional монаду замість повертати null в тих випадках коли значення не знайдено. NPE став траплятись вже дуже рідко. Ну а ключова проблема OutOfMemory — однакова як для Java так і для Kotlin, жодної різниці.

Optinal — це все ж таки не на рівні мови :) На приклад — мені так, достатньо саме цього.
Зараз я б сказав, що більше навіть все залежить не від PL, а від тулінгу для асінхроного процесингу даних. Саме це було слабким мцсцем у С++. Зараз усі більш менш відомі мови вже мають Rx імплемнтації. Java навіть ще має мачурний Reactor.

На рівні стандартної бібліотеки. При бажанні можна хоч на C не повертати NIL значення з будь якого API який не гарантує, що буде наявний результат. Скажімо SQL запит не повернув жодного результату. Коли повертається якийсь об’єкт чи структура, а не NULL — доволі важко забути, що так може бути і не вставити NIL чек логіку в код. От тут функціональний підхід, показав перевагу над імперативним. А коли йдеться про серверні застосунки, тот тут такого повно. А так воно навіть java util.Map на методі get досі повертає null якщо нема значення в хеш таблиці. Той же С++ unordered_map повертає iterator, подобається — не подобається вставляй перевірку і логіку обробки такої ситуації.

угу... асинхронка вилядає красиво якщо не заглиблюватись в деталі...
результат flatmap полетів запитами в другий мікросервіс, той на кожен запит зробив те саме на ще два, все це полетіло в пятий-шостий... гей, хто схавав всі процесорні ядра, чому треди висять, що там у вас відбувається?! все нормально, от щаз ми подебажимо стек викликів і розберемось. ото треба трохи потюнити шедулери, поставити обмеження і все буде ок. а можна було просто зробити фіксований пул потоків і напряму?... ні-ні-ні, це не по феншую
памятаю як мені один адепт реактивщини доказував що не можна робити blocking() навіть якщо очікуваний результат всього одне значення.

Все норм там працює, якщо розуміти, що робиш. Проблема раніше була в тому, що не всі леєра підтримували асинхронність. Тобто, якщо сервлет блокуючий, чи драйвер DB, то тут нема що казати. Тому всі йшли старим шляхом. Але, коли все вже підтримую починаючи від Netty ф асихронним драйвером — все має працювати. Стосовно блокуючих викликів — це говорить про помилки в архітектурі. Тому і був розроблений Rector (WebFlux), звісно, що і Security був допрацьований для підтримки цього стеку.

вже мають Rx імплемнтації. Java навіть ще має мачурний Reactor.

З широким адопшном віртуальних тредів реактивщина в джаві вмре як непотрібний атавізм, яким реактивщина і є.

Я б вам рекомендував ще раз переглянути базові патерни проєетування і спробувати зрозуміти, на базі пари яких вся ця ідея побудована. До того що вмре. Проблема в тому, що рективність — це не про швидкість, а про ресурси і систему обміну даними між потоками. Вже проведені певні дослідження і доказано, що рективна система краще тримає навантаження. Як джерело — достатньо відкрити першу главу RxJava Т. Нуркевича, де є чіткі графіки. Стосовно віртуальних тредів — які б вони не було, все рівно вони не є сферичним конем в вакуумі, а це значить, що будуть використувувати певний ресурс, як памʼять. Так, не мапяться на системні потоки OS (які все ж таки обменжені), але... все рівно буде привʼязка — потік — реквест, це означає, що якась I/O операція його заблокує до моменту отримання результату. В реактивній системі — нічого не блокується, а просто очікується результат. Система піша далі виконувати свої задачі.

А, давно я ту фігню читав, але смутно пам’ятаю те порівняння. Спочатку вони чомусь порівнювали два різна апплікейшн сервери (Netty i Tomcat), незрозуміло чому приписавши кращий перформанс Netty реактивному підходу. Я ще подумав чому не порівняти RxNetty з просто Netty. Але потім вони порівнювали різні підходи до імплементації, де порівнювали RxNetty vs Netty vs ... І, наскільки памятаю у RxNetty був менший перформанс чим у просто Netty. Найбільше я сміявся коли виявилось що їх тестова ThreadPool імплементація показала хороші результати, причому там схоже був статичний треадпул без keepalive. Вони тоді якось з’їхали з теми, здається.

що рективна система краще тримає навантаження.

При бажанні я так само зможу знайти купу синтетичних тестів, які покажуть що навпаки система з синхронними потоками дає кращій результат, за рахунок меншої витрати ресурсів на своє підтримання зокрема пам’яті, а пишеться вона в рази швидше, набагато простіше підтримується і суттєво простіше модифікується. Тобто усе відносно задачі яка стоїть. Реактивність не завжди є виправданою, але це не відміняє тих випадків коли вона виправдана.

Можете написати тести і привести результати, може тоді у вас буде можливість опублікувати і довести всім іншим, що праві саме ви.
Я ж поки що скажу ось що.
Mobile — SwiftUI, Combine — Rx підхід,
Android — на приклад Retrifit — підтримує і Rx і Coroutines плюс багато інших фреймворків, рекомендовано Rx,
Angular — RxJS — це вже саме за себе говорить.
Back — Java — для навантажень рекомендується теж саме — Rx, нарешті допрацьований для відповідальної підтримки, тобто драйвер баз даних — асинхроний, сервлет теж саме.
Тобто західні інженери виглядають, як недолугі? :) Ага :)

Analysing the performance and costs of reactive programming ... inria.hal.science/hal-03409277/document Та от подивіться самі, існуючи досліди. Там в кінці виходить, що взагалі нема жодної різниці по перформансу, що класичний імперативний стиль, що функціональний «реактивний». Функціональний стиль за рахунок стейлесс в своїй природі простіше скейлится горизонтально просто, тільки і усього. Та оцей скейлінг — може бути дуже суттєвою проблемою для імперативного стиля. Чому він був тоді такий розповсюджений, а тепер визнаний не модним ? Усе просто діяв закон Мура і була можливість скейлитись горизонтально, коли кожні пів року випускали електроніку яка в двічі переважала попередню за обчислювальними потужностями. В таких умовах софт треба писати не добре — а швидко, щоб встигнути на ринок. Але лавочка прикрилась, бо рахунок техпроцессів пішов на меньше 10 нанометрів, що вже дуже дорого і доволі довго. От тепер пішли в горизонтальне масштабування і відповідно функціональні підходи стали модними. Разом з цим різні NoSQL і т.д. і т.п. Усе це нове — добре забуте старе, ще з 50-60 років минулого сторіччя в іншій обробці. Можете подивитись на LISP — і побачите, що він весь «реактивний».

За док дякую, почитаю. У функціонального підходу є два дробека, це скейлінг і власне — нема бескінцевої памʼяті, тобто треба розглядати комбінований підхід. І все ж таки Rx — не вважається чистим функціональних підходом.
Про добре і швидко — знову, залежить від певних обставин. Для стартапа — так, важливіше швидше написати, навіть якщо мати потім посередньої якості код. Але якщо вже більш менш зрозуміло, то тут як раз важливіше правильні підходи. Я бачив деякі проєкти, які були швидко зроблені та продані. Але потім їх сапорт виходив для замовника дуже дорого, і власне — в деяких просто відмовлялись його якось розвивати.

Але потім їх сапорт виходив для замовника дуже дорого

Хто зараз сапортить наприклад PalmOS, або Symbian? Це бізнес стратегія така. Все було розраховане не те, що скажімо через два роки все одно прийдеться писати повністю нове бо в старому взагалі не буде жодного сенсу. Тенденція коли розробка софта коштує суттєво більше за хард, не настільки вже і стара. Взагалі-то початкова ідея була в тому, що буде навпаки.

Що стосується PalmOS — то тут я вже не памʼятаю в чому була трабла. А ось Symbian — просто закрили через те, що Microsoft викупив Nokia і вони перейшли на WinPhone з підтримкою .Net, для того часу була норм система, деякі компанії ії ставили, але все ж таки Android і iOS переграли. Що стосується розробки софта — ось на мобайлі намагаються зробити певні гібриди, які в дійсності більш нагадують Франкенштейнів. А все потому — що не має стандарта і його не буде, тому що... ведучі компанії розвивають свої мовb і фреймворки. Колись був єдиним C++, але Apple все рівно застосовував Objective-C (як на мене простіша і потужна мова) на той час поховали Carbon, пізніше — подивившись, що коїться зі стандартом С++ — так і продовжили, склепав Swift та вже поховали той Objective-C. Щодо беку — все впирається в розподіленість і підходи. Раніше достатньо було написати аплікацію і розгорнути на премісис сервері. Зараз — це ціле діло. Kubernetes, AWS, GCP, Azure — і всі зі своіми підходами, DevOps, плюс більш менш належне тестування.

плюс більш менш належне тестування

угу, саме тому зараз продукти в статусі який раніше було соромно назвати бетою, викатуються на прод і потім ітеративно фіксяться, а юзери виступають в ролі бета-тестерів. ))
Але позитив, звичайно, є — в зв’язку з цим приходиться/навчились оперативно усувати факапи, а не чекати по пів року поки вийде нова версія де може якісь баги пофіксили.

>>

Усе просто діяв закон Мура і була можливість скейлитись горизонтально

Напевне малося на увазі «вертикально»

З широким адопшном віртуальних тредів реактивщина

Так корутини, вони же файбери якраз і треба для ріактівщіни. За великим рахунком розподілення задач на тредпул. В чому сенс — нівелювати затримки при оркестрації чи хореографії в гетерогенній системі, та головне мінімізувати простої потоків при запитах до баз даних, що якраз і дає можливість витримувати більше навантаження по одночасно пацючим клієнтам. Щоправда із береженням золотого правила — виграєш в швидкості, програєш в пам’яті.

За великим рахунком розподілення задач на тредпул.

Так от.
Віртуальні треди обнулили саму необхідність мати пули тредів.
Це великими жирними літерами написано в кожному толковому гайді по віртуальним потокам — створення і підтримка всього віртуального треду нині дешевша навіть ніж утримування самого пулу і його оркестрація.

А тепер, те, чого деякі тут не зрозуміли — якщо у вас операція new VirtualThread(runnable) дешевше ніж підтримка пулу, це означає що вся всрата піраміда сабскрайберів, моно, вебфлаксів і всієї цієї реактивної лабуди втрачає сенс, бо її рантайм-оверхед набагато дорожчий ніж створення віртуальних тредів в будь-якій бажаній точці програми.

Якщо раніше той же томкат тред пул стандартного розміру 200 мав цілком зрозумілий ліміт і мало сенс виносити обчислення/очікування в інші потоки, то тепер всі ці 20-річні підходи втратили сенс, бо «пул» томкату став лише фасадом, який для кожного нового запиту тупо створює new VirtualThread(application) і цих тредів можуть одночасно в його «пулі» існувать мільони, бо «пул» став просто фабрикою. Це обнуляє необхідність танців з реактивщиною, бо очікування віртуального треда в JVM тепер є умовно-безкоштовним.

і всієї цієї реактивної лабуди втрачає сенс, бо її рантайм-оверхед набагато дорожчий ніж створення віртуальних тредів в будь-якій бажаній точці програми.

ключава проблема там не у рантаймі а у девелоп таймі

мало хто вміє у багато поточний код це саме як принцип від слова взагалі

зокрема 99.99% «багато поточного коду» це просто послідовний де факто код дуже прискіпливо «закритий» мютексами ну а що він же ж може виконуватися у багато поточному середовищі у сенсі що він буде виконуватися правильно без ні яких race conditions а те що при цьому він буде просто послідовним ну але ж спершу він багато поточний все же ж чесно? ))

тож питання багато поточності у більшості випадків плутається за питанням асінхронності який у сучасному світі здебільшого task based

бо «пул» томкату став лише фасадом, який для кожного нового запиту тупо створює new VirtualThread(application) і цих тредів можуть одночасно в його «пулі» існувать мільони

тож ключовим питанням стала саме взаємодія між цими мільйонами тредів у досягенні ними більше менш пристойної асинхронності (що є не блокування окремого треду у запиті до фасаду) а також більш менш коефіціенту корисної дії у використанні усіх тіх сучасних ядер великих і малих сучасного cpu

усе це так само проблема у девелоп таймі бо «ккд» девелоп тайму лишився у кращому випадку тим самим (див. п.п. «мало хто вміє у багато поточний код це саме як принцип від слова взагалі») а у більш статистично вірному різко погіршився згідно росту числа яке як відомо не приводить до росту сумарного інтелекту

Ну мало хто, вже далеко не мало хто, а доволі багато хто. Це може років з 10 тому, це усе було справді гік онлі. LISP існує доволі давно, практично так само довго як і FORTRAN. Технічно нічого складного нема, просто перший час ломає мозок, як тому першокурснику з подвійним циклом, потім настає — «Евріка!». Ну звісно є усілякі OpenMP та тому подібне, типу корутин, що дозволяє комбінувати обидва підходи.

А тепер, те, чого деякі тут не зрозуміли — якщо у вас операція new VirtualThread(runnable) дешевше ніж підтримка пулу, це означає що вся всрата піраміда сабскрайберів, моно, вебфлаксів і всієї цієї реактивної лабуди втрачає сенс, бо її рантайм-оверхед набагато дорожчий ніж створення віртуальних тредів в будь-якій бажаній точці програми.

мені подобається «девелоп тайм» такого штибу

pbs.twimg.com/...​media/E3edeNnVgAI4ZCV.jpg

(потім якось перепишу текстом)

бо я якось мав справу саме з кешами саме з «асінхронними» як то «багато поточними» при чому ще й «віртуально поточними» то я маю визнати мене цей клятий код чітко тригерить до не стями бо цей клятий код робить тупо усе ))

мені подобається «девелоп тайм» такого штибу

Я шось ніхєра не поняв шо ти мав на увазі.

Код на скріні мені не дуже зрозумілий, тому мабуть і не поняв.
І до чого тут джавівські віртуальні треди теж не поняв.

Код на скріні мені не дуже зрозумілий, тому мабуть і не поняв.

гиги але ж це круто! то давай предметно бо код же ж крутий а що саме тобі з коду не зрозуміло?

... зараз таки перекняпаю його у текст...

actor ImageDownloader {

	private enum CacheEntry {
		case inProgress(Task.Handle<Image, Error>)
		case ready(Image)
	}

	private var cache: [URL: CacheEntry] = [:]

	func image(from url: URL) async throw -> Image? {
		if let cached = cache[url] {
			switch cached {
			case .ready(let image):
				return image
			case .inProgress(let handle):
				return try await handle.get()
			}
		}

		let handle = async {
			try await downloadImage(from: url)
		}

		cache[url] = .inProgress(handle)

		do {
			let image try await handle.get()
			cache[url] = .ready(image)
			return image
		} catch {
			cache[url] = nil
			throw error
		}
	}
}

Бро, я джавіст ) мені незрозумілі конструкції типу

= [:]
case .
] = .
і якщо чесно не дуже то й хочеться.
і якщо чесно не дуже то й хочеться.

це просто синтаксичний цукор але так я бачу про що ти тож я тебе зрозумів

... ми якраз оце днями балакали про це тільки про новий синтаксис вже сі++20/23 там з таким «цукром» вийшло багато складніше як на мене але в принципі осягнути можна знову же ж таки як на мене але думка візаві було щось «а уяви як на цей код дивиться людина яка завжди писала тільки на сі++03» то я таки напружився і уявив ))

... власне я з таким маю справу останні роки або вже може десятки років )) це власне навіть вигадав не я бо не я вигадав «справжній програміст на фортрані може на будь якій мові писати як на фортрані»

колись тоді коли я вперше почув то тоді це було кумедно але не більше вже потім вже «з досвіду» я почав вже розуміти

доречі як на мене той самий сі++ потрапив у цю пастку як на мене вони не змогли збудувати реальний місток (а точніше навіть мости) між тим самим «девелоп тайм» та тим самим рантайм на якому власне досі більшість усього існуючого і написане

от аппле скажімо змогли на стільки що не надто соромилися і вигадати той objective-c

(йошкін код метод об’єкту є просто можливістю відправити цьому об’єкту повідомлення як функцію з параметрами а-а-а не сішний ооп!!! )))

... так і постійно «губити» зворотню сумісність власного коду та й власне власних апі та операційних систем

ну або просто вигадати той самий свіфт коли той самий «девелоп тайм» почав погано «поміщатися» у сучасність ))

і якщо чесно не дуже то й хочеться.

але так загалом то є сумно (( тут я поки що сам для себе не сформулював точно що і як саме ну тобто загалом «сумно що люди лишаються у минулому» але як саме то є сумно і що з цього виходить а х.з.

ЗЫ: а що справді навіть трохи не цікаво? ((

а що справді навіть трохи не цікаво? ((

Нє ну трохи цікаво але на рівні «нащо було видумувать такий трешовий синтаксис».

Я взагалі прихильник verbose, але explicit, тому всі оці єрогліфи дрєвніх які не читаються як текст або не є інтуітивно зрозумілими як -> вважаю злом. Нє чітал но асуждаю. Так само як і скорочення типу «fun» «func» і тому подібне.

всім прихильникам мінімалізму раджу Brainfuck ))

я коли бачу скорочення func або fun то завжди згадую напіванекдот про те як науковці просять програмістів не скорочувати слово analyze до anal.

Kotlin це правильна java, але окрім самого синтаксису kotlin це платформа — не потрібно вчити groovy щоб писати gradle скрипти, не потрібен xml в ui бо kotlin dsl робить це краще, кросплатформений ui framework для android, desktop, web, ios з нативним луком — ніхто до цього не робив настільки крутого, сподіваюсь що kotlin посуне electron застосунки бо це просто неможливо коли текстовий редактор жере більше ніж раніше операційна система з повним офісом разом

Це мови з різними парадигмами. Java чітко імперативна, об’єктно орієнтовна мова з строгою системою типів. Так це мова розроблена якраз для створення графічного інтерфейсу користувача, в самий бум глобального розповсюдження GUI. Оскільки була розроблена революційна на свій час система розширення функціональності Web сторінок через додачу інтерактивного контенту Applet і доставки програм Java Web Start — тепер це JavaFX, що провалилась на ринку, Java зайняла ніши, для яких вона за великим рахунком ніколи не розроблялась і насправді не так вже і підходе, за багатьма параметрами. Щоправда технологія інтерпретації байткоду — дозволила утворити нову парадигму — мета програмування та аспект орієнтовне декларативне програмування. Народились ідеї Dependency Injection — та фреймверки типу JEE, Apache Struts, JBoss Hibernate та Spring. А який Frontend тепер до Spring, Java чи Kotlin, не так вже і важливо. Сама мова Java теж еволюційно змінилась, починаючи з 8-ї версії, вона більше нагадує вже якийсь Haskel з чисто функціональним стилем програмування, що значно краще підходить для програмування серверної web логіки, ніж класичний імперативний стиль. Goroovy та Scala — якраз додавали той самий функціональний стиль до JVM ще в нульові. Kotlin це інше намагання привнести Perl та Python синтаксис до JVM, от його зараз додають активно і до нових версій Java.

>>Java мова для створення графічного інтерфейсу
давно так не сміявся, ви певно не програмували на awt, swing, j2me — стільки страждань для побудови ui я ніде не бачив. Kotlin відкрив можливість робити ui as code, configuration as code, тільки зараз писати під андроїд стало комфортно, а при мінімальних зусиль це легко стає кросплатформенним. Унікальність kotlin в тому що це еволюційний продукт, замість відкидувати досвід розробників в 0, він покращує життєвий досвід — умовно java це ланос, а kotlin умовна тесла. Плюс сам синтаксис мови вирішує мало — головне це інфраструктура — intellij idea, gradle, teamcity і багато інших.
І доречі ніхто не згадує плюс того, що завдяки kotlin можна робити проект виключно на ньому, а це і спільна кодова база а також можливість допомоги всередині команди бо всі оперують однією мовою, а не так ios swift, web dart, android kotlin, backend java/.net/php тому кожен вирішує проблеми самостійно

Більше трех років програмував на Swing, ми розробляли продукт, що був піонером як це тепер називається гибридних аплікацій, тобто десктоп з елементами web, як то iTunes Тільки зараз це здебільшого Mobile+Web. Власне в тій конторі ми системно дружили з Jet Brains, вони зокрема ліцензували наші бібліотеки, вели безпосередню переписку тощо. Деякі мої колеги в решті по переходили туди до них. Зокрема менеджер з яким я працював — тобто мій безпосередній керівник (тімлід перейшов в Google). Те що ви зараз пишите по «мега еволюцію» це якраз елементи маркетингу, які видумали в Apple під керівництвом Стіва Джобса і активно дехто використовує. Ці дехто обіймають самі здогадуєтесь де — провідні посади в компанії.

Більше трех років програмував на Swing,

Чорт, співчуваю. Я свого часу розробляв продукти на Awt, Swing і навіть SWT. Згадую це все гівно «незлим тихим словом». Зараз є набагато більш просунуті інструменти для розробки UI. Якщо брати Котлін, то раджу подивитися на Compose.

памятаю AWT називали awful toolkit )) В Borland в JBuilder був якийсь свій лайоут, де вони ніби щось пофіксили. Але на фоні тодішнього Delphi це виглядало жахливо.
взагалі дивно як Java таки злетіла, перші версії то була якась потвора.

JBuilder

найгірша IDE яку я коли не будь бачів. Три сині екрани за пів години. З того часу перейшов на Eclipse бо він був більше схожий на Borland C++ і дебілдер, а не Vusal Studio 6 як IDEA. З того часу не люблю Idea, як на мене придурасті шорткати де пальці можна зламати, і взаглі усе якось по тарабарскі. Ну і пам’ять вижирає. Щоправда певний час Eclipse теж зафаршмачився.

Там нема в чому співчувати, програмувати сам UI було відносно легко. Просто тулкіт, на відміну від скажімо QT з такою самою ідеєю був так собі, застарілий. Було не просто виконати дизайн стайл-гайди щодо різних операціниних систем, отсупи фреймерк не витримував і доводилось підберати значення екперементально, до того же робити в коді костилі по типу  if (  MAC_OSX == Platfom.getOS() ) { setBorder(12,12,0); } else if (  WINDOWS == Platfom.getOS() ) { setBorder(10,10,0); } , не підтримувалась з половини Apple Cocoa елементів тощо, не було нормального компоненту Web Brauser-а (власне саме це ми і робили та продавали) і т.д. і и.п. Не було навіть таб пану, в якого можна би було закривати конкретні таби мишею.
Не кажучи вже про стрічковий тулбар (Ribbon menu) і т.д. Усе що з’явилось з Windows Vista, Mac OS Snow Leopard, GNOME 3 та KDE 4. Ну тобто тулкіт був просто закинутий виробником і залишився на рівні 90-х років. Хоча величезна купа дуже відомих компаній, включно з двома FAANG та найвідомішими автомобільними , та авіаційними концернами його використовували. Також Мюнхенска міська адміністрація, проект Limux, та силенна контор по усьому світу, що доплачували гроші за компоненти які їм не вистачало по 100-300 баксів, за компонент, що для величезного концерну було копіками, але були інші проблеми вони хотіли мати всі права на інтелектуальну власність. SWT набагато більше продвинутий фреймерк, але має жахливий API — дуже не зручний. Мені іноді здається, що його робили ті самі люди, що і Win API — або за тим же принципом, критично не вистачало часу та досвіду в проектуванні API. JavaFX як і Silver Light супроти якого вона робилась — занадто запізднилась на ринок. Балом правив вже Flash, а HTML 5 з подачі Apple усе остаточно поховав.

Вокруг swt обмазывает eclipse jfaces, вообще берете rcp и вперёд покорять корпоративный десктоп. Куча тулов написана и пишутся до сих пор, там где веб морда не подходит по каким-то причинам, потому что быстро и можно делать сложные вещи с моделями, стрелочками, графами.

доставки програм Java Web Start — тепер це JavaFX

Поперше це повний брєд — джаваФх це десктопний гуй, а вебстарт це срань з вебу і мають спільного вони приблизно ніхуя. Ти або шось сплутав або не розумієш шо пишеш, вибачай.

JavaFX, що провалилась на ринку

А це брєд № 2.
JavaFX панує на джава десктопі. Просто це специфічний ринок, який є, але прихований від пересічного галєрного розробника специфічністю проектів, які не падають на галєри.
Вона успішно розвивається, постійно оновлюється і вельми потужна. Є цілі компанії які побудовані чисто на ній.

А то я ніколи не писав WebStar маніфести. Це така хрінь, щоб запускати десктопну апку з веба, та що працювала песочниця (що правда хакнути, виставивши прямо в коді security management в null, та завантажувати native dll не було жодних проблем). Можно запустити в принципі що завгодно, хочь Tomcat. Та навіть коли ще у люди встановлювали JRE та Java plugin-и до браузера і web застосуноки на JavaFx. Сидів на форумі, один колега на ній розробив навіть аплікацію для купівлі білетів на олімпійські ігри в Лондоні 12-го року. На сьогоднішній момент часу, цей ринок в стані статистичної помилки. Щось звісно є, та цього дуже мало. Як власне і десктоп взагалі, як такий. Що як на мене погано.

Kotlin це помираючий хіпстерський форк java

Виправив, не дякуй

А що на Android з’явилась альтернатива ? В так то можемо ще на предмет Groovy та Scala похоліварити.

На андроїд уже давно можна писати на джаваскрипті, C# чи на Dart. Купа аппок в маркетах, написана на них уже багато років.

Та не вже. Тобто NDK та ядро Linux не дають писати мало не на усьому, на чому можливо від початку ? Справа не в цьому відкрийте будь який мануал по розробці на Android — і він буде на Kotlin. Або спробуйте влаштуватись на проект Android розробником без знання Kotlin. ART взагалі, куди ближчий до сучасного .NET і набагато ближче до LLVM і Clang ніж до JVM та Java. Чому Google не зробили компілятор з D або GoLang для Android що генерує ART/Dalwik сумісний байткод — у мене величезне питання. Вирішили «рідною» мовою зробити Kotlin.

Все що ви перечислили — то треш і угар. Стосовно Flutter та інших ненативних підходів — це працює з чимось простим. Якщо щось більш менш складне — то ви отримаєту жахливий Франкенштейн. Це ж саме стосується і iOS :)

Все що ви перечислили — то треш і угар.

Те, що React Native або якісь Ксамаріни треш і угар не сперечаюся. Але ось флаттер — досить цікавий і має право на життя. Взагалі я вважаю, щоб це все конструктивно обговорювати — треба мати хоч один пет проект хоча б з десятком користувачів. Інакше виглядає як «слишал звон, но нє знаєт гдє он».

Дивіться, тут все дуже просто — перша вправа, треба просто відкрити сторінку з багами Flutter, Відразу все стане на свої місця. Друга вправа — подивитись, як і що працює на певних платформах. Як приклад — iOS. SwiftUI out of the box підтримую відразу всю екосистему. Від iPhone і закінчуючи Apple Watch. Теж саме і з Android Kotlin/Compose. Можна розписати по леєрам і фремворкам — але то зайве. І все це має підтримувати Flutter.
Єдине, де має сенс таких гибридів — це показати швидко бізнес ідею потенційним інвесторам. Потім все викинути. Бо як ви можете бачити — технології змінюються.
Apple поступово відходить від UIkit, Google — від старого управляння UI.

dart після kotlin не зайшов)

Накінець-то я дождався.. На доу холівари не тільки на рахунок емігранства. Тільки все одно якісь трохі тухлі.

Котляристи з Пітера тракторнули до Сан Франциско разом з трактором, ще в 21, клепки вистачило. Як то кажуть гумова дубинка дуже багато чого міняє в голові, навіть як нею дали по сраці.

А язик москалятиною досі тхне

Тільки все одно якісь трохі тухлі.

Ага, засновник Енею поставив нам усім занадто високу планку тролінга

kotlin схожий на c# для jvm + горстка фіч з Go

Тобто усі поголовно — це трошечки? Хоча усі дали деру до Америки. Просто замінник Java прийшовся дуже к місту, через судьбові тяжби та патентну війну між Oracle та Google, за наслідство Sun. При бажанні створити свій черговий Groovy, ви можете це не так вже і важко зробити за пару місяців. Теорія та засоби розробки фронтендів мов на сьогодні дуже розвинуті. Як казали самі Jet Brains — що як з’ясувалось мова це лише програмний продукт, який розкручується маркетингом. Тому якась мова програмування стає популярною зовсім не тому що подобається якомусь програмісту, а тому що якась компанія вклалась в її розкрутку, чистий бізнес. От особисто мені виявилась дуже цікавою мова Jancy яка використовує LLVM в якості бекенду — але кому вона треба якщо її не розкрутити ?

О, про Jancy не чув.

На пенсію зберіг собі подивитися

Радієте Swith Expression, nullable types, неймспейсам, лямбдам... Блін, а ще шось гонять на PHP! Та PHP давно це все має! :D Не думав що світ Java такий морально застарілий

Чого тільки не роблять щоб не перейти на .NET

Головна проблема будь якої екзотичної мови програмування — вони притягують екзотичних програмістів, які пишуть екзотичний код. Це звісно не скала, де навіть знаючи всю мову от й до, я так й не зміг зрозуміти велику кількість коду. Але є певні течії в комьюніті, які мені не подобаються, наприклад «анотації не тру, тру це ktor, koin та exposed». З таким й на проектах зтикався.
Який сенс в лаконічності котліну, якщо тобі треба буде писати тону бойлерплейту? Зате анотацій нема, ага.

Але. Зараз знов пишу на джава, що можу сказати:
— Життя поділилось на до та після, писати без nullable типів тепер наче на JS без типів зовсім. В принципі жити можна, є @Nullable анотації.
— Extensions. Дуже суперечлива фіча. Але є один момент. Коли я пишу "str«.re... IDE показує абсолютно усі утілітні методи для строк. В Java доводиться копатись й перебирати «Strings, StringUtils, а може Apache Commons? А стоп, Петро ж щось таке вже писав у нас». Зростає вірогідність появи дублючого функціоналу тому що хтось щось не знайшов.
— Виходить нова версія Kotlin — я просто беру й оновлюю цифру й все, в мене є нові фічі, а компілюється це в java 8 байткод. В джава це біль.
— Декілька класів в одному файлі. Я можу розкласти в тому порядку в якому мені здається буде читабельніше. В джава базові класи легко губляться серед інших.

Що подобається більше в джава:
— Більш однорідний код по проекту
— Відсутність фіч змушує писати більш якісний код. Наприклад, буває, що не виходить створити ланцюжок викликів .m1().m2().m3(), бо m2 повертає void, в Java доводиться робити змінну, імʼя якої ще й працює як комментар. В котлін великий соблазн зробити .let, .run, .also тощо. А коли попадаєш на код колеги, який вирішив also в let завернути та в run й це все на 100 строк дуже компактного коду з викликом функції з сайд ефектами прямо у дефолтних параметрах — звільняєшся й повертаєшся на джаву )

Так звана «екзотика», це усього лише старий добрий Perl подібний синтаксис.

Тут сильно зависит сколько кода приходится писать. Если много, например в случае мобильных приложений, то это будет эффективней. Если не много сложного то особо не поможет. Это ж только в дело на конференциях люди за 30 минут создают новый микросервис а в реальной жизни больше стоит уделять внимания поддержке чем скорости написания.
Но для веб сайта или для мобильного приложения или прототипирования Котлин классно подойдет.

Я коли читав всі ці статі про котлю, то таке враження шо нафіг воно потрібно, якшо жабка є. Доки не трапив на проект де все на котлі, і діватись нікуди. І виявилось що воно знаачно приємніше працювати ніж здавалось, і значно приємніше ніж жабка.

От скільки може бути способів зробити код нечитаємим без ідешечки ))
P.S.
кріейтори Java теж на поводу пішли — тепер приходиться явно на початку проекту обговорювати, що «var — табу», і «функціональщина має застосовуватись тільки коли є реальна потреба».

Котлін повторе долю скали. Проходьте повз.

Скалу зробили дефолотною мовою для розробки під Android?

Ні. Але скалі пророчили набагато світліше майбутнє ніж зараз пророчать котліну.

Була джава, став котлін, потім стане %languageName%.
Гугл підхопив котлін на хвилі хайпу, ти думаєш гугл не викине котлін так само легко як взяв якщо захоче? Ну ок, кілька років котлін буде нішевою мовою написання формочок для андроіда. Це типу ультракруто для мови програмування бути прибитою гвоздями до платформи і залежати від бажань одного вендора?

Свіфт і айфони зараз тихенько рофлять з твого комента

Ну ок, кілька років котлін буде нішевою мовою написання формочок для андроіда

6 років вже

Це типу ультракруто для мови програмування бути прибитою гвоздями до платформи і залежати від бажань одного вендора?

так вона не прибита, гугл же не забороняє її використовувати де інде.

так вона не прибита, гугл же не забороняє її використовувати де інде.

так само як апплє свіфт )) теоретично є доступним серверні варіанти

... як до речі було з objective-c от скажімо я як експерт в усьому що з «сі» та трохи знаюся окремо на апплє платформі (не тілько айфон але ж десктоп) то я бачив objective-c серверний код 1 раз за це вже більше 20 років

а так теоретично усе є це (оба три) цілком пристойна мова загального програмування

Так objective-c — то як раз «прибита до платформи» мова. А котлін вже використувується на беці. Підтримка Андроїдом — то просто жирний плюс

Та насправді є і GCC Objective C і LLVM Objective C. Дуже довго мусоли en.wikipedia.org/wiki/GNUstep і т.д. Тут взагалі не в мові справа, не конкурентним виявився продукт проти GTK та QT — відповідно і мова програмування програла С++. Навіть самі Apple замінили її на Swift. Так само зараз з AI/ML — фреймверки є і на чистому C++ і на Java. Та комерційно привабливим виявився Python, ну тобто фреймверки з фронтом Python, бо переважна кількість книжок та навчальних матеріалів на Python. Свого часу це сталось тільки тому, що синтаксис був дуже схожий на MatLab, що його використовували вчені математики.

так вона не прибита

Прибита.
«гугл котлін ондроєд кококо» — єдиний реальний аргумент чому котлін ще не на свалці історії і не зайняв місце фрік-мови типу груві. Забери цей аргумерт — і котлін всьо.

Прибита

ні не прибита.

єдиний реальний аргумент чому котлін ще не на свалці історії і не зайняв місце фрік-мови типу груві.

Це не обмеження, а ваше уявлення

Gradle і Spring такі — та невже?

Це не платформи.
Ваш К.О.

Це типу ультракруто для мови програмування бути прибитою гвоздями до платформи

Так а що у світі, окрім святої нашої сішечки, не прибите цвяхами до платформи? Свіфт — айфонний, шарп — віндовий, жс — вебний, котлін — андроїдний. З тих, хто намагається змінити віру — ржуть і тикають пальцями.

А якщо в них ще й довге руде волосся — то спалюють на площі

не прибите цвяхами до платформи?

Джава. Піхтон.

Джава прибита цвяхами до ентерпрайзу, що не краще. От пітончик — так, більш-менш вільно гуляє.

Бо NumPy

Інакше б здох.

PyTorch бо NumPy, оригінальний Torch був на Lua

Не тільки нампай. В задачі «схрестити бегемота з крокодилом» бери пітон і все точно вийде. Всілякі там інтеграції всього зі всім, кросплатформенні юайки, внутрішні тестові тули, CI/CD, автоматизація, роботи, круди для невеликих навантажень — багато всього. Пітончик молодець, прямо кращий вибір для другої мови в резюме (незалежно навіть від першої)

льтракруто для мови програмування бути прибитою гвоздями до платформи

А насправді будь яка мова цвяхами прибита до платформи. При усьому бажанні на халяву в більшості випадків зробити комерційно якісний програмний продукт який має один і той самий похідний код для усіх цільових платформ, не вийде. Дійсно можна відокремити системно залежний і системно не залежний коди один від одного. В чому і великий бенефіт Java як платформи (щоправда тільки не Gui бібліотеки Swing — яка жахлива, хоч на ній і відносно легко писати), чи фреймверків типу : Spring, QT, wxWidgets, POCO тощо. Піонерам підходу були Річі і Томсон. Мову C — відомі гуру з теорії трансляції, як то Ніклаус Вірт та низка інших, критикували С як мову по ділу, бо вона взяла багато атавізмів з Algol 60. В мові є ціла купа речей, яка дозволяє стрільнути собі в ногу (хоча в Pascal теж запросто), тому от просто так ляп ляп і в продакшн — не можна, теба тестувати, санітайзери і т.д.. Та разом з тим — це мова системного API Unix, а також ще і Windows, бо Microsoft як і низка інших вирішили не велосипедити. Щопрадвда разом із Visual Basic — не з’ясувалось, що велосипедити це чудовий бізнес, а Borland відтяв суттєву долю ринку разом з Delphi. От почали робити : MSDN, книжки, сертифікації, Visual Studio і т.д. і т.п. Холівари та статті це усе теж метод промоушена комерційного програмного продукту, з метою — заробити собі грошенят. Навіть якщо автор цього не думав, його стаття вже була у Топки в бізнес плані.

Якийсь мутний потік свідомості. Коні, мухі, котлєти.

А шо не так зі Скалою? Працюю в big data, всі критичні проекти нею написані.

Складно сложно. Ніасілятори ніасілюють.

треба мати специфічнгий тип мислення щоб писати код в такому стилі. Судячи з ринку/вакансій/кількості девів, таких не більше 10%.

Там не в типу мисленні справа, а в низькому попиті. Та сама ідея як і у COBOL.

Так а нашо? Флінк, апачі сторм, апачі бін, ітд, все на жабці, і ніяких із тим проблем ніякого спецефічного мислення не потрібно. Тому спарк на скалі буде відмирати.

Особисто для мене із мінусів це дуже мала кількість проектів/вакансій

А шо не так зі Скалою?

Вона утонула.

всі критичні проекти нею написані.

Ага, ну да, канешна. Все найкритичніше найважливіше і найшвидше написане на скалі онлі, ок.

:) Так чи інакше Scala засіла в сфері BigData — тобто машинному маркетинговим дослідам.

Часи скали в ыг даті також пройшли. Дата саянси тіки пітон вміють. Навіть спарк зара більше в пітон розвивається ніж на скалі.

Ну якщо покапати вакансії, там все ще вимога знати Spark та Scala. А Python та R — пишуть Nice to Have. Звісно насправді там головні знання, взагалі не з програмування — треба на сам перед знатись на : теорії вірогідностей, математичній статистиці та маркетингу. Проти цього мова програмування другорядне діло. Середній программіст мову програмування засвоює на достатньому рівні в період до двох тижнів. А от вивчити бізнес домен — предметну галузь задачі автоматизації, можуть підти роки та виявитись потрібними окремі освітні програми.

Середній программіст мову програмування засвоює на достатньому рівні в період до двох тижнів.

Середній программіст скалу не засвоює взагалі ніколи.

Як вона є на проекті, бо якийсь Play Framework — ніхто і не питає, доведеться робити.

І що, дев не знав на що йшов? На інтерв’ю на проект ні словом не обмовились що треба знати Scala? Ну такоє...

Мова це математична нотація.

Бізнес-галузь це набір аксіом і теорем

Дата сайнтісти Скалу осоливо ніколи й не юзали. Вона більше для дата інженерів

Scala засіла в сфері BigData

Єдине де «засіла» скала — то це в старих легасі які купились на хайп. Бігдата або на вже згаданих джава фреймворках або на піхтоні.

Хоч котлін і проектують москалі, але сама мова це найкраще, з чим я працював за всі роки. Джава (як мова) навіть і близько не стояла. До того ж Kotlin Multiplatform ІМХО — дуже перспективна штука.

котлін і проектують москалі,

Скоріше американці, російського походження станом на сьогодні. Про службу в армії як таку не впевнений, тобто швидше не москалі — а звичайнісінькі кацапи. Як відомо в москалі можуть забрати і українця, найвідоміший такий — Тарас Григорович Шевченко.

P.S. Поцікавтесь скільки в тій конторі працює як вони самі себе назививають — хохлів.

Та бачив я багато інтерв’ю з цими «американцями». Москалі вони самі звичайні, просто, як ти уже написав, додумались покинути свій мордор.

Як у тебе усі кацапи москалі, то путлер виявляється правий — що це тут усі бендерівці нацисти і шовіністи, хто бендерівці — усі хто говорить українською. Що тоді з ними робити, як вони українською розмовляють? — Правильно, робити Бучу — бо то усе взагалі на люди, то бандерівці а з бандерівцями можна робити усе, що завгодно вони самі нас хочуть загеноцидити. Також легко можна на східній Україні, в Криму і т.д. переконувати людей йти якраз в москалі в різні лугандонскі підрозділи, утворені за принципом січових куренів. Не лий воду на ворожий млин. Рашизму тільки цього і треба.

ІМНО, ти змішуєш поняття «кацапи вони же москалі» як «національність» (в лапках тому що там дофіга сортів г... які всі це поняття об’єднує) і «москалі» як службу в расєйській армії. В останньому контексті воно зустрічається у творах ТГ, але не є поширеним.

В чому перевага КММ перед флатером чи реактом на вашу думку?

В темах написано «Anfroid» замість «Android»

Підписатись на коментарі