Комментарии 20
Очень сильно хотел увидеть недостатки Котлина. А не процесса его разработки.

По недостаткам о технологии можно понять гораздо больше, чем по достоинствам.
Из другого интервью
Заголовок спойлера
— Хочется поговорить о проблемных местах. Продолжая разговор про обратную совместимость: а было ли за годы работы над Kotlin принято какое-то значимое решение, о котором впоследствии пожалели, но было уже поздно менять?

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

Одна — это делегирование классов, возможность имплементировать интерфейсы делегированием. Хорошо было бы, если бы мы не зарелизили это в своё время в 1.0 и взяли побольше времени на то, чтобы это подизайнить. В 1.0 у нас ещё не было понятия экспериментальных фич. В итоге получилась очень негибкая фича, и очень сложно как-то её развить. Мы в этой области не сделали никаких позитивных шагов за два года, потому что это попросту слишком сложно, она сопротивляется. И что с этим делать, пока непонятно, будем думать дальше, как сдвинуться с этой мёртвой точки.

И вторая такая же проблемная фича — это companion objects. Там развитие какое-то есть, но это тоже слишком сложная в поддержке история, потому что много завязок в разные места. Было бы здорово, если бы мы в своё время потратили побольше времени на дизайн этой фичи. Но мы не догадались, что это такая серьёзная точка риска, и не вложили туда больше ресурсов.


Ещё есть доклад про заимствованные из других языков идеи

Однажды я писал примерно вот такой код:


val handler = Handler()
val action = { println("Hello world!!!") }
handler.post(action)
handler.removeCallbacks(action)

handler.post(Runnable) добавляет Runnable в очередь на выполнение, а handler.removeCallbacks(Runnable) удаляет Runnable из этой очереди. Судя по коду, строка Hello world!!! не будет напечатана, но она печатается. В чем же дело?


Оказывается лямбда имеет тип Function0<Unit>, а handler.post(Runnable) и handler.removeCallbacks(Runnable) принимают в качестве аргумента Runnable, и котлин для удобства и бесшовной интегреции с Java оборачивает лямбду в Runnable и получается, что в очередь добавляется один Runnable, а удаляется другой.


Для того, что бы исправить ситуацию, нужно добавить Runnable перед лямбдой, вот так: val action = Runnable { println("Hello world!!!") }. Теперь action имеет тип Runnable и ничего не оборачивается и корректно работает.


Получается, что в данном случае проблема в том, что компилятор много на себя берет и скрывает часть своей работы от программиста с расчетом на то, что этот сахар ничего не сломает.

У меня, честно говоря, в голове не очень укладывается: если я вот прямо сейчас начну делать язык программирования, да ещё и "наберу команду" — моих сбережений хватит в лучшем случае месяца на 3 работы. Откуда у Бреслава такие ресурсы?

Те ресурсы, о которых вы спрашиваете — ресурсы JetBrains.

О, удачный код для обсуждения Котлина. myself в данной функции имеет тип Person?. Хотя скорее всего подразумевается, что Я уж точно существую. Как идеоматичнее быть в данном случае? Не хотелось бы использовать оператор !!, т.к. его использование расслабляет и плявляется соблазн использовать его повсеместно, что сводит на нет все плюсы котлина с точки зрения null безопасности. Можно написать ?: return, но это так же плохо как и пустой блок catch при обработке исключений. Наверное правильнее было бы бросить исключение: ?: throw IllegalStateException("Myself is not exists?!"), но не слишком ли много писанины ради ситуации, которая никогда должна случиться?
Кстати, если не менять код, то we будет иметь тип List<Person?>, что выглядит так же странно.

Все так, если бы не слишком важен был бы эксепшен — я бы просто использовал first.
Return может иметь смысл в зависимости от контекста.
Ну и самый общий случай это кидать после элвиса свой "бизнес" exception.
Делать методы которые принимают Person? в данном случае конечно не стоило

А, про first я забыл. В данной ситуации, на мой взгляд, похоже лучше всего подходит.

throw IllegalStateException(...) можно записать короче — error(...). Функция именно это исключение и бросает

Kotlin прекрасен, какие ещё недостатки?
Разве что после Java не хватает тернарного оператора.
Я думаю что если человек смог оправдать динамическую типизацию, то ему надо идти в адвокаты, ибо он может оправдать кого угодно.

В Котлине статическая типизация. var в Java и auto в C++ не делают же их динамически типизированными.

Конец посмотрите. Где Андрей Бреслав, оправдывает существование ЯП с динамической типизацией, теоремой о неполноте Гёделя. :-)
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.