• Косплей

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

    Если нравится Стив Джобс, сделай Айфон. Если Павел Дуров — сделай соцсеть с той стеной, которую считаешь нужной. Если Лапенко — сними смешной ролик. Но не повторяй внешность или стиль общения в интернете. Это ужасно.

    Точто так же не стоит повторять стиль жизни. Не надо вставать в пять утра, принимать контрастный душ, ходить босиком и медитировать. В мире полно людей, которые медитируют и не едят мяса, но не достигли ничего.

    Между великими людьми вообще нет связи. Все они были молодыми и старыми, сатанистами и христианами, бабниками и девственниками. Связи нет никакой. Когда кто-то читает десять правил знаменитости, я не понимаю — зачем? Ведь известность из них не следует.

    Доводилось видеть человека, который косплеил Дурова: челка, плащ до колен, все черное, взгляд мимо камеры. Он делал стартап, и было забавно видеть его за работой. Не знаю, чем кончилась его затея, но судя по всему — ничем.

    Все это сказано цитатой о Стиве Джобсе. У Стива были две половины: одна — редкостный засранец, вторая — редкостный гений. Из-за второй половины ему прощали первую. Сегодня много людей косят под Стива, но у них получается первая половина — засранца.

    Начинайте со второй половины.

  • Как в X

    Совершенно ужасная вещь — писать на яыке X как в Y. Например, в Питоне как на Хаскеле, а в JavaScript — как в Кложе. Придумать какие-нибудь “элегантные объекты” и тыкать людям, что они живут неправильно.

    Чемпионом в этой области является Питон. Из-за его гибкости на нем можно косплеить любой язык — хоть Хаскел, хоть Кобол. Скажем, выражение ниже можно сделать рабочим:

    items = List[1, ...]
    

    Для этого пишут особый класс List с метаклассом, у которого реализован метод __getitem__. В нем проверяется, что если второй элемент — класс Ellipsis, то возвращается ленивый список от 1 до бесконечности.

    Для Питона созданы сотни библиотек, которые косплеят другие языки — Хаскель, Скалу и другие. Я тоже отметился: написал либу с лаконичным названием f, где собраны плюшки Кложи: стрелочные операторы, мультиметоды и всякие мелочи.

    Все это замечательно, если бы не одна деталь: оно никому не сдалось. До перехода в Кложу я работал с Питоном семь лет и ни разу не видел, чтобы использовались функциональные поделки. Промышленные проекты на Питоне — это скучный ООП-код без map/reduce, монад и алгебраических типов. В точности так, как это видит создатель языка.

    Точно так же в Кложе никто не использует монады. Уже в седьмой раз я устраиваюсь кложуристом и не вижу их в проде (и это хорошо).

    В текущем проекте на Кложе беда — его начинали люди, которые знали ее синтаксис, но не идиомы. Другими словами, они знали, что вместо 1 + 2 надо писать (+ 1 2), но не знали, как устроить работу с базой, компоненты, тесты и окружение.

    Кажется, это были рубисты. Я не держал свечку, но это сквозит в коде. Чуваки написали свою ORM, которая матчит базу с REST — кривую и глючную. Для конфигурации используют переменные среды, и это тоже треш и содомия. Компоненты и система убоги. Позже в фирму пришли люди опытом на Кложе. Они либо обходят легаси — ходят в базу напрямую, используют свои решения, — либо прибегают к нему с легким отвращением.

    Идиома “писать на X как в Y” — это проигрыш по определению. В любом виде. Это билет в один конец, и он всегда одинаков. Вы пишете “как надо”, но потом уходите, и другие с трудом приводят код в нужное русло. Не всегда удается сделать это полностью — иной раз авгиевы конюшни столь полны, что переделывать слишком дорого, и с этим как-то живут.

    Легковестные агенты из Эрланга в Кложе. Элегантные объекты в Джаве. Монады вместо исключений в Питоне. Да, интересно, да, ярко. Но бесполезно.

    Если идеи по-настоящему сильны, их нужно выразить в новом языке. Не устраивает чистый C — появляется C++. Не устраивают древние диалекты Лиспа — появляется Кложа. Не нравится бородатый Эрланг — пишут Эликсир.

    На любом языке надо писать так, как в нем принято. На Руби — как в Руби, а не в Кложе. На Кложе — как принято в Кложе, а не в Руби.

    Чем раньше это поймешь, тем скорее на тебя снизойдет благодать.

  • Три часа

    Хорошо, если бы режиссерам кто-нибудь объяснил: три часа для фильма — это много.

    Что бы ты ни добавил, какой бы сюжет ни закрутил, какую бы графику ни навертел — получится затянуто.

    Все трехчасовые фильмы, на которые я ходил, были затянуты. “Однажды в Голливуде” — затянуто, занудно. “Довод” — затянуто, занудно. Нелепые сцены, ответвления сюжета. Второй “Аватар” — затянуто, одно да потому.

    На “Дюну” и что-то другое кассовое я не пошел, потому что научен опытом. Взяли любимую игру детства и поставили в трейлер Pink Floyd — искушение было сильно, но нет. Три часа — это знак, что режиссер не смог упокавать образы во что-то емкое и решил проблему количеством, а не качеством.

    Три часа — это чересчур для формата фильма. Полтора-два — в самый раз. Все, что выше этого, второстепенно и отвлекает от главного.

    Сейчас все кричат про Оппенгеймера, но три часа — увы, я пас. О жизни великого человека можно рассказать и за полтора часа, а три-четыре снимайте для фанатов — пусть смотрят режиссерскую версию отдельным сеансом.

    Разбухшие фильмы — такая же проблема, как и разбухший софт. Почему об этой проблеме не говорят — загадка.

  • HTMX

    Этот пост — попытка объединить заметки об HTMX в Телеграме во что-то целостное. Написать статью о нем за один подход не вышло, поэтому пришлось по частям.

    HTMX — это библиотека для серверного рендера HTML. От современных React и Vue она отличается тем, что не хранит состояние на клиенте и не занимается рендером на JavaScript. Она посылает запрос к серверу и получает кусок HTML — в особых случаях несколько кусков, — которые вставляет в нужное место DOM.

    При всей примитивности этого подхода у него есть сторонники, и их число растет. Я тоже склоняюсь к серверному рендеру и хочу написть о нем подробнее.

    Htmx — не единственная в своей области библиотека. Есть еще HotWire, LiveView и другие. Под HTMX я имею в виду не конкретную библиотеку, а серверный рендер в принципе; просто HTMX звучит короче.

    Первая заметка об HTMX касалась числа запросов на сервер. Порой говорят: HTMX требует больше запросов, потому что забирает состояние с сервера. А в React-приложении ты выгреб состояние и хранишь на клиенте — улыбаешься.

    Это неправда. Когда в HTMX открываешь диалог, происходит один — и только один — запрос. Когда открывается диалог в приложении на Vue, происходит 14, — прописью, четырнадцать — запросов. Буквально на днях я правил фронтенд по работе, и там был именно такой случай. Цифры я взял какие есть, без преувеличений.

    Другой пример: дашбоард сайта Use Multiplier совершает 235 запросов. Если отфильтровать по слову “graphql”, останется 35 запросов. Выходит, JavaScript-разработчикам нужно 35 сетевых сессий, чтобы построить документ. Не многовато ли?

    Что же выгодней: один запрос или их десятки?

    В такие минуты искренне желаю, чтобы фронтендеров заменил HTMX. Они делают интернет хуже: больше запросов, больше трафика, больше расход CPU, дольше время ожидания. Таким разработчикам не место в профессии.

    Вторая мысль об HTMX такая: часто говорят, что это “хайп” (в кавычках, потому что не люблю это слово). Очередная вещь, которая пройдёт зенит и уйдёт из повестки.

    Это не так. HTMX — это не очередная JS-поделка, снискавшая популярность. HTMX и его аналоги — это протест. Отказ от того, что предлагает индустрия для разработки приложений в браузере. Протест — по определению более сильная вещь, чем хайп, потому что в его основе идея.

    В этом году исполняется 10 лет с публикации исходного кода React.js. У Реакта и аналогов было достаточно времени, чтобы показать себя. Результаты есть, но не ошеломительные. Да, по сравнению с Backbone.js делать интерфейс стало проще, однако рано или поздно все сводится к одному: проект тонет в каше из компонентов, а состояние разбросано, как субстанция, попавшая на вентилятор.

    Сейчас работаю с Vue, и чтобы добавить новый диалог, нужно поправить 18 файлов. Такая структура явно говорит о проблемах, но никого это не волнует. Отрефакторить это невозможно, потому что поедет все. Только переписать на новый фреймворк, что обязательно состоится, когда бизнес купят или команда фронтендеров уйдет в полном составе.

    За эти десять лет мы получили одно — возросшую сложность разработки. Современный сайт обязательно содержит пачку npm-модулей, их сборщик, компоненты на React/Vue и бог знает что еще. В каждой фирме эту кухню готовят по-разному; вся она глючная и хрупкая.

    Еще печальней, что фронтендеры, получив инструменты, не научились ими пользоваться. Фронтам нужно 35 запросов Graphql на страницу; 14 запросов на открытие диалога. Одна и та же сущность запрашивается по пять раз. Это полная капитуляция, расписка непригодности разработчика. Если нужно 35 запросов на страницу, в команде не думают о качестве, а просто закрывают тикеты. Это просто данность.

    За это время я видел только одну удобную обертку над React — это кложурный re-frame. В нем скрыли острые углы Реакта и свели разработку к простому принципу: база, подписка, событие. Просто настолько, что дальше уже невозможно. Конечно, и на re-frame можно сделать проект неподдерживаемым, но кривая сложности у него более покатая.

    HTMX и его аналоги — это отказ от всего, описанного выше. Это отказ от хрупких npm/js-артефактов. Это отказ от команды фронтендеров, которым платят 10-20 тысяч долларов в месяц — на эту сумму можно купить тысячи машин в облаке. Это отказ от сложности коммуникаций, когда бекенд выкатил фичу, а фронты доберутся до нее через месяц. Это отказ от двух источников правды — сервера и состояния на клиенте — в пользу одного. И много от чего другого отказ.

    Поэтому я верю, что HTMX и схожие проекты с нами надолго. Эпоха Реакта и реактивного интерфейса проходит. Результаты есть, но они обходятся слишком дорого. Время нового подхода.

    Третья мысль об HTMX касается его роли в прошлом. Мысль о том, что HTMX появился недавно и поэтому хайп — ошибочна. На самом деле серверный рендер существует давно, и некоторые его используют. До сих пор о нём было мало разговоров, потому что в центре внимания Реакт — и сумасшедшие деньги, которые вливал в него производитель. Не только на зарплату разработчикам, но и поддержку, связи с сообществом, конференции, митапы и прочее.

    Серверный рендер по существу очень прост. Сервер выдает HTML, который вставляется в нужное место DOM. Кустарная реализация занимает не более ста строк, поэтому неудивительно, что серверный рендер тихо делает свою работу — без кричащих статей на Hacker News, звезд на Гитхабе и остального.

    Другое дело, что кустарное решение учитывает только свои нюансы, поэтому нужен общий знаменатель. Так и появились проекты HTMX и аналоги.

    Не каждый знает, что серверный рендер был одно время в Твиттере. Первые 20 твитов грузились как часть страницы, а при скролле выгребались куски HTML, в которых были новые 20 твитов и так далее. Хорошо это помню, потому что у меня был пет-проект по парсингу Твиттера. С HTML было относительно удобно: распарсил, прошелся Xpath-селекторами и готово. Серверный рендер в Твиттере ввели после того, как люди стали массово жаловаться на клиентский рендер — он был столь ужасен, что пара вкладок раскручивала вентиляторы на полную.

    Пользуясь случаем, скажем отдельное спасибо фронтендерам за это.

    Кроме Твиттера, серверный рендер использовал ваш покорный слуга. Было это 13 лет назад в Чите, в славной компании ООО Энергосбыт. Возле моего кабинета стоял терминал для показа каких-то роликов. Я решил сделать из него облегченную версию личного кабинета без авторизации. Вводишь лицевой счет и номер квартиры и видишь задолженность и показания счетчиков. Можно передать текущие показания. Принять деньги, увы, было нельзя из-за отсутствия купюроприемника.

    Интерфейс терминалов — это обычный Хром, запущенный с ключом --kiosk (по крайней мере раньше он так назывался). В режиме киоска браузер растягивается на весь экран, прячет курсор и противится попыткам свернуть его или открыть системные менюшки. Беда в том, что если во время запроса обрывалась связь, Хром показывал страницу “Oh no!” с диназавром, и нужно было нажать кнопку “Обновить”. Сейчас Хром обновляет ее по таймауту, а тогда нет.

    Ясное дело, я не мог бегать каждый час к терминалу смотреть, все ли с ним в порядке. Нужно, чтобы все работало на аяксе, но одна мысль об этом бросала в ужас. На дворе 2009 год, никаких реактов нет и в помине. jQuery в зените популярности, развивается Backbone.js — попытка навертеть MVT-фреймворк поверх jQuery. Окинув этот зоопарк, я решил задачу проще: на каждый запрос отвечал куском HTML, который вставлялся в центральный элемент на странице. Это было неоптимально, потому что в обновлении нуждались не все элементы, но разницы не было.

    В итоге я контролировал все на сервере, а клиент был минимально прост. Разработка заняла неделю, и вскоре терминал стоял в самом проходном месте города. Им пользовались, все было хорошо. Ради интереса представил разработку сегодня: npm/yarn, React/Vue, папка node_modules, хрупкие сборки и конечно компоненты, компоненты, компоненты. Команда фронтендеров, недели и месяцы работы. Неподдерживаемый результат в конце, смена команды и переписывание.

    Вот почему я уверен в своей правоте: я пробовал и знаю. Серверный рендер — это просто и быстро. Да, есть недостатки, и порой без клиентского кода не обойдешься. Но ни Реакт, ни Вуй даже близко не приблизились в плане скорости и удобства к серверному рендеру.

    Четвертый пост об HTMX касается его не очевидных недостатков. Прочитав текст выше, кто-то может решить, что HTMX — это избавление от всех бед фронтенда. К сожалению, это не так. Ниже я перечислю, какие трудности вас ждут при переходе на HTMX.

    Прежде всего, HTMX не подходит крайне динамичным страницам — картам, редакторам текста, играм. Их объединяет сложное состояние, которое меняется даже не клику, а по движению курсора или прокрутке. Опрашивать сервер с такой частотой будет тяжело, хотя и возможно: в HTMX есть поддержка веб-сокетов. Всё зависит от условий задачи, но для сложного состояния HTMX будет скорее проблемой.

    Второй момент — с HTMX усложняется серверный рендер. Раньше вы отдавали данные клиенту, а как он их выводил, вас не касалось. А теперь вы за это в ответе.

    Предположим, вы достали из базы число покупок пользователя. Чтобы вывести фразу “У вас X покупок”, нужно учесть случаи:

    • X равно нулю или NULL, и тогда фраза будет “у вас нет покупок”;

    • учесть множественность: “1 покупка” и “N покупок”;

    • для второго случая учесть склонения: “3 покупки, 5 покупок, 21 покупка”.

    Нужно писать функции, таблицы склонений, стемминг и остальное. Что-то есть в библиотеках, но без их адаптации не обойтись.

    Еще интересней даты и форматы чисел, валют. Раньше ты выплюнул JSON с Unix timestamp, и остальное тебя не касается. А теперь, перед тем как рендерить, нужно узнать локаль пользователя — из запроса, кук или сессии — и передать ее во все подобные функции. Это усложняет процесс.

    Положа руку на сердце, гораздо удобней отдать JSON, не заморачиваясь с рендером. Но потом, когда фронтендер уйдет или заболеет, ты полезешь в его код и увидишь, какой же там ад. И что лучше бы это был серверный рендер.

    HTMX усложняет обработку ошибок. Если что-то пошло не так, нужно вывести сообщение внутри элемента или в отдельной области при помощи техники OOB — out of boundaries. Это когда сервер возвращает несколько HTML-элементов, и они вставляются в разные места страницы. Кроме того, можно задать реакцию на неудачный AJAX-запрос на уровне библиотеки. Я не буду подробно все расписывать, скажу лишь, что об обработке ошибок в HTMX нужно думать с самого начала и придерживаться одного подхода. Иначе будет разброд и шатание.

    Тесты. Одно дело тестировать JSON, другое – HTML. Его нужно парсить, обходить проблемы склонений и форматов, применять рекулярки и XPath. Все это менее удобно, чем данные в JSON. Схемы – ваш лучший друг в случае с JSON, а какие схемы могут быть в HTML?

    Последний и наиболее важный недостаток — это двойной API. Как правило, бекенд предоставляет апишку не только сайту, но и мобильному приложению и третьим фирмам. Удобно, когда бекенд — это чистое API, и все это понимают.

    Теперь вы приходите к начальству с предложением сделать HTMX-апишку для серверного рендера. А зачем? — спросит начальство. На бекенде у нас REST/GraphQL, пусть сайт и ходит к нему через API. Этот довод почти невозможно проломить, потому что все сходится: бекенд общается с миром через JSON, у каждой платформы свой клиент. Что можно ответить?

    Пожалуй, то, что команда фрондендеров дорогая, а их труд тяжело поддерживать. Скажем, чтобы сделать динамический сайт, кроме дизайнера нужно как минимум два фронтендера: один идет вперед, другой чинит баги. В случае с бекендом достаточно одного человека, который бы поддерживал HTMX-апишку. Это и дешевле, и надежней, потому что бекенд покрыт тестами и не такой хрупкий.

    Поэтому не в каждой фирме дадут добро на серверный рендер. Протащить его в прод — та еще задача.

    Пятая заметка об HTMX касается важного момента — источника правды. Должно быть, после недостатков серверного рендера кто-то приуныл. Чтобы восстановить баланс, поговорим о решающем плюсе HTMX, который не видно на первый взгляд.

    Для начала вспомним React и Vue. Сильно упрощая, можно сказать, что их работа сводится к следующему. Мы переносим состояние с сервера на клиент и показываем в браузере. В теории нам не нужно беспокоится от отрисовке: реактивные фреймворки делают это за нас, когда мы изменяем состояние.

    Звучит хорошо, но таким образом мы завязаны на состоянии. Каждый, кто немного программировал, знает, что самое сложное — контролировать состояние. Поэтому так популярны Advent of Code и похожие задачи: для программистов это своего рода отдых. В них почти нет состояния: тебе дают одну структуру данных, и ее нужно переколбасить в другую. Нет базы, Кафки, Редиса и всего этого.

    Задачи из AoC решают на растах-хаскелях, потому что писать на них чистые преобразования — почти физическое удовольствие. Но приходит утро, и программист идет на работу, где его ждут кровавые Джава и Питон.

    Так вот, состояние на клиенте влечет сложность уже самим появлением. За ним нужно следить и синхронизировать его с сервером. Если вам кажется это простым, вы ошибаетесь. Бывает, сервер не может вернуть данные в одном запросе, и нужно слать их несколько. Бывает, одни и те же данные нужны компонентам А и Б, но их писали разные люди, и одинаковые запросы идут параллельно без проверки на дублирование. Последее я вижу постоянно: одну и ту же сущность выгребают по пять раз просто потому, что она нужна всем, а разработчики не договорились.

    Давно я читал в интернете: отдайте клиенту его данные, и пусть делает что хочет. Это не работает хотя бы из-за размера данных. Представим, вы активно пишете на каком-нибудь Твиттере или StackOverflow. За три года у вас скопилось 10 тысяч заметок. Вы хотите вывалить их клиенту при загрузке страницы? А заодно его друзей, рекомендации и прочее?

    Хорошо, будем выгружать порциями по 100 штук. Выгрузили — сохранили на клиенте — отрисовали. Спрашивается, почему эту цепочку нельзя сократить — нарисовать без сохранения? Ведь состояние быстро протухает: написал комментарий, поскроллил, сменил фильтры, критерии сортировки, и все — пора лезть на сервер за новыми данными.

    Все это мартышкин труд. Вы никогда не угадаете, что конкретно нужно клиенту в текущий момент. Выгружать все — дорого и долго. Остается запрашивать данные точечно: последние 10 статей, последние 50 комментариев. А если порции данных небольшие, зачем их хранить, если можно просто показать? Так мы уберем состояние, из-за которого одни сложности.

    Ликвидация состояния — важный шаг вперед: управлять клиентом становится проще. Помните аналогию с Advent of Code и функциональными языками? С HTMX я испытал похожие чувства. Да, оказывается, так можно: отдаешь HTML, который без какого-либо состояния отображается на клиенте.

    Резюмируя, можно сказать, что HTMX сводится к одному плюсу — ликвидации состояния на клиенте. Пусть каждый решает сам, но для меня это самое важное. Нет состояния — берем. Ради этой фичи я согласен на все минусы, о которых сказал раньше.

    Шестая заметка об HTMX касается дизайна. Возможно, кто-то решил, что HTMX — это когда фронтендеров увольняют, а суровые бекендеры берут дизайн в свои руки — с предсказуемым результатом. Может, где-то практикуют подобное, но я это не одобряю, и вот почему.

    Действительно, многим фронтендерам нужно дать пинка под зад. Например за то, что заставляют браузеры жечь трафик и процессор почем зря. Как мы выяснили, чтобы страница была динамичной, чаще всего фронтендер не нужен — можно вернуть HTML с сервера и вставить в DOM. Но остается вопрос с дизайном.

    В компании должен быть человек, отвечающий за дизайн всего: не только сайта, но и логотипа, буклетов, визиток и остального. Кто-то думает, что дизайн — это верстка в программе, но это не так. Дизайн — это точка, где клиент соприкасается с продуктом, и дизайнер отвечает за эту точку в целом.

    В компаниях, где процесс налажен правильно, он протекает так. Дизайнер делает макет в Фигме или иной программе. В ней указаны состояния страницы и сценарии перехода. Например, при нажатии на кнопку “добавить в корзину” четко указано, какие элементы изменятся и на что.

    Верстальщик или фронтендер (в классическом понимании этого слова) переносит дизайн в статичный HTML. Если это продвинутый верстальщик, он вынесет изменяемые элементы в отдельные файлы, которые импортируются шаблонной системой вроде Jinja2. Получается набор статичных страниц, но у каждой из них есть структура.

    Бекендеры принимают нарезанный HTML и оживляют его на сервере. При этом им запрещена любая отсебятина. Если бизнес-процесс не вписывается в дизайн, все трое — дизайнер, верстальщик, бекендер — собираются и решают, что исправить. Исправления вносятся во все три источника: дизайн, верстку, бекенд.

    При таком подходе принцип HTMX остается в силе. Бекендеры не выдумывают дизайн на ходу, они действуют в рамках, которые ставит им дизайнер. Верстальщик служит промежуточным звеном между дизайном и его реализацией на бекенде.

    В грамотных фирмах есть процесс сдачи сайта дизайнеру. Сайт не выкатят в прод, пока дизайнер не убедится, что верстальщик перенес дизайн в HTML без ошибок, а программисты оживили его без косяков.

    Так был устроен процесс в Wargaming, где я когда-то работал. И хотя там были свои косяки, мне кажется он единственно верным. Что ещё в нем хорошего — он не привязан к конкретным технологиям, и HTMX отлично на него ложится.

  • HDMI в тренде

    Раз в полгода телевизор докладывает, что сегодня в тренде… порт HDMI 1. При этом ни в один из HDMI портов ничего не воткнуто. Откуда он это берет? Неужели настоящие данные, собранные с устройств — люди играют в приставки, смотрят пиратки с ноутбуков?

    Этот порт, как говорит телевизор, “недавно в…”. Очень полезные сведения. Еще бы понять, что значит “в…”. Калека-дизайнер оставил квадрат пустым, а на текст выделил сотую часть. Не влезло, но ничего: обрежем и добавим многоточие.

    Забавно, как текут абстракции: в понимании телевизора порт HDMI — это приложение, поэтому участвует в трендах. Напоминает одну игру, где можно было чинить лошадь гаечным ключом. А что, транспорт, значит можно чинить.

    Проблема “умных” вещей в том, что они пытаются быть умнее, чем есть на самом деле. Нет-нет и вылезет какая-то тупизна, от которой нет слов. Только вздохнёшь и идёшь дальше.

  • Нейромазня

    Что ж, мы дожили до момента, когда нейросеть по запросу рисует кота-хакера за компьютером. Потрачены усилия, сделан прорыв, взяты рубежи.

    Верю, что доживу до момента, когда нейросеть объяснит, зачем мне этот кот. В какой текст его вставить, к чему подавать и что им объяснить.

    Потому что сейчас не понятно: на что этот кот? Зачем? Какую мысль он несет? Ладно кот, но все эти картинки туда же: ни малейшей идеи, чем они могут быть полезны.

    Чувак пишет статью о четвертом измерении и ставит такое:

    Какой-то алмаз, в нем пузыри, блики, крошки, капли смолы, планеты.

    Другая картинка: вензеля, стекла, то ли башня, то ли корабль. Что это вообще?

    Конечно, у женщин осиная талия и шестой размер груди. И нет трусов. По улице только такие и ходят.

    Никто не может сказать, какой смысл несут эти картинки? Что они добавляют в текст? Что потеряет текст, если их убрать? Хорошая иллюстрация несет смысловую нагрузку, помогает понять то, что трудно описать словами. Делает акцент на особых случаях, когда что-то отличается от повседневного.

    Как вы уже поняли, ничего полезного в нейромазне нет. Это мусор, который заполняет интернет, и нет от него спасения.

    Пара ссылок про иллюстрации:

  • Списки в In Design

    Опять Индизайн. Уж наверное, если сделали длинный список, нужно упорядочить его по алфавиту, нет? Секунд двадцать искал пункт Units в подвале, а он еще до середины находится. Интересно, что глаз скользит по списку, замечает Units, и тут же теряет, потому что мозг ожидает его не там. Сущее издевательство.

  • Удаленка, но есть нюанс

    Удаленная работа за рубежом имеет несколько преимуществ перед обычной офисной. Кроме очевидных, связанных оплатой — в валюте и выше рынка — я бы отметил автономность и самостоятельность. Ты как будто мини-фирма: сам себя продаешь, оформляешь, ведешь расчеты, платишь налоги. Претендуя на удалённую вакансию, конкурируешь не с тремя разработчиками из твоего города, а со всеми разработчиками смежных часовых поясов. Победа в такой борьбе значит больше.

    Есть, однако, и недостаток удаленной работы, о котором не пишут. Будучи удаленщиком, ты не будешь принимать решений. Вам просто не дадут полномочий. Вы будете делать только то, что скажет начальство и тимлид. Чтобы что-то внедрить или переделать, понадобится много сил — гораздо больше, чем у того, кто сидит в офисе и регулярно видится с начальством.

    Не нужно подробно описывать, почему так происходит. В любой группе людей коммуникация первична. Какие бы средства связи нас ни окружали — телефоны, Zoom, очки реальности, — общаться лицом к лицу проще. Поэтому сотрудник, который пьет кофе с боссом и ходит с ним в курилку, получит его расположение. Даже если офисный сотрудник что-то делает не так, его проще похлопать по плечу и наставить на путь истинный — в отличие от удаленщика, который появляется на экране раз в сутки.

    Будет неверно говорить о всех разработчиках, но мой опыт подтверждает сказанное выше. Где бы я ни работал, повторяется одно и то же. Если на горизонте появляется интересная задача, ее проработка достается тому, кто в тесном контакте с руководством. Это, кстати, не гарантирует навыков в разработке; гораздо чаще я вижу что-то вроде обратной зависимости.

    Может быть, вы пошли на обед, обдумывая новый сервис. В это время тимлид и коллега из офиса тоже пошли в “Жареный жир” и славно поболтали. К возвращению в офис уже все решено, формальности обговорены. На следующий день на созвоне вы излагаете свое видение сервиса, не зная, что в этом нет смысла. Вас вежливо выслушают и скажут, что решение отличное и его приберегут для будующих проектов. А пока что Джон уже приступил к разработке, и мы с нетерпением ждем.

    Сделав черновик, Джон с пафосом презентует его фирме, после чего его роль выполнена. Он уходит в другую команду или приступает к проработке нового проекта. Дальше наступает рутина удаленщика — поддержка этого чуда. Ваш выход! Моментально находятся краевые случаи, которые Джон не предусмотрел, недостаток тестов, банальные баги. Ты их чинишь. Дни становятся неделями, месяцами, годами. Когда проект заработает стабильно, вас перебросят на поддержку новой сырой поделки.

    Бывают, конечно, и маленькие победы: путем рефакторинга удается заменить самописный треш на библиотеку или, наоборот, отказаться от жирной библиотеки в пользу десятка строк. Если в фирме совсем все плохо, правильные решения говорят лучше тысячи слов. К примеру, нормальное тестирование, которое можно развернуть локально, не прибегая к удаленным машинам; линтинг, внутренний гайд разработки и прочее.

    Кто-то подумает, что пост носит жалобный характер, но это не так. Со временем я понял, что, во-первых, навозну кучу разгребая, что-то да найдешь. Совершенно точно поймешь, как не надо делать. Роль поддержки освобождает от тесного общения с начальством — а это много митингов и поездок в офис. Свободное время можно потратить на блог, книгу, опен-сорс, семью.

    Все мои годы удаленки — это поддержка чужих решений. Да, что-то делал и внедрял, но в гораздо меньших пропорциях. В одной фирме я пробыл 3.5 года, и это был самый длинный период работы на одном месте. При этом только на четвертый год мне доверили делать важную функциональность почти самостоятельно. Почти — потому что и в этом случае были жесткие рамки в плане технологий и фреймворка, местами неудачные.

    Вот, пожалуй, что нужно держать в уме, собираясь на удаленку. Да, она сделает вас самостоятельным и пробивным, да, вы будете получать больше коллег из яндексов и сберов. Но чтобы обсуждать ключевые вопросы, чтобы принимать решения, нанимать, руководить — будьте добры в офис.

  • Запуск InDesign

    Готовлю книжку к печати и поэтому вынужден иметь дело с Адобом. Избежать этого шага невозможно — некоторые программы заменить нечем. Несмотря на то, что в адобовских программах я работаю буквально 20 лет, поминутно матерюсь из-за их косяков. Покажу серьезный прокол, который заслуживает отдельного поста.

    Перед вами видео, где я запускаю Индизайн. Обратите внимание, что приложение стартует быстро: буквально пару секунд занимает сплеш-скрин, а дальше распахивается окно. Это, кстати, не заслуга Адоба: просто в процессе записи я несколько раз открывал и закрывал его, и поэтому оно прогрето. Холодный запуск будет медленней.

    Но дело не в этом. После того, как окно распахнется на весь экран, программа вступает во вторую фазу: загружает внутренний экран с последними файлами и рекламой новых фич. Эта загрузка длится десять секунд. Целых. Десять. Секунд. Пока он не просрется, не видно последних файлов и кнопок создания нового документа.

    В итоге сидишь и тупишь в пустоту, пока что-то там не загрузится. Однако если нажать Ctrl+O, откроется диалог выбора файла. Выходит, программа прекрасно работает, даже если главный экран не загрузился! Если выбрать в диалоге файл с проектом, он откроется мгновенно. Можно не ждать эти 10 секунд, а открыть файл ручками и работать. Это подтверждает второе видео:

    Такие вот интересные программы Адоба.

    Чем-то это напоминает современные веб-приложения: программа загрузилась, но это присказка, не сказка. Мы только загрузили скрипты, далее они выгребут свое дерьмо с серверов и только затем покажут приложение. На телевизорах такое постоянно: первый прогрес-бар показывает загрузку приложения на уровне ОС, а приложение запускает второй прогресс-бар для загрузки своего барахла.

    Печально, что эту ерунду нельзя объединить в один шаг, потому что как пользователю мне эти фазы до одного места: один хрен программа не работает. Вдвойне печальней, что это зараза переходит на десктоп.

    Подозреваю, что упомянутый главный экран — ничто иное, как Хром + Node.js + React. Это видно по косвенным признакам: он похож на Слак и прочие поделки, которые не могут быть отрисованы частично, а только целиком. Возможно, скрипты ломятся в сеть, но блокируются из-за санкций или бог знает чего. Ожидание в 10 секунд похоже на таймаут, заданный при отправке HTTP-запроса. Спасибо, что хотя бы выставили его: по умолчанию он равен 30 секунд.

    Странно, что последние файлы отображаются внутри браузера, хотя никак не связаны с ним. Это банальная глупость, деградация разработки. Надо сказать, я не удивлен. В Адобе много что делают на Node.js, например дашборд, из которого ставятся приложения. Я как-то шарился по папкам и нашел ворох скриптов. Плюс часто выскакивает диалог с текстом “приложение node хочет доступ к такому-то сертификату.”

    В сотый раз повторю тезис: сапожник без сапог. Фирма, которая тридцать лет пишет настольные программы под Винду и Мак, не может нормально показать последние файлы. Для загрузки приложений делается поделка па Хроме и Js, глючная и тормозная. Деградация софта в угоду менеджменту: сделать тяп-ляп, но зато быстро и получить повышение.

    Хочется верить, что индустрия печати пересядет с иглы Адоба на что-то другое, но пока что просвета не видно.

  • Avoid code you cannot debug

    This is a small tip I’d like to share with Clojure programmers.

    In a project, avoid code you cannot debug. It’s simple: if you can put a tag like #debug or similar somewhere in the middle, run a test and hang in a debugging session, you’re good. But if you cannot, you’ll be in trouble one day.

    Thus, any kind of DSL or yet another “smart” solution is a source of potential problems. Take Meander, for example. Imagine I have a map like this:

    {:name "Ivan"
     :address {:city "Chita"}}
    

    and I want it to become this:

    {:name "Ivan"
     :city "Chita"}
    

    With Meander, I would write:

    (m/match
      {:name "Ivan" :address {:city "Chita"}}
      {:name ?name :address {:city ?city}}
      {:name ?name :city ?city})
    

    and it works fine. But one day, my datasource suddenly returns a user without an address:

    {:name "Ivan" :address nil}
    ;; or just {:name "Ivan"}
    

    which is completely fine because a user might have no address associated with them. By passing that map into m/match, I expect it to return {:name "Ivan" :city nil} but no: there will be an exception:

    (m/match
       {:name "Ivan" :address nil}
       {:name ?name :address {:city ?city}}
       {:name ?name :city ?city})
    
    Unhandled clojure.lang.ExceptionInfo
       non exhaustive pattern match
       {}
    

    The line “non exhaustive pattern match” tells nothing to me nor the ex-data does. The message is fuzzy, there is no context, the ex-data has nothing useful (it’s an empty map). Having such an entry in logs or Sentry would not help you in a bit.

    Moreover, you cannot debug it. The m/match macro expands into a huge block of code. Debugging it somewhere in the middle would be quite challenging.

    Now compare it with a plain function that splits the data step by step:

    (defn remap-user [entry]
    
      (let [{username :name
             :keys [address]}
            entry
    
            {:keys [city]}
            address]
    
        {:name username
         :city city}))
    

    First, it works with both maps:

    (remap-user {:name "Ivan"})
    => {:name "Ivan", :city nil}
    
    (remap-user {:name "Ivan" :address {:city "Chita"}})
    => {:name "Ivan", :city "Chita"}
    

    Second, I can always put a debugging tag into that function and observe the local variables, the state and even run some expressions. With Meander, it’s just impossible or only possible with certain effort.

    Third, if a city is required, I’d put something like this:

    (assert city "The city is missing")
    

    and get a clear exception I want.

    Vast Meander patterns are completely unmaintainable. Pass something weird and you’ll get a “non exhaustive pattern match” message with no idea about what went wrong.

    Finally, debugging is crucial. If you cannot hang in the middle of execution and observe the state, that’s bad. Most Clojure programmers believe it’s a special language liberating you from debugging errors, but it’s not true. Debugging has not gone anywhere even with such a great language as Clojure.

Страница 12 из 75