Kotlin 1.5.30 и KMM/KMP

За последний год или около того был постоянный поток версий Kotlin, каждая с новыми функциями и исправлениями. В общем, все как обычно. Поскольку мы (Touchlab) изо дня в день усердно трудимся над клиентскими проектами с использованием KMM, могли легко упустить из виду что-то более важное. Kotlin 1.5.30 воспринимается (в количественном отношении) как очередная доработанная версия, но в действительности является значительным продвижением платформы. 1.5.30 представляет несколько важных функций, по крайней мере в ознакомительном варианте. В конечном счете эти функции проложат путь к массовому внедрению технологии общего Kotlin-кода, позволив ему достичь лучшего качества.

Kotlin 1.5.30 — поворотный момент в KMP. И вот почему.

Превью модели памяти

Одним из наиболее спорных аспектов Kotlin/Native является модель многопоточной обработки и памяти. Высказывались разные точки зрения. Мы не будем здесь обсуждать, хороша или плоха такая модель и почему. Однако за последние несколько лет я говорил о ней гораздо чаще, чем о чем-либо другом, поскольку без нее невозможно развитие технологий KMM и KMP. Тем не менее, некоторые относились к модели памяти как значительному блокирующему фактору. Скоро все изменится. Я бы пока не запускал в производство новую модель памяти 🤞, но вы можете начать экспериментировать с ней уже сейчас в расчете на то, что производственные развертывания появятся при переходе к 1.6 (Как я предполагаю 🙂 🚀.

Что это за бизнес с использованием модели памяти, спросите вы? В некоторых языках (Java, Swift и т.д.) несколько потоков могут считывать и записывать общее состояние. Некоторые используемые при этом методы опасны, поскольку чреваты ошибками. Многие языки не позволяют получать доступ к состоянию из нескольких потоков (JS), в некоторых даже есть правила ограничения памяти, встроенные в язык и компилятор (Rust). Технология Kotlin/Native представила относительно уникальную модель. Теоретически это интересно, хотя на практике такая модель может привести к путанице и оказаться непригодной для внедрения.

Новая модель памяти, по-видимому, обеспечит неограниченный общий доступ к состоянию. Некоторые вопросы остаются пока без ответов:

  • Будут ли предусмотрены эквиваленты средств многопоточного программирования JVM (синхронизируемые и т.д.)?
  • Если вы напишете библиотеку, которой нужна новая модель памяти, не получите ли ошибку при компиляции с зависшей моделью?

Такого рода проблемы, я уверен, со временем будут решены.

Ознакомьтесь с кратким обзором модели памяти Рассела.

Что эти изменения будут означать для вашего кода и что вам следует сделать сегодня? По крайней мере, в течение следующих 6 месяцев вам потребуется реальное понимание текущей модели, а ваш код, вероятно, вообще не изменится при подключении новой модели. Версия 1.5.30, скорее, смягчит правила, чем изменит их.

Анализ кода на этапе компиляции

Плагины для компилятора дорабатывались с течением времени, как и IR-компиляторы для JVM и JS. Эти доработки были не совсем привязаны к 1.5.30, но они привели к добавлению поддержки KSP для Kotlin Native и KMP в целом, а поддержка K/N была добавлена несколько месяцев назад.

Технология Kotlin Native довольно статична во время выполнения, поэтому любой значительный анализ кода и манипуляции с ним необходимо выполнять на этапе компиляции. Поскольку нет реального эквивалента “процессора аннотаций”, существует ряд библиотек, которые на самом деле не могут быть созданы так же, как для Android. Применение таких фреймворков, как Dagger, возможно только с плагинами для компилятора. Любая замена реального объекта имитированной реализацией потребует преобразования кода. Кроме того, для создания кода Swift для упрощения интеграции необходим стабильный (и тщательно записанный) на этапе компиляции анализ кода. 1.5.30 не включает сразу все эти функции, но усовершенствование плагинов, добавление KSP и мультиплатформенный IR-компилятор, используемый теперь по умолчанию, значительно ускорят разработки библиотек, что было гораздо сложнее в случае с предыдущими версиями.

Иерархические модули / исходные наборы

Я бы сказал так: Hierarchical MPP (HMPP), подпадая под общий список доработанных и стабилизированных инструментов, является конкретным их примером. Возможно решение многих задач с очень похожими API-зависимостями, особенно в Native, но настройка IDE и компилятора для их распознавания не была полнофункциональной. Она нормально срабатывала в более простых ситуациях, таких как ios (), но для библиотек с вложенными иерархиями и множеством задач публикация библиотек с HMPP-поддержкой на самом деле не была вариантом.

С Kotlin 1.5.30 это было (в основном) исправлено! С помощью пошагового перемещения мы выяснили, как правильно настроить относительно сложные библиотечные модули. В течение следующих нескольких дней мы опубликуем версии HMPP-библиотеки. В настоящее время опубликованы:

SQLDelight HMPP и M1 Mac Arm support объединены и, надеюсь, скоро этот тандем будет запущен. Возможно, Koin и другие тоже, хотя я давно не проверял…

Наша библиотека журналирования, Kermit, претерпевает изменения, связанные с HMPP, но также проходит довольно значительную капитальную реконструкцию, ориентированную на производительность и функциональность. Вы можете попробовать предварительную версию 0.3.0-m1. Сам api несколько изменился, но должен быть совместим для большинства применений.

Кроме того

M1-архитектуры являются долгожданным дополнением. Во всех библиотеках, упомянутых выше, опубликованы целевые объекты архитектуры mac arm.

Обеспечена прямая поддержка XCFramework. Мы тратим немало времени, помогая клиентам интегрировать KMM в их сборку промышленного кода и CI, поэтому спрос на Swift Package Manager остается повышенным. Оптимизация XCFramework имеет решающее значение в этом отношении. У нас возникли некоторые проблемы с производительностью при использовании различных внешних решений, и мы начали экспериментировать внутри компании. Надеюсь, прямая поддержка улучшит эту ситуацию.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Kevin Galligan: Kotlin 1.5.30 and KMM/KMP

Предыдущая статьяМетоды лингвистического моделирования с использованием Python
Следующая статьяКак создать самообновляющийся заголовок Twitter с динамическим контентом