А так же что Kotlin дает для разработки front-end'a
То же, что node.js даёт для разработки бэкэнда, а именно — возможность писать всё на одном языке. Дальше обсуждать бессмысленно, потому что есть 1000 мнений на этот счёт. Но уже одно то, что node.js есть и собирает большое коммьюнити, говорит о том, что идея иметь один язык для всего, не так уж маргинальна.
Кроме возни и гемора с классами и как следствие тонн всяких конверторов JSON->Object и обратно
есть немного специального кода для поддержки пакетов
Уже давно нет. Пакет — просто пустой объект JS, куда накидываются свойства.
Что символы, что строки часто используют обёртки от Kotlin
Не совсем. Строки точно никогда вообще не оборачиваются. Символы в ряде случаев оборачиваются, но тут есть нюанс: в JavaScript вообще нет понятия "символ", можно его представлять как строку из одного символа, можно как число. Но и в том и в другом случае нельзя отличить на рантайме символ от строки или числа. А если всё же хочется, приходится оборачивать.
Нет switch на уровне языка, when же всегда преобразуется в набор if. Не знаю, плохо ли это.
И городить свой UI фреймворк имеет смысл только с прицелом на android разработчиков по-моему.
У меня не столько фреймворк сделан, сколько компилятор альтернативный. Проблема в том, что ничего GWT-ного в нём не работает, ни UI binder, ни Errai. Теоретически можно попросить создателей Errai портировать его на TeaVM, но вряд ли они на это согласятся. Вот и пришлось городить свой UI-фреймворк.
Да и стандартный UiBinder вполне себе декларативный
Вот есть у меня большущая коллекция, и мне нужно показать её в table или в ul. Что делать в UiBinder? Он такого не поддерживает. Приходится городить код, который итерируется по коллекции и добавляет элементы в нужное место (некоторые для строк таблицы пишут ещё один отдельный шаблон). А если надо ещё и обновлять, причём минимальным количеством действий с DOM, то можно вообще убиться. Так что нет, UiBinder вовсе не декларативен и совершенно не удобен.
Это очень древняя история, я давно уже этим не занимаюсь (как и автор Graphhopper). Не стал от греха подальше упоминать о подобных вещах. Но вот в комментах напишу: ещё вполне актуально использование TeaVM в CodenameOne: https://www.codenameone.com/demos.html Почти на каждой демке есть опция JS port. Это они с помощью TeaVM скомпилили.
Заоптимизировал, прислал пулл-реквест. Сам код TodoMVC не менял, просто собрал последний Flavour локально и заменил в pom.xml версию на 0.1.0-SNAPSHOT. А ещё выставил уровень оптимизации FULL. Стало значительно лучше, причём и при добавлении
Заставляя при этом подчиняться ему. И, как я уже писал выше, шаг влево, шаг вправо — расстрел. Вместо этого на себя оптимизации могут брать библиотеки. Одна библиотека (RxJava) оптимизирует пересчёт данных, другая (Flavour) оптимизирует перерисовку DOM.
Обычно, тормозит 10% программного кода, остальные 90% в принципе работают с такими объёмами данных, что тормозить нечему. Зачем в этих 90% кода городить лишние абстракции?
Насколько я понял Flavour никакой не фреймворк, а просто библиотека для рендеринга.
В какой-то степени так. А ещё для роутинга, сериализации, валидации и REST. Не люблю фреймворки, потому что они принуждают пользователей к определённой структуре организации приложения, при этом шаг влево, шаг вправо — расстрел. Но если назвать свой проект "библиотека" или "toolkit", люди не поймут.
Фреймворк не создаёт экземпляр класса страницы, и никак не управляет им. Вместо этого вы создаёте его сами и сами же им управляете как хотите
Делается это, чтобы не навязывать пользователю определённую модель данных. А ещё для того, чтобы соблюсти SRP. Но я поиграюсь на выходных, попробую зацепить какую-нибудь RxJava или поищу другие фреймворки для реактивных данных. Суть в том, что пользователь может обновлять данные так, как ему хочется. Хочется руками — пусть обновляет руками, хочется реактива — будет реактив. А если перфоманс не принципиален в конкретном случае, так пусть вообще оставит наивную но простую реализацию.
Flavour — это не про данные, а про их отображение. По идее, для пересчёта данных можно придумать/переиспользовать что-то другое, это никак не отразится на том, как шаблоны выглядят.
Ну, по хорошему реализация должна быть максимально нативная для фреймворка, без заточенных специально под бенчмарк оптимизаций, типа "сохраняем в localStorage лишь через секунду".
Я не об этом. Например, в моей наивной реализации TodoMVC фильтр (это тот, который All|Active|Completed) применяется при каждом чтении свойства, причём не в ленивый sequence, а в новый ArrayList. Можно сделать sequence, можно немного умнее перестраивать список и т.п. Это никак не относится к фреймворку.
Кстати, мне пришло в голову, что этот бенчмарк измеряет не просто фреймворк, на котором писали TodoMVC, но ещё и конкретную реализацию. Реализацию, прямо скажем, я даже не пытался оптимизировать, написав максимально простой код, ведь это же пример. Уверен, можно сделать и лучше.
Спасибо. Вообще, я знаю в чём дело. Надо просто немного улучшить реализацию std:foreach, потому что сейчас она полностью перестраивает DOM, если изменяется начало списка. Улучшение тривиальное, но руки не доходили сделать. Попробую сегодня поправить, собрать TodoMVC на снапшоте и повторить замер.
В Kotlin же есть нативная поддержка компиляции в Javascript. Получается, что я могу скомпилировать Kotlin-фронтенд двумя разными способами.
Да, всё так
Уже пробовали их сравнивать?
В каком смысле сравнивать? По производительности? По размеру генерируемого кода? Полагаю, можно написать синтетические бенчмарки, показывающие преимущества того или другого в специфическом сценарии. Что касается концептуального: в Kotlin/JS нет возможности использовать библиотеки, написанные на Java, в TeaVM немного сложнее интеропиться с JS (потому что нет специальной поддержки со стороны языка в Java и Kotlin/JVM, приходится придумывать костыли и обкладываться аннотациями). А так, если интересно, можно потратить некоторое время на исследование и составить подробный список различий, преимуществ и недостатков каждого подхода.
В TeaVM не надо писать на JavaScript, для того он и создан
Есть возможность делать гуй на шаблонах (с биндингом, перерисовкой только изменившегося DOM). Пишите шаблоны под bootstrap — будут и компоненты. Можно создавать свои компоненты для шаблонизатора, можно биндиться к JavaScript-компонентам (как и в GWT). Но, разумеется, т.к. мой проект пока не нашёл широкого применения, под него есть только небольшой набор стандартных компонентов.
Например Element.querySelector() уже более 5 лет доступен в браузерах, а в GWT его так и не поддержали
А зачем его вызывать вручную? Я всегда думал, что выбор элементов за меня сделает библиотека виджетов. А сделает она это через JSNI или через overlay-тип — мне какая разница? Конечно, иногда надо напрямую сделать что-то с DOM, но это настолько редко требуется, что кусочек JSNI не проблема написать. Зато остальные 99% кода пишутся на Java без проблем.
но зачем тогда вообще тащить GWT
Причина одна, но для кого-то может быть крайне весомой — возможность писать клиентский код на Java.
Я в курсе. Речь была о том, что даже если автор не позаботился о расстановке этих аннотаций для удобства использования из Java, то полученный негативный эффект будет не более, чем косметическим.
То же, что node.js даёт для разработки бэкэнда, а именно — возможность писать всё на одном языке. Дальше обсуждать бессмысленно, потому что есть 1000 мнений на этот счёт. Но уже одно то, что node.js есть и собирает большое коммьюнити, говорит о том, что идея иметь один язык для всего, не так уж маргинальна.
kotlinx.serialization всю возню берёт на себя, это должно упростить жизнь.
Уже давно нет. Пакет — просто пустой объект JS, куда накидываются свойства.
Не совсем. Строки точно никогда вообще не оборачиваются. Символы в ряде случаев оборачиваются, но тут есть нюанс: в JavaScript вообще нет понятия "символ", можно его представлять как строку из одного символа, можно как число. Но и в том и в другом случае нельзя отличить на рантайме символ от строки или числа. А если всё же хочется, приходится оборачивать.
Как раз недавно пофиксили, см. KT-21160.
Ещё вы можете компилировать Kotlin в JS не через Kotlin/JS, а через вот это, и использовать хоть BigInteger, хоть всякие локали, форматы, даты и т.п.
У меня не столько фреймворк сделан, сколько компилятор альтернативный. Проблема в том, что ничего GWT-ного в нём не работает, ни UI binder, ни Errai. Теоретически можно попросить создателей Errai портировать его на TeaVM, но вряд ли они на это согласятся. Вот и пришлось городить свой UI-фреймворк.
Вот есть у меня большущая коллекция, и мне нужно показать её в table или в ul. Что делать в UiBinder? Он такого не поддерживает. Приходится городить код, который итерируется по коллекции и добавляет элементы в нужное место (некоторые для строк таблицы пишут ещё один отдельный шаблон). А если надо ещё и обновлять, причём минимальным количеством действий с DOM, то можно вообще убиться. Так что нет, UiBinder вовсе не декларативен и совершенно не удобен.
Есть там UI: http://teavm.org/live-examples/graphhopper/
Технических проблем не было вообще. Были организационные и коммуникационные проблемы.
Это очень древняя история, я давно уже этим не занимаюсь (как и автор Graphhopper). Не стал от греха подальше упоминать о подобных вещах. Но вот в комментах напишу: ещё вполне актуально использование TeaVM в CodenameOne: https://www.codenameone.com/demos.html Почти на каждой демке есть опция JS port. Это они с помощью TeaVM скомпилили.
Заоптимизировал, прислал пулл-реквест. Сам код TodoMVC не менял, просто собрал последний Flavour локально и заменил в
pom.xml
версию на 0.1.0-SNAPSHOT. А ещё выставил уровень оптимизации FULL. Стало значительно лучше, причём и при добавленииЗаставляя при этом подчиняться ему. И, как я уже писал выше, шаг влево, шаг вправо — расстрел. Вместо этого на себя оптимизации могут брать библиотеки. Одна библиотека (RxJava) оптимизирует пересчёт данных, другая (Flavour) оптимизирует перерисовку DOM.
Premature optimization is the root of all evil © Donald Knuth
Обычно, тормозит 10% программного кода, остальные 90% в принципе работают с такими объёмами данных, что тормозить нечему. Зачем в этих 90% кода городить лишние абстракции?
В какой-то степени так. А ещё для роутинга, сериализации, валидации и REST. Не люблю фреймворки, потому что они принуждают пользователей к определённой структуре организации приложения, при этом шаг влево, шаг вправо — расстрел. Но если назвать свой проект "библиотека" или "toolkit", люди не поймут.
В статье я ясно написал:
Делается это, чтобы не навязывать пользователю определённую модель данных. А ещё для того, чтобы соблюсти SRP. Но я поиграюсь на выходных, попробую зацепить какую-нибудь RxJava или поищу другие фреймворки для реактивных данных. Суть в том, что пользователь может обновлять данные так, как ему хочется. Хочется руками — пусть обновляет руками, хочется реактива — будет реактив. А если перфоманс не принципиален в конкретном случае, так пусть вообще оставит наивную но простую реализацию.
Flavour — это не про данные, а про их отображение. По идее, для пересчёта данных можно придумать/переиспользовать что-то другое, это никак не отразится на том, как шаблоны выглядят.
Я не об этом. Например, в моей наивной реализации TodoMVC фильтр (это тот, который All|Active|Completed) применяется при каждом чтении свойства, причём не в ленивый sequence, а в новый ArrayList. Можно сделать sequence, можно немного умнее перестраивать список и т.п. Это никак не относится к фреймворку.
Кстати, мне пришло в голову, что этот бенчмарк измеряет не просто фреймворк, на котором писали TodoMVC, но ещё и конкретную реализацию. Реализацию, прямо скажем, я даже не пытался оптимизировать, написав максимально простой код, ведь это же пример. Уверен, можно сделать и лучше.
Спасибо. Вообще, я знаю в чём дело. Надо просто немного улучшить реализацию
std:foreach
, потому что сейчас она полностью перестраивает DOM, если изменяется начало списка. Улучшение тривиальное, но руки не доходили сделать. Попробую сегодня поправить, собрать TodoMVC на снапшоте и повторить замер.Да, всё так
В каком смысле сравнивать? По производительности? По размеру генерируемого кода? Полагаю, можно написать синтетические бенчмарки, показывающие преимущества того или другого в специфическом сценарии. Что касается концептуального: в Kotlin/JS нет возможности использовать библиотеки, написанные на Java, в TeaVM немного сложнее интеропиться с JS (потому что нет специальной поддержки со стороны языка в Java и Kotlin/JVM, приходится придумывать костыли и обкладываться аннотациями). А так, если интересно, можно потратить некоторое время на исследование и составить подробный список различий, преимуществ и недостатков каждого подхода.
А зачем его вызывать вручную? Я всегда думал, что выбор элементов за меня сделает библиотека виджетов. А сделает она это через JSNI или через overlay-тип — мне какая разница? Конечно, иногда надо напрямую сделать что-то с DOM, но это настолько редко требуется, что кусочек JSNI не проблема написать. Зато остальные 99% кода пишутся на Java без проблем.
Причина одна, но для кого-то может быть крайне весомой — возможность писать клиентский код на Java.
А можно услышать какие-нибудь аргументы? Просто интересно
Пользуясь случаем, попиарю свой проект: http://teavm.org/
Поддерживаются Java, Scala, Kotlin, есть Angular-образный фреймворк в комплекте
Я в курсе. Речь была о том, что даже если автор не позаботился о расстановке этих аннотаций для удобства использования из Java, то полученный негативный эффект будет не более, чем косметическим.