Прочитал официальную документацию к Котлин. Написана, кстати, очень хорошо — больше похоже на увлекательную книгу, чем на формальный мануал. Однако выводы, если вкратце: Kotlin бодро развивался все последние годы, поэтому фич в нём нормально уже так. Уже не слегка подрихтованная Java. Однако он всё ещё «половина от Scala», увы. Правда, половина он всё-таки потому, что и Scala тоже всё это время не стояла на месте. Если сравнивать с версиями пятилетней давности — уже процентов восемьдесят наберётся. Несмотря на распространённое мнение, всецело базирующееся на пиаре, а не на знании обоих языков, Kotlin, внезапно, не проще, чем Scala, а сложнее. Не так, чтобы сильно сложнее, однако заметно сказывается то, что концепции в Scala гораздо более «регулярные»: один раз понял — в ста местах используешь. В Kotlin же оно всё более локальное, а потому как бы в каждом месте там надо понять свои собственные концепции. В результате, в сумме их оказывается больше, однако больше возможностей они от этого давать не начинают. Вместо этого дают чуть-чуть меньше. Опять же, несмотря на распространённое мнение, всецело базирующееся, ну вы поняли, в Kotlin нет того, про что можно было бы сказать «ну, зато там есть вон та штука, которая компенсирует и просветляет». Да, Java он обогнал по очень многим фишкам, но вот Scala — ни по одной. Самый топчик в этом смысле: отдельные фишки записываются чуть-чуть короче и/или сразу встроены в стандартную библиотеку, а на Scala пришлось бы один раз написать три–пять строк, чтобы их добавить в столь же универсальном виде. Обратное, кстати, в основном не работает: многие фишки Scala невозможно добавить в Kotlin на уровне пользователя языка — только плагинами к компилятору или вообще его переписыванием. Видно, что Kotlin как бы делает реверансы в сторону сторонников «старого доброго на новый лад» — там многое заточено под обработку null, try-catch, «традиционные» циклы и т.п. С одной стороны, это вроде бы упрощает вхождение в язык, с другой стороны, вместе с тем тормозит вхождение в его более продвинутую часть. Поскольку соблазняет не тратить полчаса на понимание того, как всё то же самое можно написать в пять раз короче и в десять раз универсальнее, а вжарить как умеешь на данный момент, отложив все разбирательства на бесконечный потом. Некоторые вещи, которые есть в Scala, но отсутствуют или сильно урезаны в Kotlin, — реальные серебряные пули для тех, кто с ними разобрался. Без них вообще пипец как тяжело и муторно. Чтобы был понятен масштаб проблемы, приведу аналогию про современный и даже уже слегка устаревающий мэйнстрим: представьте, что вам дали язык, где у контейнеров нет итераторов, невозможна их реализация и нет никакой поддержки языком хоть каких-то их аналогов. Доступен только старый добрый цикл со счётчиком и «ручная» разборка связного списка в цикле while. Ну да, писать, конечно, можно — когда-то ведь так и писали. Однако пятая точка будет полыхать каждый раз, когда понимаешь, что вот тут можно было бы написать хотя бы for-each, но его нет. За единственную заметно отличающуюся фишку могут сойти корутины: вот их для Scala так пока ещё и не реализовали. Однако весьма вероятно, что не реализовали их именно потому, что даже встроенный в стандартную библиотеку подход Future–Promise по длине и удобочитаемости кода оказывается почти неотличимым от подхода с корутинами, но при этом реализует универсальный интерфейс контейнеров, а потому не требует постижения своего особого жаргона. Фактически, если отвлечься от некоторых опциональных элементов тонкого управления потоками и подписки на результат, всё остальное во Future неотличимо от контейнера с одним элементом (как и в Option, например), а потому понявший как пользоваться контейнерами в Scala, практически один в один переносит своё понимание на обращение с Future. Подумываю написать сравнение прямо по разделам документации с примерами. Но соберусь ли… Эх. doc-файл