Читать в телеге. Когда-то там были посты не только от меня.
Txl
После эксперимента с OpenRewrite планировал посмотреть что-то более надежное, а именно Txl. В целом, я остался доволен экспериментом.
Чтобы получить общее впечатление, я не изобретал велосипед и тупо выполнял задания из Txl Challenge. Примечательно, что там предлагается общаться по почте с одним из “Оракулов”, чтобы получить помощь (делать я этого, конечно, не стал).
Язык не очень сложный — все основы можно почерпнуть из презентации. Однако документация в целом не супер — это набор PDF. Искру добавляет неироничное использование шрифта Comic Sans.
Установка оказалась простой. Ошибки не очень дружелюбные, но при этом цикл обратной связи достаточно короткий.
Киллер-фича по сравнению с OpenRewrite, на мой взгляд, — это валидация выхода: вместо просто “текста” на выходе получается тоже АСД. Т.е. замена либо применится и это будет корректный код, либо будет пропущена. Увы, за это приходится расплачиваться тем, что надо иметь хорошую грамматику для целевого языка и задабривать компилятор: например, if -> if преобразовать просто, а if -> switch уже тяжело, потому что типы другие.
На 3 задании долго тупил как раз из-за непоняток, как правильно преобразовывать типы, и в итоге пришлось подсмотреть готовые решения на GitHub. Еще у меня почему-то не работал [list X]
, да и в целом любые преобразования кроме 1 к 1 давались тяжело. При этом преобразования 1 к 1 выглядят чуть ли не как куски кода из оригинала (“возьми такое и замени на сякое”).
У технологии, на мой взгляд, 2 основных минуса. Во-первых, откуда-то надо добыть грамматику. Для какой-нибудь Java это легко, для чего-то типа Kotlin — до свидания. Во-вторых, как я понял, нет никакого способа предоставить контекст. С какими-нибудь функциями расширения Kotlin — удачи понять, откуда метод и что там сейчас в качестве this
. Т.е. совсем произвольный код не очень понятно как преобразовывать с учетом того, что могут быть подключены библиотеки.
При всем при этом группа ученых смогла написать скрипт для перевода Java на C#. Правда только с версии 1.1 и это заняло 8 месяцев.
Еще отмечу, что первая версия Txl появилась аж в 1985 году. В целом, мне кажется, что фундамент вполне хороший и если бы инструмент немного набрал бы популярности в нужное время, то описанные проблемы могли бы быть решены.
Обучение горячим клавишам в IntelliJ
Мне лень учить горячие клавиши для многих приложений, и IntelliJ не исключение. Давным давно я запомнил штук 10 от силы, а для остального кликаю мышкой (ну или ищу через два шифта). Тем более что все возможные комбинации запомнить нереально имхо, да и не стоит оно того. Короче, максимально неправильный разработчик.
Случайно наткнулся на плагин, который “учит” комбинациям клавиш для конкретно ваших частых операций. И за 2 недели использования он что-то конечно предложил, но я вижу ровно ноль пользы от запоминания комбинации, когда вот кнопка на интерфейсе, даже ни в какое подменю не надо заходить. Короче, 0 новых выученных комбинаций.
Увы и ах, опять придется тратить время на то, чтобы что-то делать не супербыстро. Есть риск, что появятся мысли.
Задержка чтения из разных источников
Сабж. Про разницу масштабов я надеюсь все в курсе, но тут интересна еще динамика их изменения. Ну и что абстракции не бесплатны, не стоит забывать.
Параллельных запуск нескольких вещей в IntelliJ
Редко когда это нужно, но может пригодится — можно запустить что-то в параллели или последовательно для отладки — клиент + сервер или приложение + удаленный дебаггер. Но, например, для запуска нескольких тестов лучше сделать отдельную задачу в билд-скриптах.
Неполное клонирование
Во всяких CI и/или тестовых окружениях обычно не нужна вся история коммитов, а достаточно выгрузить состояние репозитория на момент определенного (чаще всего последнего) коммита. Чтобы сэкономить время и снизить вероятность ошибки сети, если она нестабильна, можно вместо тупого clone
сделать неполный:
git clone --depth=1 <remote-url>
# или
git clone --depth=1 <remote-url> --branch <branch_name> --single-branch <folder_name>
Больше опций можно посмотреть в статье от GitHub, а сравнение скорости для некоторых репозиториев — тут (до 25х быстрее).
Еще возникает иногда желание склонировать только коммиты из ветки (например, для того, чтобы проверить каждый из них на вшивость), но, увы, это сложнее. Даже стандартный checkout от GitHub это пока не умеет. Всякие обходные пути можно найти в том же тикете.
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
с проверками на систему или переписать на питон. Еще один обходной путь: вызывать два варианта команды через ||
с учетом того, что неподходящий вариант отвалится с ошибкой.
Карта исторических границ
Сабж. Для важных переговоров™.