Комментарии 150
Основаная проблема Ceylon — нет вакансий.
Ребят, я не говорю, что боюсь изучать новую платформу или язык. Я говорю о том, что эти знания несильно востребованы на рынке. По опыту, весьма часто требования диктует не разработчик (особенно новый, особенно, в моём случае, джун-мидл, поскольку не занимаюсь, увы, JVM или компиляцией экзотики в JS), а заказчик или команда. Такие дела.
Если у человека в резюме стоит экзотический язык, например Common Lisp — с вероятностью процентов 90 это весьма приличный разработчик.
Либо он учился на математическом факультете, где учат только лиспу, умеет доказывать теоремы, но к практическому программированию не готов :-)
Что то я не встречал студентов-математиков со знанием Лиспа :). Я лучше не буду про преподавание ИТ специальностей в ВУЗах, ибо будут непечатные слова. Так скажем, типичный выпускник прикладной математики в лучшем случае в настоящее время паскаль знает.
Обычно изучается это все самостоятельно, SICP и тому подобное. Но я реально знаю двух людей с 4-мя годами коммерческого опыта на Common Lisp.
Т.е. было такое, когда заказчик скажем говорит — у нас куплены Oracle и Weblogic, делаем на них (версии такие-то). Но при этом спокойно можно было параллельно брать любой другой инструмент, который повышает вашу производительность или качество кода. Вменяемый заказчик — только за такое.
Сейчас вот на моем бывшем проекте, откуда я ушел, пытаются переписывать на котлин. Я бы этого не стал делать (не потому что язык плох, а скорее потому, что основные проблемы лежат не в той в плоскости, чтобы их решал другой язык разработки), но опять же — заказчику все равно, ты разработчик — ты и выбирай инструмент. Если он бесплатен и хоть более-менее распространен — как правило всем кроме вас это до лампочки.
Основаная проблема Ceylon — нет вакансий.
Эта основная проблема только для кодеров.
А для софтверного инженера, который звучит гордо, выбор путей решения (в том числе и выбор нужных именно ему самому инструментов) — даже, я бы сказал, рутина.
С этими равенствами, кстати, я уже в Котлине обжёгся.
if(type === TYPE_VARIABLE || type === TYPE_PARAMETER || type == TYPE_FUNCTION ||
type === TYPE_METHOD || type === TYPE_FIELD) { ... }
Заметили опечатку? В джаве такая опечатка невозможна, а в Котлине/Цейлоне — легко (и я их видел в реальном коде).
Опечатку то я заметил.
Ну, в Ceylon я б такое написал как:
if (type in {typeVariable,typeParameter,typeFunction,typeMethod,typeField}) {...}
И вообще то, за все время написания на ceylon мне ни разу не приходилось использовать === оператор. Я даже забыл что он есть :).
Разумеется, вы заметили опечатку, перед вами же две строчки кода, а не проект из тысячи файлов, в одном из которых опечатка. Зачем же был введён ненужный оператор? :-) В дизайне языка самое главное — не решить, что в него добавлять, а решить, что в него добавлять не стоит. С этим, кстати, очень большая проблема у груви (@RockPresident привет). Грувисты всегда хвастаются тем, что у них есть, но не могут похвастаться тем, чего у них нету. Котлин гораздо лучше именно потому, что в нём меньше фич. И то несмотря на юный возраст Котлина, в нём уже есть лишние вещи.
upd: немного опоздал.
Вероятно, Red Hat не пиарят его так, как это делаю JetBrains, Google, Mozilla и Apple свои языки
Вообще что в нем есть, чего нет в Scala?
А вот необходимость писать return после Scala отпугивает.
А for в Ceylon c монадами работает (Future и тп)?
При необходимости можно использовать такие же приемы, как на Java 8 и Scala. Например вся асинхронность к меня завернута в rxJava. И далее всякие композиции, map, flatmap и и.д. Хотя, если честно, предпочел бы async await функциональность, которой пока нет — это ИМХО более читаемо.
Если имеется в виду код:
for {
r1 <- future1
r2 <- future2
r3 <- future3
} yield (r1+r2+r3)
То на ceylon он бы выглядел как:
value r = {
for (r1 in future1)
for (r2 in future2)
for (r3 in future3)
r1 + r2 + r3
}
Естественно это все нужно предварительно заврапить
for в Ceylon получает блок? Я могу написать аналог
for {
r1 <- future1
r2 = r1+1
r3 <- future3
} yield {
r2/r3
}
На ceylon это будет примерно так:
value r = {
for (r1 in future1)
let(r2 = r1 + 1)
for (r3 in future3)
r2 / r3
}
На деле это обычный for. Future в данном случае должна быть просто Iterable, просто возвращая одно значение. Для каждой итерации будет выполнен код, который идет после for. И далее это все обернется в ленивый Iterable. Если нужно не лениво, то вместо {for ...} будет [for ...] или можно {for ...}.sequence
Только скобки в for и let смущают, как-то не ожидаешь, что описаные величины внутри скобок будут доступны в объемлющем блоке. С таким с только в макросах сталкивался.
В частности в котлине не написать метод, аналогичный mempty из haskell, Monoid[T].empty из scala и Default::default() из rust.
На самом деле «implicit classes» — это частный случай к implicit conversion. И по сути это ближе всего к extension methods, но с тем важным отличием, что возможно не только добавление отдельных методов, но и приведение к интерфейсам.
Хотите подробней — я ниже ссылку кинул — лучше Одерски я не расскажу, но могу ответить на конкретные вопросы, если возникнут.
Как минимум это полезно при написании DSL. На Scala можно написать очень навороченные DSL практически любого синтаксиса. В этой области Scala рулит и рулит просто неимоверно. На Kotlin возможностей по написанию DSL будет поменьше, некоторых вещей будет не хватать. На Ceylon ситуация хуже, чем у Kotlin. За счет обязательной точки с запятой и из за того, что вызов функции всегда идет с указанием скобочек, и нельзя аргументы передавать через пробел. Но намного намного лучше, чем на Java.
Но вообще, 3 языка вполне имеют право на жизнь в настоящее время, у каждого из языков есть свои сильные и слабые стороны. Ни Scala, ни Kotlin, ни Ceylon, не являются серебряной пулей, подходящей ко всем задачам.
case(is String)
не превращается ли switch просто в более красивую запись дерева условий?Со switch там интереснее. Как это под капотом, по существу не важно, это 100 раз могут безболезненно поменять
У switch там совсем другое назначение по сравнению c Java. Именно в Java я его практически не использую, кстати, ибо вероятность что я там ошибусь и поставлю break достаточно высока.
Предположим у меня тип
Integer|Exception i = Integer.parse("56);
Или же что поинтереснее:
Integer|Exception|Complex p = doComplexParsing("345|45");
Если я делаю switch(p)
То сама IDE заставит меня и сгенерирует код для обработки всех возможных вариантов p
То есть
case(is Integer) {}
case(is Exception) {}
case(is Complex) {}
И если какого case не будет или не будет else, то ругнется компилятор, что я не все возможные значения отработал. За счет чего использование switch в Ceylon очень даже приветствуется.
Ну и также когда switch используется совместно с tuple, entry и деструктуризацией — получается весьма неплохой код, почти паттерн матчинг.
Ну и то, что это выражение, а не оператор, удобно.
К сожалению нет.
Для полноценного хотелось бы:
case(Person("Vasja", 33)) { print("this is Vasja 33")} //не поддерживается
case(Animal(name)) {print(name);} //не поддерживается
case(["56", a]) {print(a)}; //не поддерживается,придется делать case([String str, Object a]) {if (str == "56") {print(a)}};
Жить можно без чего угодно. На Java нет даже близко ничего подобного, и народ как то не жалуется. Ибо про альтернативы не знает. Частые use case язык покрывает, остальное возможно появится в будущем. На практике очень часто используются кортежи и их деструктуризация, соответственно для значительной части задач этого хватает.
Так это же библиотеки, а не сам язык. За счет библиотек можно сделать ОЧЕНЬ многое на любом языке. Вот только библиотеки — это не забыть добавить зависимости, не забыть про статик импорты, выглядит это чужеродно, большинство разработчиков про такое не знают ибо не всегда распространено, в конкретной конторе такую библиотеку могут вообще запретить к применению ибо каждую внешнюю либу нужно согласовывать в 10 инстанциях и т.д. Нужно следить за версиями библиотек и их зависимостями и тому подобное. Можно все, на любом языке. Хотя бы кодогенерацией :). Вопрос в лишних телодвижениях. В свое время я делал эти телодвижения и считал, что Java прекрасна ибо на ней можно все. А потом попробовал альтернативы, когда много полезного уже есть из коробки. И обратно то уже не хочется ...
>На Java нет даже близко ничего подобного
Это все-таки не совсем верно. Есть многое, хотя и не совсем таким же образом реализованное. Тот же ломбок, к примеру.
Ну и сделать такое можно далеко не в любом языке, и вообще говоря, когда не было лямбд, сделать такое в Java было практически нельзя (либо было чрезвычайно неудобно пользоваться).
Т.е. мысль-то моя простая — если язык позволяет сделать библиотекой то, что в другом языке требует изменений компилятора — это хороший, годный язык. Ну, типа лиспа :)
Когда не было лямбд, любители функциональщины прекрасно жили через анонимные классы :). И IDEA даже сворачивала эту громоздкость и код читался практически так же, как в случае с лямбдами :). А когда вышла восьмерка, тот код средствами той же IDEA стало возможным по хинту преобразовать в код с лямбдами, при этом практически ничего и переписывать не приходилось и все продолжило выглядеть так же, как и выглядело.
На деле, да факто куча недостатков Java можно сделать путем умной IDE. громоздкий синтаксис можно скрывать и т.д, сложные конструкции писать за тебя. Но что то мне подсказывает, что такой путь немного сомнительный. Это де факто получается другой язык, но жестко завязанные на конкретную IDE.
Ну и все-таки, размеры кода сильно сократились в итоге, что позволило его быстрее писать и легче читать.
Ага, можно ещё Advanced Code Folding поставить, вообще другой язык будет :-)
Вот 33 — это у нас что?
Это int, также как в Java 33 это int а не long, short, byte, float, double
от в данном случае Person(«Vasja», 33)
Должен быть конструктор который принимает String и int.
call("Vasja", 33)
Откуда вы знаете какой метод будет вызван? Который принимает массив char'ов? Объект с toString()? StringBuilder/StringBuffer? Своя кастомная коллекция с char'ами?
поэтому оверлоадинг — отстой
Т.е. вы называете методы callStringAndInt?
На самом деле без оверлоадинга в Ceylon можно жить достаточно комфортно. Во первых, оверлоадинг при необходимости делается через Union Types. Метод один, он принимает определенные аргументы, а аргумент может быть или одного типа, или другого. А далее в обработчике либо сразу учитывать логику, либо уже делегировать специфичным непубличным методам. Во вторых, в Java большинство оверлоадинг методов нужны, так как там нет параметров по умолчанию. В третьих, если уж ну совсем приспичило с оверлоадингом, что ну никак не исхитриться (мне не доводилось с таким сталкиваться, но мало ли), то никто не запрещает написать нужную логику на Java, и вызывать этот оверлоадинг из Ceylon.
оверлоадинг при необходимости делается через Union Types
Т.е. вместо того чтобы в compile-time знать какой метод надо вызывать, мы теперь будем в run-time определять?
Во вторых, в Java большинство оверлоадинг методов нужны, так как там нет параметров по умолчанию.
Так ведь тогда и конструктор будет один и не будет неоднозначностей
Да, в рантайме. Да, перфоманс. Но про перфоманс я уже ответил.
По поводу оверлоадинга — любопытная статья относительно того, что функционал оверлоадинга весьма затруднил появление в Java лямбд из за чего было множество сложностей и багов.
https://objectteams.wordpress.com/2017/04/02/several-languages-java-8/
Плюс все радости оверлоадинга, когда код может внезапно без палева начать работать по-другому, потому что ты определил более специфичный метод/конструктор.
Вы пишите тесты? И как часто вы определяете более специфичный метод/конструктор?
А это тут при чем?
образовалось: 95% написанного кода работают сразу, как удовлетворил компилятор еще до запуска
Потому что не 100%. Вы все ровно пишите тесты и можете проверить какой метод вызвался. А с паттерн матчингом еще и код более читабельный.
Ну так далеко зайти можно. Например, выкинуть типизацию и писать вместо этого тесты.
Писать тесты проше чем " линейными типами и единственностью реализации какого-нибудь тайпкласса для типа, описывающего процесс регистрации"
Использовать типизацию проше чем писать тесты.
Сторонники динамической типизации будут спорить. (:
Писать тесты проше чем " линейными типами и единственностью реализации какого-нибудь тайпкласса для типа, описывающего процесс регистрации"
Зависит от того насколько удобно это реализовано в языке.
Независимо от того, насколько удобно это сделано, такая проверка является неправильной.
Если тайп-классы настолько мощные, что гарантируют правильность работы программы — то они сами нуждаются в тестировании. Возможно, тест нужно будет писать не динамический, а статический — но его все равно нужно писать.
Интерполяция строк
Это как бы более умная и читабельная версия String.format() из Java, встроенная в язык:
value x = 4; value y = 7; print("sum of ``x`` and ``y`` is ``x + y``"); // sum of 4 and 7 is 11
ИМХО синтаксис здесь будет поприятнее, чем в Kotlin, с Java даже не хочется сравнивать.
Kotlin
val x = 4
val y = 7
print("sum of $x and $y is ${x + y}") // sum of 4 and 7 is 11
и что вам тут не нравиться?
Знак ${}.
Приведу цитату из FAQ непосредственно от разработчиков языка https://ceylon-lang.org/documentation/1.3/faq/language-design/#string_interpolation_syntax:
Why not "Hello $name" or "Hello ${name.uppercased}"?
Primarily because it looks a bit cleaner for defining text in user interfaces or other treelike structures.
Html hello {
Head head { title="Greeting"; }
Body body {
P { "Hello ``name``. Welcome back!" }
}
}
We did originally investigate the ${...} syntax, but it turns out that syntax would require a stateful lexer and, since } is a legal token in the language, is more fragile when editing code in an IDE. Anyway, some of us just don't love seeing dollar signs all over the place. It reminds us of languages we don't like.
Anyway, some of us just don't love seeing dollar signs all over the place. It reminds us of languages we don't like.
Т.е. не нравится Java, но синтаксис уноследовали, а знак доллара не нравится, его не взяли.
Синтаксис Java унаследован частично. Например не public, а shared, не implements а satisfies и т.д. Из Java в основном идет имя типа слева от переменной, ключевой слово class и фигурные скобочки. Сам язык просто создавался с нуля, с учетом того хорошего, что было до этого.
P.S. Мне тоже `` напоминает кое-что из того, что хотелось бы забыть.
Хочу рассказать о новом языке программирования, который называется Ceylon
Kotlin не вчера появился, но Ceylon по моему, старше Kotlin-а лет так на 5 или 6, у него первый стабильный релиз был в 2011, когда Kotlin только только зарождался.
В отличие от Kotlin обошлось без ключевого слова downTo.
value n = 10;
value m = 2;
for (i in n..m) { ... }
Ceylon в рантайме делает проверки?
n..m это просто синтаксический сахар для Range.
Внутри код вроде:
shared actual
Element[] span(Integer from, Integer to) {
if (from <= to) {
if (from <= to) {
Т.е. каждый раз проверяется в рантайме :(
А если нам надо чтобы цикл выполнялся только если n < m?
И тот и другой 2011. По сравнению со Scala, которая в 2003 появилась. Scala стала мейнстримом где то последние года 4, по крайней мере на scala можно найти работу без проблем. Kotlin стал настолько популярен, что на нем можно найти работу — тоже только в последние несколько лет. Но на Ceylon тоже можно работу найти, у меня получилось, когда я искал работу на Scala или Kotlin :):):).
Что считать стабильным релизом на самом деле еще и вопрос. Первая стабильная версия 1.0.0 в 2013 году. В гораздо более стабильном языке я лично зарепортил весьма немало багов, некоторые даже сам и поправил :).
Читаю все эти статьи и не пропадает впечатление что авторы просто не слышали о языке Groovy? В котором всё это уже есть лет 10, да плюс ещё огромное количество настолько же полезных возможностей. Стабильный язык, почти полная совместимость с .java кодом (и причём не такая где можно использовать другие java библиотеки, а в том смысле что можно просто взять .java файл, и он скомпилируется groovy сразу), полное решение всех verbosity проблем которые есть у джавы, куча паттернов позволяющих быстро прототипировать и вообще писать код, хорошая читаемость, узнаваемость, convention over configuration, свободный выбор между static type compilation/dynamic type compilation, (причём на уровне отдельных классов или даже методов!) и так далее.
Автор, если вы не пробовали Groovy, обязательно сделайте это.
1) Как у groovy с иммутабельностью по умолчанию?
2) Как там дела с for comprehensions?
3) как там дела с деструктуризацией кортежей, причем чтоб деструктуризация была прямо в лямбдах?
4) Как там с женериками? Можно ли в groovy у List узнать в рантайме тип T?
1. По умолчаню — никак. А вообще примерно как в Java, можно написать аннотацию Immutable, т.е. по сути — на уровне обработки AST где-то достигается. Встроено в язык.
2. В принципе. средства расширения языка (включая и лямбды сюда же) вполне позволяют например написать свой цикл until, имея только лямбды. Не задумывался об этом, но подозреваю, что можно сделать вполне пригодное что-то.
3. Простой запрос гуглю отвечает ссылкой http://groovy-lang.org/semantics.html#_object_destructuring_with_multiple_assignment, которая показывает, что это тоже одна из возможностей расширения языка. Т.е. есть multi assignment, и можно кое-какие методы объекту дописать, чтобы он деструктурировался. Не блестяще наверное, но напомню — этому языку уже лет 10.
4. По-моему также, как в Java. Тип T можно узнать, он сохраняется в байткоде, но скажем так — не слишком прямолинейно это делается. Я подозреваю, большинство программистов про этот способ не слышали. TypeToken например погуглите, это из guava. Type erasure тут сильно мешает, и язык мало что может с этим сделать (разве что нарушив совместимость с Java на уровне байткода, что мы видим на примере скалы).
Писать аннотацию Immutable самому даже не нужно, она уже есть: http://docs.groovy-lang.org/2.4.7/html/gapi/groovy/transform/Immutable.html
И самое интересное то что про производительность — везде где ищу информацию об этом — оказывается что нет никаких проблем с ней. Проблемы были когда-то в начале, все по одной лишь той причине что Groovy по умолчанию использует динамические типы. Потом встроили аннотацию статической компиляции, которая по сути делает производительность такой же как у Java.
На последнем конгрессе Groovy говорили что все текущие проблемы по сути из-за плохого пиара языка, в то время как технологически, по сегодняшним меркам, Groovy в выигрыше по сравниению со многими.
Но всё-таки хочется уточнить:
можно просто взять .java файл, и он скомпилируется groovy сразу
Это true только для java-файла до 1.7 включительно. Лямбды из 1.8, например, не скомпилируются.
Уже не долго. Срок поддержки заканчивается в 2020 году. Django, ipython больше не поддерживают 2 ветку. В Heroku теперь версия по умолчанию — 3.6
Что вы имеете ввиду? Насколько мне известно любой Java код можно вызвать из Scala, наоборот нет и это очевидно.) Scala более богатый на возможности язык чем Java.
Наоборот тоже прекрасно вызывается. Через одно место, громоздко, криво, но вызывается :).
Наоборот нет? Я помнится извращался, и вызывал Scala код не только из Java, но и из Ceylon.
И Scala, и, как оказалось, Kotlin не на 100% совместимы с Java, ваши комментарии по этому поводу?
C Java как языком, или с некоторыми Java библиотеками и некоторыми тяжелыми серверами :)? Именно с взаимодействием с Java проблем нет. Как в одну, так и в другую сторону. Например я люблю в IDEA в момент точки останова делать evaluate expression, и вызывать непосредственно нужный метод. Я это любил делать в Java — я продолжаю таким заниматьсяи в Ceylon, хоть и мне приходится знать как ко всему этому достучаться из Java. Возможно с выходом Java 9 на начальном этапе будут какие то мелкие проблемы, а может и крупные, пока нормальной поддержки Java 9 не появится в языке. До версии Ceylon 1.3.0 были мелкие проблемы с взаимодействием с Java 8, но тоже вполне решаемые.
Почему столько вариантов и чем они друг от друга отличаются? (Кроме очевидного by.)
Включая, не включая, в обратном порядке, c шагом, проверка на нахождение в диапазон в if. Там можно и поболее вариантов привести.
И самый главный вопрос, почему же стоит переходить на Ceylon или Kotlin?
Про это будет далее. Если коротко в этих языках исправлены фундаментальные недостатки Java. А именно — многословность, мутабельность по умолчанию, проблема c null safety. Весьма поднимает это все производительность разработки.
В Kotlin выкинули овеществленные дженерики чтобы со стороны Java код выглядел нормально. Без этой жертвы странно говорит про 100% или даже 99% совместимость с Java.
Я немного не понимаю какие тут большие проблемы. Вот код использования из Java ceylon ArrayList вместе с цейлоновскими же строками:
ceylon.collection.ArrayList<ceylon.language.String> ceylonStrArr = new ceylon.collection.ArrayList<ceylon.language.String>(ceylon.language.String.$TypeDescriptor$);
ceylonStrArr.add(ceylon.language.String.instance("I am adding ceylon string from Java"));
Специально не убирал явные имена пакетов, из за чего здесь это выглядит громоздко. Все проблема с овеществленными женериками из Java некрасивый $TypeDescriptor$ в конструкторе.
Единственная практическая проблема с вызовом из Java кода кода на Ceylon заключается в IDE. IDE да, пока не видит из Java цейлоновские классы. Из за чего внутри среды разработки Java код, вызывающий Ceylon код выглядит красным. Но это компилируется и запускается. И эта проблема актуально только в том случае, если проект изначально цейлоновский, и я мешаю там вызовы из Java в Ceylon. Если же цеплять jar, написанный на Ceylon к уже существующему проекту, то таких проблем не будет. Но рано или поздно это пофиксят, соответствующая бага давно заведена.
API где нужно всюду передавать $TypeDescriptor$
не назовешь идиоматичным Java кодом.
Я хотел еще раз подчеркнуть что в Kotlin трактовке "совместимость в обе стороны" подразумевает идиоматичный вид Java из Kotlin и Kotlin из Java. Мне кажется этот очень важный факт принижается в статье с отмашкой "где мы такое не видели".
наверное заминусуют сейчас люто, но!
вы видели современный swift? Там все тоже самое, различия минимальны
Scala — 11%
Groovy — 7.4% (тестировщики :)
Kotlin — 1.7% — просто Java с доп. требованиями Котлина.
Ceylon — 0
Как работают стандартные коллекции в Ceylon? Они "свои" или используются классы из JDK? Если я использую совместимость с Java, придется ли мне копировать (даже если и неявно) из коллекции в коллекцию?
Звучит так как будто при неосторожном смешивании библиотек производительность начинает резко просидать. Так себе ситуация, IMHO. Подход Kotlin с черной магией в компиляторе в этом смысле сильно лучше.
Я понимаю что в этой статье вы не ставили себе задачу сравнить все за и против, но вообще это был бы один из минусов Ceylon.
На самом деле, когда реально важна производительность, там вообще не до коллекций :). Уже и на Java узким местом становится боксинг анбоксинг и тому подобные приколы, потому может потребоваться отказаться от Java коллекций в сторону обычных массивов примитивов. Как в одном из наших проектов на Ceylon, на каждый уникальный запрос перелопачивали в памяти 500 миллионов записей с фильтрацией группировкой аггрегацией на кластере :). Пришлось посидеть с профайлером и ускорить удалось где то в 60 раз. Узкие места были переписаны на Java. Но именно взаимодействие Java кода с Ceylon кодом для наших задач никогда не была узким местом. В настоящее время узкое место — скорость DoubleAccumulator. Предполагаю можно еще процентов на 30 поднять, и возможно еще раза в 2-3, если использовать кодогенерацию в Java и использование JavaCompilerAPI ради разворачивания циклов, но уже скорости хватает. И так практически в шину памяти удалось упереться, за 3 секунды перелопатить 30 гигов на каждой ноде это не так чтобы и медленно. Если бы проект писался целиком на Java, а не на Ceylon — быстрее бы точно не было. А так, переписать на Java пришлось процентов 10 кода. После профилирования. И даже если б писалось это изначально на Java — пришлось бы узкие места точно так же переписывать.
Производительность это совершенно отдельная тема, но по опыту использования — с производительностью у Ceylon достаточно неплохо. И взаимодействие с Java в тех узких местах, где код желательно было переписать на Java в нашем случае проблемой не стал.
Если уж касаться оптимизаций — некоторые вещи у нас вообще сишные либы делают. Причем этим сишным либам еще и кластер нужен :). Соответственно мы из Ceylon вызываем Java библиотеки, которые являются обертками над сишными библиотеками. И узким местом является именно сишная библиотека. не подготовка данных, а именно тупой расчет.
Если уж на то пошло, улучшенные дженерики с информацией о типе дженерика в рантайме с точки производительности очень даже не бесплатны и в узких местах узнавать информацию о типе не стоит выяснять. В узких местах вообще то многое не следует делать :).
Почему стоит полностью переходить на Ceylon или Kotlin (часть 1)