Pull to refresh
-3
0,1
Rating
Send message

Пу пу пу … тяжелый случай. Ну начнем по пунктам.

Котлин мультиплатформенный язык так-то, JVM, LLVM, JS, WASM.

Kotlin не может позволить себе реализовать такие вещи как специализацию для дженериков.

Ну так и у Джавы с этим все стабильно плохо. В dotnet уже как с десяток лет существуют обобщения на уровне рантайма, а в джаве мы продолжаем затирать типы во время компиляции. Вальхаллу уже 15 лет обещают и все никак не сделают. И все же у Котлина с этим получше будет, т.к. есть reified типы, которые позволяют определить тип класса у обобщенных функций не прибегая к рефлексии и все во время компиляции. Сюда же можно отнести и inline функции. В некоторых случаях компилятор Котлина просто уберет type erasure(для примера возьмем любой примитив, без null аннотации) и подставит сгенерированную функцию с необходимым типом. Частичка мономорфезации как у Плюсов, хРуста.

Java более оптимально и повториться история с корутинами.

Тоже спорно, VT конечно лучше обычных потоков, но утилизация процессора на еденицу работы у него кратно хуже, чем у WebFlux, Coroutines. У VT RPS ниже, p99, p95 задержки выше, чем у последних двух. А нормального structured concurency так до сих пор и нету, JEP сидит в инкубаторе с 20 JDK. В Котлине это идет из коробки и будет попроще для восприятия.

Java пример
UserProfile loadUserProfile(String userId) throws Exception {
    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
        Future<String> userFuture = scope.fork(() -> fetchUser(userId));
        scope.join();
        scope.throwIfFailed();

        String userData = userFuture.resultNow();

        try (var innerScope = new StructuredTaskScope.ShutdownOnFailure()) {
            Future<List<String>> ordersFuture = innerScope.fork(() -> fetchOrders(userData));
            Future<List<String>> recommendationsFuture = innerScope.fork(() -> fetchRecommendations(userData));

            innerScope.joinUntil(Instant.now().plusSeconds(2));
            innerScope.throwIfFailed();

            return new UserProfile(userData, ordersFuture.resultNow(), recommendationsFuture.resultNow());
        }
    }
}
Kotlin пример
suspend fun loadUserProfile(userId: String): UserProfile {
    return coroutineScope {
        val userData = async { fetchUser(userId) }.await()
        
        val orders = async { fetchOrders(userData) }
        val recommendations = async { fetchRecommendations(userData) }

        UserProfile(
            user = userData,
            orders = orders.await(),
            recommendations = recommendations.await()
        )
    }
}

И VT в Джаве все еще далеко до Корутин из котлина, т.к. если мы захотим побаловаться Reactive Streams, настроить как-то под себя backpressurе, то Джава нас тут оставляет с голым носом и нужно тащить в стек RxJava или Reactor.

Совместимость? Хреновая.

Совместимость у Котлина с джавой лучшая в своем классе. Для ознакомления советую попробовать написать обертки с Жабы на Скалу, интересное занятие, которое никому не порекомендую. Хуже только, у нативных языков, когда нужно прибегать к JNI. А NPE это косяк разработчика написавшего Джава код и забывшего поставить аннотации.

Также большинство либ рассчитано под Java и не все без приседаний и костылей будет работать.

Про наличие библиотек оберток и аналогов говорить или нет?

В Java, при всех ее минусах, то что написано в коде плюс минус будет в байткоде. Kotlin вам вообще ничего и нигде не гарантирует.

Да не уже-ли? For each итератор по списку сгенерирует одинаковый байткод как на Java, так и на Kotlin. Если хотите предсказуемый байткод, так и пишите простой и предсказуемый код, в документации все описанно, где, что и когда генерируется. Каждая фича языка, будь то record в Жабе или data class из Котла сгенерирует вам здоровую портянку кода.

Отдельного упоминания стоят именованные параметры, defauld параметры и перегрузки функций. Как там с ними дела?

Пунктик за который нужно в панамку накидать автору статьи - не указанны фишки Котлина, которых у Джавы пока-что нету и не факт, что будут:

  • Contracts

  • Extension methods

  • SmartCast

  • Context parameters

  • Value classes (inline classes)

  • Power Assert

  • DSL

Я это все к чему. Котлин в первую очередь проектировался для снижения нагрузки для разработчика и утверждение, что Котлин это просто сахарок от части верно. Но Котлину уже 15-ый год стукнул, за это время он успел обрасти своими уникальными фишками и экосистемой, а после перехода на K2 перед разработчиками открылись двери для введения новых фишек по типу Error types | Unions, позволяющих отказаться от try catch в пользу более понятных ошибок, отлавливаемых еще на этапе компиляции. Котлин проще Джавы в прямом сравнении? По уровню входа Джава проще, по уровню поддержки Котлин выигрывает за счет лучшей читаемости и большей гибкости. Главный плюс это Котлина, что он может работать на любой версии Джавы начиная с 6, а в Java хочешь не хочешь, а придется поднимать JDK до последней версии, если хочется себе какие-нибудь новые плюшки.

З.Ы.
Kotlin это сахар над Java
Java это сахар над C++
С++ это сахар над C
С это сахар над ASM
ASM это сахар над Оп кодами
ASM и OpCodes лучшие ЯП. Change my mind.

Только как говорится, есть нюанс. Это не совсем Идея, а Fleet который зачем-то переименовали. А по функционалу, Флит не далеко ушел от ВС кода, перейти к реализации, переименовать символ и считай все, того огромного комбайна функций из идеи даже близко не было, хотя казалось бы под капотом движок Идеи. А ну он ещё более тормозной, даже чем идея.

А можно просто не заниматься ерундой и использовать UniFFI который имеет из коробки поддержку Async и убирает необходимость писать синхронные обертки вручную.

Dart стал единственным языком, который успешно добавил полноценный sound null safety в уже существующий язык.

C# - ну да, ну да, пошел я нах*р.

> С КМР/Jetpack так не получится, они используют нативные компоненты, которые нужно уметь правильно готовить.

Ушибочка. Compose имеет возможность интеропа с нативными компонентами, но не заставлять их использовать, ровно как и флаттер.

Простите, но в каком месте вы увидели плюсы в ядре Линукс?
Если хочется Хруста на встройке, есть embedded-hal и его реализации для разных платформ.

Готов поспорить, что в изначальном варианте был void*, но как-то в процессе редактуры "*" протерялся, на что кстати намекает лишний пробел в касте (void )(unsigned long)

А что является критерием для сравнения, хотя бы тех же самых плагинов на обоих платформах? Кол-во плагинов? Кол-во строчек кода на единицу плагина? Такой же вопрос к сообществу... Если читать между строк, то ответ на вопрос "Как быстро можно на вашем КМП взять готовые библиотки, тяп ляп и в продакшн": В целом должно быть так же быстро как и на Флаттере. Большинство кейсов должны покрываться существующими библиотеками Котлина: всякие permission, круд запросы, синие зубы, работа с локальной бд и тд.
Можно еще вот тут с остальным ознакомиться, представлены конечно не все библиотеки, но большинство есть.

Есть система сборки Amper, конфиг мало чем от конфига флаттера отличается.

Какой-то несвязный поток сознания у вас вышел, но давайте разберемся. Го-байткод он же IR это нормальная практика для большинства современных языков. Разделение на фронтенд(Лексер языка, генерация IR) и бекенд(генерация машинного кода и в том числе работа с регистрами) позволяет относительно быстро добавлять новые архитектуры и платформы. От LLVM отказались мне кажется намеренно, т.к. один из краеугольных камней Го - быстрая компиляция по сравнению с Си и переезд на LLVM кратно, а может быть и в десятки раз увеличил бы время сборки.

Я вот сейчас пальцем в небо тыкну и на первом же блоке с err != nil нам попадется

		if err != nil {
			return nil, err
		}

Проблема в том, что ошибки то не проверяются, а просто кидаются выше по дереву вызовов до места вызова. Из-за чего разработчики должны писать лишний бойлерплейт.
В Расте вот немного умнее подошли к обработке ошибок. Функция возвращает Enum, который может содержать ошибку или значение и ее можно распаковать оператором ?. Если имеем ошибку возвращаем ошибку, если нет, получаем значение.

fn check_even(num: i32) -> Result<i32, String> {
    if num % 2 == 0 {
        Ok(num)
    } else {
        Err(format!("Число {} нечетное", num))
    }
}

fn process_data(n: i32) -> Result<i32, String> {
    let val = check_even(n)?; // Распаковка через ?
    println!("Обработка значения: {}", val);
    Ok(val * 2)
}

fn main() {
    match process_data(4) {
        Ok(res) => println!("Результат: {}", res),
        Err(e) => println!("Ошибка: {}", e),
    }
    
    // Для нечетного числа
    match process_data(5) {
        Ok(res) => println!("Результат: {}", res),
        Err(e) => println!("Ошибка: {}", e),
    }
}

В Zig тоже достаточно похожая и органичная обработка ошибок, только там error union вместо Result и try вместо ? оператора.
Но авторы Го на любое предложение с мыслями о эволюции языка просто зыкрывают тему со словами "У нас все хорошо, ничего нам не надо". Я до сих пор не понимаю, каким чудом удалось в Го протолкнуть обобщения.

Потому-что очередная ИИ статья в копро блоге.
Вот к примеру докерфайл одного из премеров, причем по внутренней градации он "продвинутый"...

FROM ubuntu:20.04

RUN touch /hello.txt && echo "hello world" > /hello.txt

Статья как говорится ниочом. Новичкам никс преподносят как очередного убийцу докера, а те кто в теме - те в теме.

\s А почему в конце статьи нету ссылки на "полезный" телеграм канал, который ведет автор?

Эта фишка доступна любому статически компилируемому языку, не только лишь Go.

Ну это уже сверх наглость заставлять гпт писать комментарии к статье написанной ей же.

Простите за наивный вопрос, но у вас в среде разработки "Go to Reference" не работает?)) Если мы пишем крупный проект, то рано или поздно , дабы не нарушить DRY нам все равно придется написать функцию обёртку и начинается велесипедо строение вместо того, чтобы просто использовать стд-шную функцию. Более того, я уверен, что после стабилизации итераторов, в стандартной библиотеке скорее всего появится похожая функция.

Можно было хотя бы для приличия попросить ГПТ написать про Элексир или Глем? И на акторах щас в скале не пишут.

Один вопрос, зачем? Будь проект полностью написан в common для kmp, логику можно было бы проследить, но это не так - в проекте много частей на джаве. А в жвм и так есть kts, который для конфигураций не чуть не хуже. Чёт опять пахнет очередной revolution от Apple.

У серверлесс, серверлесс контейнеров и базы от Яндекса по моему есть бесплатные месячные квоты.

Information

Rating
5,013-th
Registered
Activity