«Скорее всего, будет расти как снежный ком» — Андрей Бреслав и Антон Кекс о Kotlin

7d4244a0150d41d1adb706a13a3f8083.jpg

За год, прошедший с релиза Kotlin 1.0, у языка произошли прорывы по многим фронтам: от поддержки в Gradle и Spring до выхода книги «Kotlin in Action». Число Kotlin-строк на GitHub возросло более чем вчетверо, превысив 10 миллионов. А теперь вышла версия 1.1, добавляющая компиляцию в JavaScript, и это выглядит громкой заявкой на новую долю рынка. Означает ли это всё, что вот теперь время Kotlin по-настоящему пришло, и нам всем пора активно использовать язык в продакшене?

Андрей Бреслав (JetBrains) и Антон Кекс (Codeborne) многое знают о Kotlin (и оба скоро выступят на JPoint с докладами о нём), но при этом смотрят на него с разных сторон: пока Антон разрабатывает на этом языке, Андрей работает над самим языком. Мы решили, что о настоящем и будущем Kotlin интересно поговорить с ними обоими сразу, получив полную картину. Начав с вопросов о бурном росте, затем успели обсудить ещё многое:

  • Взаимодействие с разработчиками и процесс эволюции языка
  • Компиляцию в JS, проект Kotlin Native и мультиплатформенность в общем
  • Несовершенства
  • Kotlin-паззлеры
  • Ожидания и амбиции

JUG.ru: Для начала расскажите, как именно вы связаны с Kotlin.

3b6c865c0e8846da8f09594c24735884.pngАндрей abreslav Бреслав: У меня всё очень просто, я возглавляю весь проект: и весь language design, и весь менеджмент.
 
 
 
 
 
 
 
 

6c79d2504d9f4029a60ad45f52c7b11a.pngАнтон Кекс: Я делал на Kotlin один проект в продакшене, ещё один очень крупный проект собираюсь сейчас потихоньку переводить на него, и очень много личных опенсорсных проектов перевожу с Java на Kotlin, чтобы лучше прочувствовать язык.

Тот, который уже делал в продакшене — плагин для IDEA, поэтому проще было убедить заказчика использовать Kotlin. Я начинал делать его в прошлом году: как только выпустили 1.0, так мы сразу начали на нём писать.

У меня как опытного разработчика опыт был очень положительным, а менее опытному разработчику в этом проекте было тяжело учить новый язык. То есть для меня это было больше fun, а для другого человека это было больше препятствием к тому, чтобы делать работу быстро. Но мне кажется, что мы быстро освоились, и с того времени я больше полюбил язык. До того немножко скептично относился, потому что мне казалось, что при выходе Java 8 она уже покрыла многие юзкейсы. Но оказалось, что Kotlin всё-таки гораздо приятнее, чем восьмая Java. Поэтому я сейчас вовсю пытаюсь пропагандировать язык в тех проектах, в которых участвую.

JUG.ru: Со стороны кажется, что 2016-й стал для Kotlin прорывным годом —, а как это видите вы?

Андрей: 2016-й действительно был прорывным годом, как минимум, потому что вышел релиз. Естественно, комьюнити стало всерьёз рассматривать проект, пошёл adoption. Мы очень довольны динамикой, которую видим: Kotlin пользуются крупные компании в серьёзных проектах; появляется много обучающих материалов от разных людей; люди из комьюнити пишут книжки, которые мы сами никак не спонсировали, и они популярны.

Видно, что, скажем, комьюнити Android-разработчиков или Spring очень внимательно отнеслось к появлению Kotlin, люди начали пользоваться. Следующая версия Spring будет включать в себя уже какие-то расширения на Kotlin, среди Android-разработчиков это просто очень популярный инструмент. То есть на обоих рынках, на которые мы в основном рассчитывали, у нас очень хороший результат: и server-side development очень бодро, и Android development.

JUG.ru: Востребованность языка определяется ещё и вещами вроде числа вакансий —, а с этим у Kotlin что?

Андрей: Чисто котлиновских вакансий я видел совсем немного, а вот вакансий «нужен разработчик на Java и/или Kotlin» становится больше. Понятно, что если у людей есть активно разрабатываемый проект либо на бэкенде, либо на Android, и кто-то из участников добавляет туда Kotlin, то вакансии там становятся не только Java, но и Kotlin. Если люди привыкли нанимать достаточно серьёзных специалистов, которым несложно освоить новую прикольную технологию, то для них это не барьер, и они спокойно это делают.

Антон: Я как работодатель могу ещё прокомментировать, что идёт тренд full stack development, у нас в компании все разработчики full stack, поэтому нанимать кого-то, кто знает только Kotlin или только Java — это плохая идея. Лучше нанимать людей, которые вообще умеют программировать, понимают, как работает объектно-ориентированное программирование, как работает функциональное. И выучить потом синтаксис Котлина достаточно легко, особенно если есть опыт с Java на JVM. У нас многие пишут кто на Ruby, кто на Java, и для тех, кто видел тот и другой, начать на Котлине писать не занимает много времени.

Андрей: Я Антона поддерживаю, что лучше нанимать хороших программистов, и для таких людей язык — это не препятствие в основном.

JUG.ru: Антон, а что за год вашего использования Kotlin изменилось для вас как разработчика?

Антон: Когда вышел Kotlin 1.0, он был сырой — или, как минимум, IDE. IDEA всё-таки очень сильно уступала возможностям на Java. Например, была куча багов в дебаггере, в компиляторе тоже встречались… На первом проекте мы столкнулись с достаточно многим, особенно много было проблем с дебаггером. И если в случае с Java у IDEA всё классно с инспекциями, то, например, в Kotlin те же самые недочёты она не находила. Но постепенно стало гораздо лучше.

Думаю, что версия 1.0 была триггером для многих, в том числе и для нас, начать писать настоящие проекты, и благодаря этому какие-то вещи удалось отточить уже гораздо более быстрым темпом. На данный момент уже почти нет возможностей, которых в IDE не хватает по сравнению с Java. По-моему, поддержка стала очень хорошего уровня.

JUG.ru: А, например, нужную информацию достаточно легко найти? На Stack Overflow ответов по тегу «Kotlin» пара тысяч, а по «Java» чуть ли не миллион — это не мешает?

Антон: Я бы сказал, что это не проблема. На самом деле, специфичных проблем с Kotlin мало, и обычно его документация помогает найти ответы. Очень часто, когда разрабатываешь Android или веб-приложение, возникают вопросы про платформу или API, а не язык программирования. Поэтому из миллиона ответов по Java, скорее всего, 90% подходят и для Kotlin, не вижу проблем. Помогает также неожиданная фича в IDEA: если в класс на Kotlin cкопировать Java-код откуда-нибудь из интернета, то он автоматически конвертируется в Kotlin.

e0dd237159c241308d120dc4164b1d7b.jpg

Взаимодействие с разработчиками и эволюция языка


JUG.ru: Недавно у Kotlin появился официальный подкаст, до этого процесс разработки языка сделали более открытым как KEEP — Андрей, а это части общего плана «активнее обращаться к разработчикам», или отдельные инициативы?

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

У нас есть публичный Slack, аудитория которого сейчас приближается к 6000 человек, инженеры из нашей команды там достаточно регулярно появляются и отвечают на вопросы, а комьюнити очень активно общается между собой. К вопросу про Stack Overflow: если вдруг оказывается, что где-то в публичных источниках не найти ответ на вопрос, то можно пойти в Slack и очень быстро получить там ответы, включая достаточно детальную консультацию человека, который писал эту функциональность. Также есть подкаст, разные публикации, которые мы стараемся делать сами, а недавно открыли программу поддержки юзергрупп, чтобы людям было проще организовывать встречи по Котлину. Это одно направление.

Другое направление, KEEP — это уже не про собственно организацию комьюнити, а про дизайн языка, Kotlin Enhancement & Evolution Process: то, как мы собираемся эволюционировать Kotlin. KEEP сейчас в относительно зачаточном состоянии, вот была первая проба — мы в скоупе 1.1 старались публиковать наши дизайновые решения, чтобы люди из комьюнити могли выдать нам какой-то фидбэк, вместе с нами что-то обсудить, сказать нам о своих впечатлениях, предложить что-то. Это довольно неплохо работает, хотя, конечно, нагрузка на дизайновую команду увеличивается, и сейчас мы всё немножко реорганизуем. То есть мы по-прежнему будем всё публиковать, просто немножко по-другому это сделаем, чтобы нагрузки было меньше. Но смысл такой, что мы стараемся максимально открыто работать над дизайном языка, чтобы как можно больше людей смотрели на это как можно раньше и говорили нам, что они думают. Собственно, это в лучших традициях опенсорсных проектов, и эти традиции нам очень нравятся.

JUG.ru: Антон, а вам в работе помогает эта открытость компании к взаимодействию?

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

JUG.ru: В связи с «легко достучаться, когда ты недалеко от Петербурга» любопытно:, а приводит ли это к повышенному интересу к Kotlin в России по сравнению с другими странами?

Андрей: Мы действительно видим в России очень большое внимание к Kotlin. Фактических пользователей в стране у нас меньше, чем в Америке или в Китае, но это отражает количество населения. Мне сложно сравнить с другими языками, у меня нет хороших географических данных по другим, но могу точно сказать, что мы чувствуем очень много внимания со стороны российского сообщества. С одной стороны, есть куча людей, которые что-то делают, вкладывают душу, а не просто читают. А с другой — это удивительный факт, я не знаю, чем он объясняется, но те очень редкие люди, которые у нас в разных каналах информации резко и некорректно высказывают своё мнение, переходят на личности и всяко-разно по-другому хамят, пока что в 100% случаев оказывались русскими.

Антон: Я могу предположить, что русскому человеку легко нахамить другому русскому человеку. Вряд ли русский человек будет хамить англичанину или американцу.

Андрей: Интересная версия, я про неё не думал. Возможно.

JUG.ru: Возвращаясь к KEEP: Антон, а вы в нём участвуете или нет?

Антон: Пока что KEEP«ы в основном только читаю. Там надо потратить очень много времени, чтобы погрузиться в контекст. Жаль, что не участвовал активно в проработке фич 1.1, корутин и так далее, но, может быть, в какой-то момент найду больше времени, чтобы этим заниматься.

Андрей: Да, погрузиться во все детали дизайна какой-нибудь хитрой фичи языка — это очень большая нагрузка. Я как человек, который при разных обстоятельствах погружался в дизайн других языков (в частности, Java) и участвовал в процессе, понимаю, что надо загрузить в голову очень много специфического контекста. Но, безусловно, есть люди, которые могут и хотят это сделать, и мы стараемся дать им такую возможность.

Большой вопрос для нас — как организовать дизайновый процесс так, чтобы он, с одной стороны, был открытым, а с другой — не тормозился об это. У нас очень много устной коммуникации, потому что мы находимся в одном офисе или можем созвониться, и если мы переведём все коммуникации по дизайну в переписку, они просто замедлятся в разы. Мы не хотим всё настолько замедлять, поэтому вместо этого периодически дампим текущее видение, выкладываем его, собираем комментарии и потом это перерабатываем. Это пока работало не так эффективно, как хотелось бы, но мы будем улучшать процесс и делать так, чтобы внешние люди могли реально включиться.

Антон: Я бы сказал, на самом деле хорошо, что вы делаете более эффективную коммуникацию у себя в офисе, потому что успешный язык программирования в какой-то мере нуждается в диктатуре. В принципе, сейчас видно, насколько медленное развитие у Java из-за того, что многие решения очень боятся принимать, эти несчастные лямбды столько лет мусолили… Мне кажется, что иногда, если есть две альтернативы, нужно просто выбрать одну и реализовать.

В Kotlin до сих пор с этим всё окей, и мне кажется, что так и нужно продолжать. Не ждать, может быть, о каких-то вещах слишком много комментариев.

Андрей: Совершенно согласен. С одной стороны, мы стараемся собрать как можно больше входной информации, в первую очередь интересуют юзкейсы: как люди пишут код в разных контекстах. Но при этом мы действительно не хотим блокироваться на каких-то вопросах.

Например, с корутинами у нас такая ситуация: мы сейчас в 1.1 выпустили их в экспериментальном режиме. У нас есть абсолютно работающая реализация, есть библиотеки от нас и от других людей —, но мы понимаем, что фича слишком большая, чтобы охватить её полностью за какое-то конечное время. Поэтому мы выпускаем имеющийся дизайн в экспериментальном статусе, чтобы много людей попользовалось, мы получим фидбэк, и если нужно, что-то починим.

Такой цикл обратной связи с сообществом, как мне кажется, совершенно необходим, чтобы не оторваться от реальности. При этом совершенно необязательно делать это так суперконсервативно, как принято в команде Java. У них свои причины для того, чтобы это делать, но у нас, к счастью, такой необходимости нет, и мы стараемся двигаться, не тормозить, не быть парализованными «analysis paralysis» и необходимостью удовлетворить всех на свете.

Антон: В то же время Kotlin, возможно, ещё недостаточно долго жил, чтобы наткнуться на какие-то проблемы, которые делают Java-комьюнити таким медленным и консервативным. Мы ещё не знаем, насколько выдержит код на Kotlin тест времени, будет ли хорошо работать через пять лет код, скомпилированный с 1.0, будет ли компилироваться сегодняшний исходный код через пять лет.

Андрей: Что касается скомпилированного кода, я в большой мере уверен, что работать всё будет так же хорошо, как любая другая джавовская программа, потому что там достаточно ограниченное влияние самого Котлина. А вот что касается того, как будет компилироваться исходный код — это зависит от нас, и у нас есть много вопросов о том, как идеально это делать, мы будем пробовать разные стратегии.

У нас был очень хороший эксперимент перед релизом 1.0, когда мы меняли язык, но у нас уже были какие-то сотни пользователей, и мы не хотели ломать им весь код. Мы делали средства миграции: это то, что не очень принято в других комьюнити, когда язык программирования меняется несовместимым образом, но инструментарий предоставляет миграцию. Это был довольно позитивный опыт, не было каких-то стонов и особенно большого страдания, что очень приятно. Это для нас обнадёживающий сигнал: если вдруг окажется, что очень важно что-то поменять, то мы можем это сделать и не потерять аудиторию, не превратиться в Python 3.

Но это очень сложный вопрос баланса — как эволюционировать язык, чтобы, с одной стороны, не было стагнации, какого-то жуткого легаси, которое всех достало, а с другой — чтобы людям было нормально этим пользоваться, и они не мучались с миграцией. Есть разные подходы — Java суперконсервативная, Scala в каждом релизе ломает бинарную совместимость, Swift в каждом релизе ломает source-совместимость, и у них всех есть какие-то результаты. Мы на них всех посматриваем и думаем: «А как бы нам получше с этим?» Пока что очень консервативно себя ведём, очень мало чего ломаем, бинарно вообще ничего, а на source-уровне очень-очень аккуратно.

Антон: В этом смысле автоматическая миграция — очень приятная вещь, даже Java 9 сейчас начинает какие-то шаги в этом направлении делать, улучшать deprecated-аннотацию, но, как я понимаю, до Kotlin им ещё расти?

Андрей: Да, мы выработали серьёзный универсальный механизм, которым можем пользоваться не только мы, но и авторы библиотек, и пока это просто мегауспех. Действительно, человек может написать deprecated-аннотацию, и IDE ему автоматически всё смигрирует, и всё классно. Ну, для широкого класса случаев. Какие-то вещи, конечно, не получится, но очень много чего можно смигрировать.

JUG.ru: Поскольку JetBrains занимается и языком, и инструментарием, тут у вас по сравнению с Java козырь на руках?

Андрей: Ну, в принципе, абсолютно ничто не мешает Oracle связаться с нами и сказать «Ребята, мы тут делаем такую штуку, сможете ли вы сделать в IDE поддержку», и мы, конечно, сделаем, никакой проблемы с этим нет. Другое дело — какой у авторов языка mindset, подход к этому. Там просто другой режим эволюции языка. Он на сегодня эволюционирует 100% совместимо. А что касается deprecation всякого разного API, они сейчас просто вынуждены пойти на болезненные для них шаги. Они очень долго колебались с Java 9, и сейчас что-то делают для того, чтобы это было более-менее удобно. И, конечно, весь тулинг, какой только можно, бросится им помочь, потому что есть миллионы программистов на Java, им надо сделать удобно, и тут вообще без вариантов.

Но нам легче в том смысле, что цикл взаимодействия между тулингом и языком короче. Можем очень быстро принять решение, очень быстро заимплементить, посмотреть, как работает — это занимает не месяцы, а дни. В этом смысле у нас, конечно, есть преимущество.

9daaab3d532e4ede8631ce2f9bf7288b.jpg

Компиляция в JS, Kotlin Native и мультиплатформенность в общем


JUG.ru: в выпуске «Без слайдов» СЕО JetBrains Максим Шафиров называл важным преимуществом Node.js возможность использовать один и тот же код на сервере и на клиенте. И появление в Kotlin 1.1 компиляции в JavaScript призвано дать ему то же преимущество. Антон, расскажите:, а для вас как разработчика это действительно имеет значение? Раз у вас в компании все full stack, становится ли Kotlin для вас резко привлекательнее благодаря JS-компиляции?

Антон: Не могу сказать, что привлекательность резко повышается. Обещание JS-поддержки было уже давно, я даже немного это тестировал, но пока не совсем уверен, что использовать один и тот же код на клиенте и сервере так уж полезно. Когда появился Node.js, говорили «всё, это решает все проблемы, full stack на одном языке», но на самом деле это никаких проблем не решило, потому что код для клиента и сервера абсолютно разный, очень мало чего можно переиспользовать.

Поэтому посмотрим, нужно ещё очень сильно поэкспериментировать. А что меня больше интересует — так это Kotlin Native, тоже очень интересный проект или идея, я не знаю, на какой стадии он сейчас находится.

Андрей: Давай расскажу. Сначала два слова про JS и его судьбу: у нас сейчас вышла релизная версия компилятора Котлина в JS, и стандартная библиотека, общая для двух платформ. И это первый шаг в сторону возможности писать многоплатформенные проекты, где действительно можно удобно переиспользовать код, компилировать в разные платформы. Для этого со временем появятся специальный тулинг в IDE и так далее.

И это достаточно широкая история, потому что, если в эту же линейку включить native, у нас получается три класса платформ: виртуальные машины Java, виртуальные машины JS и все нативные платформы, на которых может запуститься Kotlin Native (фактически, всё, что поддерживает LLVM). И для нас это возможность, условно, покрыть все более-менее мыслимые юзкейсы. И наша конечная цель — сделать такой тулинг, в котором можно написать код на Kotlin и скомпилировать его во все три платформы, не меняя. И, соответственно, добавлять к нему какие-то платформенные модули, делая приложения, которые переиспользуют на разных платформах какую-то часть кода.

Что касается Kotlin Native — мы недавно совсем начали, в начале осени, сейчас работаем над первой реализацией. Это полный свой рантайм — он не использует никакой готовой виртуальной машины, только LLVM как инфраструктуру для компиляции. В настоящий момент там поддержана довольно большая часть фич языка. Есть первая реализация управления памятью, и мы уже умеем интеропиться с нативными вызовами. Умеем, например, написать какой-нибудь echo server на юниксовых сокетах или ещё что-то такое, то есть уже можно писать какой-то осмысленный код, который использует стандартную библиотеку C и стандартную библиотеку Kotlin как обёртку над ней. Там ещё куча работы, это совершенно не близко к релизу. И начальная фаза проекта состоит в том, что мы делаем общую работу для всех возможных нативных платформ, базовые вещи: компиляция, управление памятью, линковка со всем, чем нужно, и интероп с нативными API. А дальше нам уже надо будет выбрать какую-нибудь одну платформу, которую первой будем поддерживать совсем-совсем по-настоящему, и мы посмотрим, что это будет — то ли iOS, то ли маленькие embedded-системы, то ли ещё что-то.

Антон: А эта поддержка JS и Native, наверное, будет очень сильно влиять на новые фичи в языке? Например, какую-то фичу, которую на JVM сделать проще, чем на JS, вы решите вообще не делать в Котлине?

Андрей: Я пока не замечаю таких тенденций, скорее наоборот: они подталкивают нас делать некоторые фичи, которые на JVM сделать сложно. Например, value-типы для native очень нужны, нам придётся делать хоть что-то своё для интеропа с value-типами на JVM. Естественно, не такое красивое, как будет в Valhalla, в принципе, ничего безумного, там всё довольно нормально придумали. Такого, чтобы существование другой платформы прямо блокировало какую-то серьёзную фичу, у нас пока не было.

Разве что есть всегда соблазн на конкретной платформе поддержать что-то эдакое, специфичное именно для этой платформы. В native такого больше всего: возможность писать в порты и ещё что-то. Пока у нас довольно неплохо получалось всё это запихивать в библиотеку, и в язык таких безумных вещей не тащить. Вот динамический тип — пример, когда мы поддерживаем какую-то фичу только на JS, потому что это просто специфическая особенность платформы. Будем ли мы когда-нибудь в native и на JVM поддерживать динамический тип — пока не ясно, на JVM ещё есть какие-то юзкейсы, в native пока не придумали. Ну и, собственно, нет юзкейсов — нет и необходимости что-то поддерживать.

То есть у нас нет формальной необходимости портировать 100% котлиновского кода между всеми платформами. Мы стараемся прагматически к этому вопросу подходить: у нас общее видение языка, в некотором смысле «core language», и мы его максимально близко компилируем на разные платформы. У нас есть очень небольшая общая библиотека, а всё остальное каждая платформа может делать немножко по-своему. На JVM есть платформенные типы, и там учитываются всякие особенности JVM. На JS нет ничего, связанного с потоками, и есть, наоборот, динамический тип. В native свои особенности, связанные с value-типами, и это нормально, потому что у нас цель не сделать язык в вакууме, а сделать то, на чём можно писать реальные программы для реальных платформ. И если нужно писать портируемый код, то те модули, которые должны быть портируемыми, будут накладывать какие-то ограничения, которых в той или иной платформе может не быть.

JUG.ru: Недостатки JavaScript стали притчей во языцех —, а каково с JS, когда сталкиваешься с ним не как обычный разработчик, а занимаешься компиляцией Kotlin в JavaScript?

Андрей: Там не так всё ужасно. Безусловно, там свои особенности, но я бы не сказал, что как-то катастрофически хуже, чем в Java. JVM накладывает гораздо больше ограничений, а на JS нет такого прямого мэппинга, какие-то конструкции Kotlin в JS просто не существуют — например, интерфейсов там просто нет ни в каком смысле. С другой стороны, в JVM очень много вещей сделать в принципе нельзя, а в JS ограничения более мягкие.

С точки зрения языкового интеропа это очень развесистая история, но идеологически она такая же, как в Java. Просто в Java есть платформенные типы, которые nullability в некотором смысле стирают, а в JS, поскольку там один тип, то у нас просто есть такой новый в Kotlin динамический тип, который ведёт себя просто как JS-тип: то есть про него ничего не известно, в нём может лежать что угодно, на нём можно вызвать что угодно. И он, в принципе, во многом покрывает потребности такого прямого интеропа, если есть библиотека на сыром JS, то можно с ней взаимодействовать. Но, естественно, инструментарию будет неудобно: во-первых, никакие типы проверять невозможно, потому что их просто нет, во-вторых, негде взять информацию для code completion, каких-то таких вещей.

Поэтому мы опираемся на типизированные заголовки, написанные на TypeScript, это ныне де-факто стандарт типизации для JS. Есть большой репозиторий таких заголовков Definitely Typed, мы даём пользователям возможность их конвертировать в Kotlin. На уровне конвертации возникает очень много творческих вопросов о том, как всё это мэппить на Kotlin, потому что там другая система типов со своими особенностями: если джавовская просто строго слабее, чем котлиновская, то тайпскриптовская просто другая. Но это, к счастью, не очень касается компиляции, это скорее вопрос «как бы нам описать ту типовую информацию, которая в этом TypeScript есть, в котлиновских терминах». По-моему, мы неплохо справляемся, но, опять же, комьюнити нам подскажет, если что-то не очень хорошо.

0fdd43c0bf80433682b3b6eb21b42daa.jpg

Несовершенства


JUG.ru: Всё звучит настолько хорошо со всех сторон, что хочется уже найти где-то подвох. Вот, например, Антон в прошлом году говорил, что для него недостатком стала скорость компиляции — что с этим теперь?

Антон: Я не замерял, но по ощущениям стало лучше. Наверное, помогает компилятор, который запускается как демон, и на тех кодовых базах, с которыми я работал, компиляция сейчас не проблема. Но я ещё не пробовал на реально большом codebase, где может быть сотни тысяч классов или что-то такое.

Андрей: А скажи, пожалуйста, вы инкрементальной компиляцией пользуетесь?

Антон: Да, конечно. Как минимум, в IDE. Думаю, как раз без инкрементальной компиляции проблема и есть.

Андрей: Ну да, мы вложили довольно много усилий в то, чтобы инкрементальная компиляция работала быстро, чтобы она работала не только в IDE, но и в Gradle, и мне кажется, что там очень хорошие результаты. У меня тоже нет претензий ко времени компиляции, когда я программирую на Kotlin. Тем не менее, мы совершенно не закончили работу над перформансом компилятора, там ещё куча всего планируется. Для нас это тесно связано ещё и с производительностью в IDE, потому что компилятор в IDE переиспользует очень много кода. И мы планируем в следующем релизном цикле, в 1.2, посвятить много времени как раз улучшению перформанса.

JUG.ru: Есть ещё такое несовершенство. У Kotlin в числе главных selling points есть null-safety и удобство интеропа с Java. Однако два этих преимущества оказываются взаимоисключающими: в интеропе с Java лишаешься null-safety, из Java может прилететь неожиданный null.

И теоретически может оказаться так, что разработчик увидит на сайте слова «Avoid entire classes of errors such as null pointer exceptions», загорится, но поскольку большой проект никто не переведёт сразу на Kotlin и ему придётся постоянно взаимодействовать с Java, в итоге он только разочаруется.

Вопрос:, а практически отпугивает ли это людей от языка?

Антон: Вряд ли отпугивает. Я бы даже сказал, что было очень мудрым решением незадолго до версии 1.0 сделать так, чтобы платформенные типы не были все nullable. Иначе было бы полным адом писать на языке, используя стандартные Java-библиотеки. Так что это был такой трейд-офф, и, на мой взгляд, всё-таки хороший. Конечно, нужно немного опыта, чтобы понять, что на Kotlin при использовании каких-то джавовских классов иногда нужно специально объявить тип, когда ты знаешь, что оттуда должно прийти — nullable или не nullable, чтобы компилятор потом не гадал. Иначе точно так же, как и в Java, получишь потом в рантайме исключение. Но, в принципе, то, как это сделано сейчас — хорошо сделано.

Андрей: Действительно, вопрос nullability при интеропе с Java у нас сожрал кучу времени до релиза 1.0. Я думаю, что в сумме это задержало релиз примерно на год, потому что мы пробовали несколько разных схем интеропа в связи с nullability, кажется, три или четыре. И первые n были неудобными, просто код писать было тяжело: либо код просто получался плохой, либо конфигурация была слишком сложная, что-то всё время не работало. Мы пришли к текущему варианту, и я согласен с Антоном в том, что он очень неплохо себя зарекомендовал.

Я не помню таких жалоб «как же так, вы обещали null safety, а у меня тут джавовская библиотека и null safety с ней нет». Люди не ожидают от нас чуда, очевидно, что если Java, то извините… Хотя, на самом деле, есть исключения даже из этого правила. Это требует дополнительной работы от автора Java-библиотеки, но можно и её так проаннотировать прямо в коде, чтобы Kotlin понимал, что там с null«ами, и всё правильно делал. В IDEA у нас большая часть кода проаннотирована, и там вообще всё отлично, потому что Kotlin просто знает, где в Java null, а где не null, и джавовская IDEA тоже знает, и ругается в Java. Если кто-то реально хочет себя защитить от таких проблем даже на стыке Kotlin и Java, то возможность есть, но это требует работы.

Антон: Андрей, а ты видел интереснейший пост Uncle Bob как раз на тему Kotlin и nullability?

Андрей: Видел, видел.

Антон: Он хорошо прошёлся по этой nullability, мне интересен твой комментарий.

Андрей: После того, как на это обратило внимание много народу, я прочитал… Он написал в общей сложности три поста (по крайней мере, когда я в последний раз смотрел). И посыл примерно такой: когда-то были языки без типов, потом языки с типами, потом снова стали популярны языки без типов, такой маятник качается туда-сюда, сейчас маятник качнулся в сторону типов и ушёл за точку баланса. У нас больше типов, чем надо.

Во-первых, это предполагает, что Uncle Bob знает, где точка баланса. Ну хорошо, он знает, а я думаю, что я тоже знаю, и у меня другое мнение. В этом месте можно просто обменяться мнениями.

Во-вторых, там есть некоторые конкретные аргументы «как же, если я, например, сделал какой-нибудь тип в своей программе nullable, то мне ж теперь надо поменять всю остальную программу, чтобы эта программа скомпилировалась». Этот момент я не понимаю, потому что — да, конечно, нужно что-то поменять, это содержательно. Если какой-то тип стал nullable, значит, код, который этот тип использует, должен учесть этот факт, иначе он будет неправильно работать! И, конечно, этот код надо поменять. Ну, можно его запустить, получить исключение, и поменять потом, а можно просто сразу поменять. Вот в Kotlin надо сразу.

Там ещё есть какие-то аргументы, аналогии с const в C++, ещё чем-то — эта аналогия не совсем корректная, по-моему.

Антон: При всём уважении к Uncle Bob, мне тоже кажется, что он просто использовал возможность ещё раз сказать «вы всё равно должны писать тесты для своего кода, и компилятор вас не спасёт». В чём он, в принципе, прав, но мне лично очень нравится в Kotlin эта фича с nullability, может быть, для меня это даже одна из основных фич, ради которых хочу писать на Котлине. С другой стороны, бывает такое, когда Kotlin не позволяет мне легко описать то, что я хочу, компилятор говорит, что я должен где-то поставить либо ?, либо !… В последнее время, когда у меня всё больше опыта с языком, мне всё меньше приходится бороться с компилятором, но есть такие кейсы. Для этого есть ещё ключевое слово lateinit, которое иногда помогает. Так что есть и плюсы, и минусы, но мне кажется, что всё-таки уклон ушёл в правильную сторону, что от этого больше пользы, чем неудобства.

Андрей: Безусловно, я согласен, что минусы есть, но за всё надо платить. Если мы хотим, чтобы компилятор что-то гарантировал, то требуется какое-то количество работы с нашей стороны. Здесь просто вопрос, что более оправданно. По-моему, опыт нас самих и всех остальных людей с Kotlin показывает, что введение nullable-типов вполне оправдано, получилось хорошо.

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

JUG.ru: Сейчас, когда Kotlin взлетает, может возникнуть эффект серебряной пули: многие примут его за панацею, решающую все возможные проблемы. Поэтому есть такой вопрос: о том, чего можно ждать от Kotlin, уже много говорилось, а вот чего от него ждать не надо?

Антон: Не стоит от любого языка программирования ждать того, что он исправит дизайн твоего собственного кода. Почти все проблемы, которые я вижу в программировании, связаны не с языком, а со структурированием программы. И в этом смысле ни Kotlin, ни любой другой язык не поможет. Он может дать какие-нибудь тулзы для этого, чтобы это было удобнее сделать — например, в Kotlin очень легко делается делегирование. Но свой код нужно уметь дизайнить независимо от языка.

Андрей: Я поддерживаю Антона, скажу просто другими словами. Мы пытались сделать Kotlin удобным языком, и как удобный язык он убирает лишнюю сложность, которой по смыслу нет в голове у программиста. А ту сложность, которая соответствует программе, тот смысл, который вкладывается в программу, никакой язык программирования не уберёт. Эту сложность в любом случае приходится структурировать и организовывать.

Ещё не стоит ожидать других чуде

© Habrahabr.ru