Читать в телеге. Когда-то там были посты не только от меня.
Valhalla для примитивов
Хороший доклад про статус проекта Valhalla, который сможет устранить проблемы, связанные с разделением на объекты и примитивы и сопутствующими оптимизациями (хранить данные на стеке).
В начале идет история примитивов, как и почему они появились, зачем нужен int
, когда есть Integer
, а также признаются ранние ошибки первых версий Java. Потом собственно рассказ о том, что с этим можно сделать — и тут всплывают и иммутабельность, и “прозрачные” типы, и null-безопасность, и потокобезопасность, и оптимизации в памяти всякие, и проблема частичной инициализации, и т.д. — то, что обычно рассказывают в каком-нибудь модном ФП языке. Представляю горящие пердаки некоторых джавистов, которые с пеной у рта доказывали что котлин не нужон с этой его проверкой на null и иммутабельностью.
Была веселая история про то, что в первых версиях Java примитивный long
был потоконебезопасен (sic!). Эта история снова может стать актуальной для value-типов на стеке (если они больше машинного слова). Выход — делать все иммутабельно.
История про проблемы с null напоминает историю Kotlin и его платформенными типами (уж не знаю, что хуже, ссылаться на свою статью на хабре или ее репост в бложике), и типичные проблемы с null-безопасностью — а что будет с массивом значений и т.п. В итоге есть план сделать явное обозначение а-ля Integer?
/Integer!
.
Увы, обратная совместимость многому препятствует. Нельзя сделать все не-nullable по умолчанию, Integer!
и int
не получится сделать на 100% синонимами, сериализация вставляет палки в колеса. Есть риск, что Java может превратиться в плюсы с точки зрения синтаксиса (*флешбеки от того, как в C++ записываются лямбды*). Ну и с дженериками еще не все вопросы решены.
В целом выглядит как движение в сторону прогресса, правда очень медленное. Все это продирается через пик сложности — проект начался аж 2014 году. Правильная модель — ключ к успеху, но ее поиски занимают много времени. Слайд с рассмотренными концептами на 44:05 впечатляет. Если отказаться от некоторых «степеней свободы», то куча сложности просто уходит.
Игры в PDF
Тетрис. У меня работает только в десктопных браузерах, хотя в комментах на HN нашли и другие приложения, в которых это пашет. Исходники.
И, конечно, Doom. Работает только в хроме. Исходники.
“Игры прикольные, ситуация страшная”:)
Старейшая тудушка в коде
Ну уж в этом-то году точно все легаси уберем, да?
Чтобы найти старые TODO в репозитории (и, скорее всего, ужаснуться), можно использовать вот эту колбасу
git grep -i -nE 'TODO|FIXME|FIMXE' | while IFS=: read -r file lineno line; do commit_date=$(git blame -L "$lineno,$lineno" --porcelain "$file" | awk '/^author-time/ {print $2}' | { read epoch; date -u -d @$epoch "+%Y-%m-%d %H:%M:%S" 2>/dev/null || date -u -r $epoch "+%Y-%m-%d %H:%M:%S"; }); echo "$commit_date $file:$lineno: $line"; done | tee >(sort > todos.txt)
(результат будет в todos.txt)
P.S. Особым мазохизмом было получение кроссплатформенного варианта этой команды и выдрать нормальную дату из гита, потому что по умолчанию blame
выдавал не очень машиночитаемый формат.
"Кроссплатформенность" bash
Годами сидя на линуксе, особо не задумываешься об версиях баша и стандартных утилит: по умолчанию ожидаешь, что cp
и в Африке cp
, и думать тут много не надо.
Но как только надо написать какой-нибудь не очень тривиальный однострочник, чтобы добавить его в документацию и/или репозиторий, чтобы “работало” везде, сразу возникают проблемы. Например, у какого-нибудь sed
есть как минимум две версии: BSD (во фряхе и маках) и GNU (в большинстве линуксов), и они серьезно отличаются.
Казалось бы, есть POSIX-команды, можно врубить какой-нибудь режим совместимости и все будет пусть и безобразно, но единообразно, да? *падме.жпг* Реальность, разумеется, полна разочарований: так с большинством команд сделать не получится.
Например, GNU date -Is -ud @249499969321
— это BSD date -Iseconds -ur 249499969321
, и если seconds
тоже можно использовать в первом случае, то остальное уже не поменять.
Другой пример: в BSD sed
“на месте” должен быть явным, -i ""
, а в GNU должно быть именно -i
, без явной пустой строки. Обо всяких \b
тоже можно забыть.
Наконец, некоторые вещи можно обнаружить только методом проб и ошибок, например, strftime
в awk
.
Вишенка на торте: по умолчанию на маках стоит баш версии 3.2 аж от 2007 года (пусть даже ее постоянно патчат, функционально она застыла во времени).
В качестве обходного решения на маке можно… тупо поставить GNU-версии через brew
. В среднем по больнице они все равно лучше. Но если это невозможно, то очевидный вариант — обмазать скрипт if/else
с проверками на систему или переписать на питон. Еще один обходной путь: вызывать два варианта команды через ||
с учетом того, что неподходящий вариант отвалится с ошибкой.
Карта исторических границ
Сабж. Для важных переговоров™.
Дублирование ссылки в Markdown
Понадобилось в во внутренней доке вынести часть ссылок в начало документа, чтобы не искать их в тексте. Оказывается, у Markdown есть механизм для ссылки на ссылку! В любом месте документа (например в конце) добавляем название
[link_name]: https://ov7a.narod.ru/index-1.html
И потом используем в квадратных скобках сколько угодно:
Это [ссылка][link_name]. И [это][link_name] та же самая ссылка.
Версионирование
Де-факто стандарт для версионирования всяких библиотек и продуктов — семантическое версионирование. Идеи довольно простые, хотя и полный документ содержит немного душноты.
Браузеры со своими версиями за 300 и внутренние релизы некоторых компаний а-ля 0.192, годами крутящиеся на проде, передают пламенный привет:)
Оказывается, у этого подхода есть куча критиков: 1, 2, 3. Недостатки сводятся к следующему:
- Демагогия по поводу того, “а что такое ломающее изменение”, “а если это влияет только на 1% пользователей”, “а мелкое ли это изменение?”, “это не баг, а фича” и т.п.
- Не все следуют SemVer (sic!) (например, у них 0.x в проде).
- О ужас, SemVer не всем подходит!
- Одно число не может передать всей глубины изменений. На него нельзя полагаться при обновлениях, все равно надо читать список изменений.
- Если ваш продукт последний в цепочке (например, фронтенд-морда) — о боже мой, всем насрать какой он там версии. Это все очень сложно, простоиспользуйте одно число, как например браузеры.
- Частые обновления библиотек могут отпугнуть пользователей.
- Настоящим инженерам вообще версии не нужны — посмотрите на ранние UNIX-программы, они совершенны! Версионирование — это отмазка, чтобы ломать API.
- В большом дереве зависимостей изменение одной версии может привести к каскадному
резонансуизменению заметного числа зависимостей. - Инженеры боятся обновлять мажорную версию своей библиотеки, и откладывают внедрение фич. Иногда во имя маркетинга.
- Ради обратной совместимости приходится делать костыли.
На часть этих замечаний неплохо отвечает создатель спецификации (один из создателей GitHub кстати): не надо бояться увеличивать мажорную версию, не надо мешать маркетинг с техническими деталями, надо любить своих пользователей, предоставляя им средства для автоматических миграций, а ломающие изменения выдавать по чуть-чуть, а не огромными пачками.
В java-мире сейчас обсуждают подход Tip & Tail, который может сгладить некоторые моменты (при этом не противореча идее SemVer). По сути предлагается иметь два релиза: tip, с новейшими фичами и всем таким, и tail, в котором все будет максимально стабильно и меняться очень редко и только когда прям совсем надо (по сути, LTS).
Валидация HTML в консоли
На одной из страничек в легаси проекте всплыл косяк, что есть лишний закрывающий div
. Вроде очевидное решение — его надо убрать, но может можно как-то найти и предотвратить это в будущем? Конечно, для этого можно использовать какой-нибудь JS-фреймворк (какой там сейчас популярный?), но у меня же тупо страничка с шаблоном (или SSR, как сейчас (или уже раньше) было модно говорить). Нашел консольную утилиту — HTML tidy, вы только зацените кислотность сайта! Привлекло, что можно ее можно использовать в формате curl url | tidy
.
P.S. думал еще какой-нибудь плагин/расширение для браузера найти, но это тяжело в пайплайн встроить, и быстро ничего приличного не нашел (если кто шарит, поделитесь опытом).
Применимость AI в разработке
Годная статья про текущий уровень, где автор неплохо и довольно трезво оценил, как лучше сейчас использовать всяких “ассистентов” (демки/MVP, автодополнение, генерация черновых вариантов), какие есть проблемы (код надо проверять, уметь дебажить и думать о крайних случаях оказывается, ну и архитектура с безопасностью в помойке) и попытался посмотреть в будущее (автоматизация рутины, помощь в поиске идей, проактивные предложения ну, и, разумеется, “вкалывают роботы, а не человек!”).
Описанное в статье в целом соответствует моим впечатлениями (см. 1 и 2)
Работа с ошибками в Roc
Очередной доклад про работу с эффектами (на самом деле с обработкой ошибок). Не могу сказать что он супер или что в нем какая-то невероятно новая идея, но тут хорошо поставлена и разжевана проблема: почему напряжно обрабатывать ошибки разных видов.
Сама идея тегов, которые отслеживает и обрабатывает компилятор, занятная, но не думаю что она выстрелит. В скале более общий и фундаментальный поход, я рассказывал об этом ранее. Да и итоговое решение не сильно семантически отличается от первоначального подхода на Rust.
Другая идея, реализация конечного автомата для асинхронных вычислений, тоже не нова, и сильно напоминает котлиновские корутины. Реализована в функциональном стиле, но сюрпризов особо нет, и проблема “двухцветности” особо не решена, и вся машинерия торчит в коде.
Впрочем, автор и сам признает некоторые недостатки и часть идей на момент доклада не была реализована. Однако, если ни с одной идеей не знакомы, доклад довольно простой и доступный, и его можно посмотреть. Видос от создателя Roc и соавтора Elm, и прошлое автора чувствуется — торчат уши языков из этого семейства и сопутствующих идей. Но он неплохой докладчик — у меня в бложеке нашлась еще пара ссылок на его видео (1, 2).