Шось про айтішку – Telegram
Шось про айтішку
1.47K subscribers
447 photos
163 videos
2 files
599 links
Фронтенд, ШІ, 3D друк, FPV, історії з життя та роботи
Download Telegram
В свободное время пытаюсь разобраться в разработке Android приложений на Kotlin. Сейчас делаю Android версию ClojureScript REPL Replete https://replete.surge.sh/

В целом неплохо. В чем-то тулинг лучше, чем в React Native. Но возможности интерактивной разработки, конечно, не хватает.

В приложении ClojureScript выполняется в V8, для него есть Java обертка J2V8 https://github.com/eclipsesource/J2V8/. Время старта приемлимое, учитывая, что там около 9Мб скомпилированного JS, но могло бы быть и лучше.

В V8 есть возможность сделать дамп хипа и использовать его для почти мнгновенного старта https://v8.dev/blog/custom-startup-snapshots По факту это такой себе AOT для JS. Это успешно использует Node.js ClojureScript REPL Lumo https://anmonteiro.com/2016/11/the-fastest-clojure-repl-in-the-world/

J2V8 собирает V8 без возможности сериализировать хип, поэтому движок нужно собирать самому под все версии архитектуры arm. Это та еще боль 😕
Заметка про Kotlin. Мне, как разработчику, который почти не работал с Java, Kotlin вполне зашел (мнение после двух недель, ага). Совсем не страшно после JS (особенно если немного смотрел на TypeScript), но после кложуры некоторые вещи приходиться делать скрипя зубами.

Кажется, что язык позиционирует себя как более «функциональная» альтернатива Java, но наследние джавы вылазит на каждом шаге. Корутины пока пригодились так же, как и core.async в кложуре (не нужен).

Самая приятная фича: если вставить код на джаве в файл с котлин, то IDE на ходу транспайлит в котлин :D
Вчера попробовал стримить разбор Kotlin + JS, вышло написать что-то с React. Запись вот здесь (местами проседает звук) https://www.youtube.com/watch?v=_VeFnJHrmaI&t=313s
Собрал гайд по интеграции ClojureScript/Reagent в JS/React проекты. Пока что это единственный известный мне более-менее нормальный способ внедрить cljs в кодовую базу на js. По крайней мере уже не нужно писать руками экстерны т.к. компилятор научился выводить их в 90% случаев https://github.com/roman01la/reagent-react-integration
Как оказалось есть альтернатива — shadow-cljs. Сборщик сделан специально под интеграцию с NPM, все делает сам с минимальным конфигом https://github.com/thheller/reagent-react-integration/tree/shadow-cljs
Стрим разработка под Android на Kotlin. Доделываю cljs REPL https://youtu.be/vHXLRgbAOjQ
Пару дней назад запустили открытую бету ClojureScript REPL Replete 2.0 https://twitter.com/mfikes/status/1086743669825261569

Помимо первого релиза для Android добавили неймспейсы для работы с файловой системой (replete.io) и сетью (replete.http).
Недавно дошли руки попробовать построить нативный UI по принципу Flutter (без нативных контролов, все сделать с нуля на OpenGL).

Первая мысль была взять простую библиотеку типа NanoVG, но такие простенькие решения не предусматривают батчинг обращений к GPU, часто не умеют размечать текст и в целом не делают многих оптимизаций, которые нужны для «богатого» UI.

В общем попробовал подключить Skia (рендерер в Chrome и Flutter). Если коротко, то C++ — боль. Особенно писать к нему биндинги.

Для лайаута взял Yoga (сабсет flex box, испольузется в React Native) и в целом вышшло неплохо, примеры можно посмотреть вот здесь https://romanliutikov.com/native-ui-part-1.html

Интересная альтернатива — новый рендерер в Firefox WebRender. Пишут, что почти все идет через GPU и вроде бы как выдает заоблачный FPS. Плюс, что написан на Rust. Минус — все еще в разработке. Но уже есть пару примеров использования в продакшн в качестве бекенда для GUI библиотек.

Другой вопрос — какой выбрать скриптовый язык? Сначала подумал про лиспы (SBCL, ECL или Carp), потом вспомнил про Lua. Но в и тоге думаю забиндить рендерер под V8/Node.js, написать кастомный reconciler для React и использовать кложуру и экосистему реакта для написания UI.

Если подумать, то производительность скриптового языка не играет роли. Изменения в UI не происходят с частотой обновления экрана, нормальные анимаци никогда не контролируються из UI потока. Узкое горлышко — это рендерер и иногда биндинги. Например Chrome многие вещи делает на CPU, а React Native гоняет сериализированные данные между JS и Native. Отсюда и хреновая производительность.

В общем интересный эксперимент, посмотрим насколько у меня хватит мотивации, может сделаю пару стримов.
Неплохая книга (free!) о дизайне интерпретаторов от создателя Dart. Описывает весь путь от текстовой программы до виртуальной машины http://www.craftinginterpreters.com

Кстати автор UglifyJS лиспер и в его блоге есть серия статей о создании интерпретатора на JS, сжато и очень доступно http://lisperator.net/pltut/
Начали публиковать доклады с недавней ClojureD. Отличный доклад интро в triple store бд (datomic, datanoscript, etc.) https://www.youtube.com/watch?v=tbVwmFBnfo4
Новое видео на канале https://youtu.be/VlLydB0rohQ Эксперименты с Hiccup, спекой и реакт с хуками.
Второе видео из серии будет опубликовано в понедельник, но для подписчиков канала запощу его сюда сегодня. Это продолжение серии скринкастов о создании cljs враппера для React https://youtu.be/Hqd7lbIc668

Получить доступ к остальным видео можно по подписке на Patreon https://www.patreon.com/bePatron?c=1239559

P.S. Если что, то подписка существует не для зароботка, а для того, чтобы понимать насколько это интересно остальным.
Новый API хуков в React оказался дубовым. Мемоизация useEffect работает через shallow equal аргументов, что не дает возможность использовать иммутабельные значения, у которых семантика сравнения совершенно другая. Вместо этого можно было бы дать возможность передавать компаратор.

Забавно, что это аргументируется тем, что разработчики реакта хотят этим предотвратить использование deep equals со стороны пользователей библиотеки. В то же время они отсекают возможность нормально использовать API с кастомными структурами данных.

То есть вышло как обычно: попытки угадать что-то наперед в итоге кому-то выходят боком. Посмотрите что там нагородили в комментариях.

https://github.com/facebook/react/issues/14476
Был вопрос по поводу вчерашнего поста: что ломает shallow equals с иммутабельными данными, если значения по ссылке равны?

Сравнение по ссылке работает верно только в том случае, если оба значения действительно ссылаються на один и тот же объект в памяти. То есть здесь все ок: (let [m1 {:x 1} m2 m1] (identical? m1 m2)) ;; true

Но два разных объекта в памяти никогда не будут идентичны: (identical? {:x 1} {:x 1}) ;; false. Хотя структурно они равны: (= {:x 1} {:x 1}) ;; true. Случай когда разные значения в памяти равны структурно возникает довольно часто, поэтому только сравнением по ссылке не обойтись.

На самом деле теоретически это возможно сделать. Если все значения иммутабельны, то по факту нет смысла аллоцировать в памяти структурно равное значение. Достаточно кэшировать такое значение и возвращать на него ссылку при создании структурно равного. Это одна из оптимизация использования памяти с иммутабельными данными (кстати пришла к нам со времен лиспов https://en.wikipedia.org/wiki/Hash_consing). Но на деле выходит, что применять это глобально всегда приносит больше вреда. Поэтому такие штуки обычно выносят в библиотеки и применяют к отдельным частям системы.

P.S. С вопросами пишите в личку @roman01la
Второй вечер залипаю на видео материалы с Ричардом Фейнманом, завидую его умению объяснять так доходчиво:

https://www.youtube.com/watch?v=VdYujzyaX68
https://www.youtube.com/watch?v=P1ww1IXRfTA
https://www.youtube.com/watch?v=EKWGGDXe5MA

Also, из WTF в программировании:
- GHC ограничивает размер таплов до 62, дальше segfault 😀 https://github.com/ghc/ghc/blob/e3f341f334d89c88f388d8e864ed8762d0890a64/libraries/ghc-prim/GHC/Tuple.hs#L170
- Rust 32 https://github.com/diesel-rs/diesel/blob/57e17f224b7938b33487d2a0e6ba83fb524dd42e/diesel/src/macros/tuples.rs
- Scala 22

И посмотрите на прекрасные елки из сигнатур 😀
Опубликовал третий выпуск скринкастов. В этот раз о мемоизации компонентов https://youtu.be/H9yyjdRhstU
​​Пример как React мог бы сообщать о «вредительских» оптимизациях в shouldComponentUpdate или React.memo https://codesandbox.io/s/kmpxv86j85
Из интересного:
Опубликовали технические детали гугловой Fuchsia OS. Перспектива писать UI на Dart не радует, но в целом выглядит интересно https://bzdww.com/article/163937/

Java 12 релизнулась с Shenandoah GC («ultra-low pause time garbage collector») https://wiki.openjdk.java.net/display/shenandoah/Main

Сообщество кложуристов все больше донатит на open source. Теперь выделяют грант в $3000 на поддержку проектов https://www.clojuriststogether.org/news/february-2019-monthly-update/
​​Пробовали когда-нибудь обрабатывать видео в браузере? Chrome дает ряд API для захвата видео и аудио источников, поэтому, в принципе, это возможно.

Комбинировать видео с текстом, изображениями и эффектами можно в WebGL: видео стримится в канвас + покадровый рендрер в текстуры и композинг (https://github.com/bbc/VideoContext) + покадровый захват (https://github.com/spite/ccapture.js/) и экспорт обратно в видео (https://github.com/thenickdude/webm-writer-js/).

При желании это можно распараллелить в воркерах используя OffscreenCanvas.

Единственная проблема сейчас — браузер не дает точный тайминг начала и конца видео, поэтому поймать первые и последние кадры практически невозможно. Альтернатива резать видео на кадры в ffmpeg скомпиленом в wasm (https://github.com/Kagami/ffmpeg.js)