nikitonsky_pub | Unsorted

Telegram-канал nikitonsky_pub - Стой под стрелой

10682

Ведет @nikitonsky. Рекламы нет

Subscribe to a channel

Стой под стрелой

Чего я не понимаю так это лимита на длину строки. Ну там 80, 120, знаете, как занудные программисты любят себе настроить и потом еще другим мозг этим парить.

Не понимаю я вот почему. Ситуации бывают разные. Бывают 4К телевизоры, а бывают 720p ноутбуки. Бывает хорошее зрение, а бывает шрифт 20 пунктов. Бывает терминал развернут на весь экран, а бывает на половину. Бывает открыта дерево файлов слева, а бывает дебаггер справа. Короче, в каждый конкретный момент размер экрана может быть совсем разный. Даже в пределах одного программиста и одного сетапа.

Ну и какой из этого вывод? Очевидно, что ширина редактора должна настраиваться редактором, динамически. В зависимости от размера окна. Или настроек пользователя. Или еще каких-то факторов. К счастью, редакторы это прекрасно умеют, и код переносить, и ресайзиться динамически. Даже терминалы умеют, что уж о нормальных редакторах!

А предлагается что? Предлагается эту ширину захардкодить в абстрактное с потолка взятое число. Ну, не совсем с потолка, конечно, а знаете откуда? С перфокарты. Да, это не шутка. 80 символов — это 80 колонок на перфокарте. Загуглите фотку, если не верите.

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

Но самая жопа знаете какая? Это изменение необратимо. Если ты расставил переносы после каждого 80-го символа, редактор ничего с этим не сможет сделать, только показать как есть. И пофиг, что у тебя справа еще три тыщи пикселей пустуют. Тимлид сказал что надо врапать после 80-го — значит будем врапать.

А наоборот — обратимо. Если принудительно текст не переносить, то редактор прекрасно его перенесет на любой желаемой колонке, в реальном времени, хоть 60 раз в секунду.

Так что ситуация несимметрична. Выбор очевиден. Но попробуй пойди это объясни программистам.

Читать полностью…

Стой под стрелой

Когда-то, лет, допустим, 20 назад, фичи операционных систем что-то значили. Помню, как читал книжку по Windows 95 и восхищался кнопке Пуск, панели задач, корзине и пытался понять, зачем нужен Портфель. У МакОСа тогда тоже наверняка был такой период, просто у меня на него денег еще не было.

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

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

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

А хотелось бы чтобы в ОС тоже теплилась какая-то жизнь. Чтобы выкатывались новые фичи и АПИ, полезные системные сервисы, которыми хотелось бы пользоваться.

И вот у меня есть идея, что можно было бы улучшить. Работу с фокусом. А именно — кражу фокуса. Дело в том, что сейчас любое приложение может украсть фокус в любой момент. Захотелось левой пятке — пошло и выставило себе на передний план. Юзер-экспириенс хуевый, зато, наверное, менеджеры рады.

В вебе есть похожие прецеденты. Например, когда-то страница могла открыть всплывающее окно в любой момент. А теперь — не может. Надо, чтобы пользователь сперва активно на что-то нажал. Так веб защищает пользователей от недобровестных сайтов.

Хочется, чтобы ОС работали так же. Я нажал на иконку — появилось окно и забрало фокус. Я переключился куда-то — все, хуй тебе, а не фокус. Жди, пока тебя явно не позовут. Это гигиена простейшая, правила хорошего тона.

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

Сейчас некоторые приложения латают кражей фокуса собственные проблемы с запуском. То есть я кликнул на иконку, приложение начало запускаться и запускается, скажем, 10 секунд. В течение этих 10 секунд на экране ничего не происходит. Пользователь, естественно, уходит заниматься своими делами. А тут приложение хоба-на: «я запустилось». И вылезает поперек экрана. Ну что за дела?

В общем, было бы круто, если бы ОС встали немножно на сторону пользователя и боролись с подобным абьюзом, ровно как это происходит в вебе. А то сколько раз можно переключатель раскладок ломать, а, Эпл?

Читать полностью…

Стой под стрелой

Хостер Vercel анонсировал поддержку баз данных, в том числе Postgres, и проиллюстрировал анонс вот таким примером кода:


import { sql } from '@vercel/postgres';
import { redirect } from 'next/navigation';

async function create (formData: FormData) {
'use server';
const { rows } = await sql`
INSERT INTO products (name)
VALUES (${formData.get('name' )})
`;
redirect('/product/${rows [0].slug}');
}

export default function Page) {
return (
<form action={create}>
<input type="text" name= "name" />
<button type="submit">Submit</button>
</form>
);
}


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

Интересно, что код начали гнобить! Это шаг назад, возврат к ПХП, код-лапша, кто так пишет. Ну, знаете, эти вот незлые (на самом деле еще какие злые) неконкретные комментарии, работающие на чувство собственной важности комментирующих.

Ну а я на другой стороне баррикад: а что, собственно, вам не нравится? Код простой и прямой, красота же! Что еще надо? Фабрик насыпать? Монад? И-де-аль-но же!

Ну и ПХП тоже не с бухты-барахты захватил интернет. Он был простым, удобным и логичным. Миллионы мух не могут ошибаться — в том смысле что если у Руби 1% рынка а у ПХП 90%, то наверное он что-то такое все-таки дает людям, что-то важное, чего не дает Руби. И можно воротить сколько угодно от него нос, но факт остается фактом, цифры говорят сами за себя.

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

Так что даешь make PHP great again! Можно нам хотя бы одну штуку в компьютерах, которая просто и понятно работает? А с типами идите в Котлин свой играть, как раз сборку в Гредле настроите к моменту, когда я свой сайт допишу.

Читать полностью…

Стой под стрелой

Тут как-то удачно выпал Ludum Dare Game Jam на выходные, и я решил опять попробовать свои силы. А то сколько можно критиковать чужие вещи и не делать своих, жить в иллюзии, что я бы смог лучше.

Ну и в общем ощущения какие-то не такие радужные. Да, я опять взял Godot, у него как раз вышла четвертая версия.

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

Ну и вот. Сделал я какую-то заготовочку самую простейшую. Рисую спрайты — картинка не перезагружается. Гуглю — никто не знает, что делать. Перезапускай, говорят, редактор (перезапускается он тоже, кстати, странно — три иконки одинаковых показывает, одна, видимо, лаунчер, вторая лаунчер лаунчера, а третья уже сама программа).

Ладно, потерплю. Поработал два дня. Дай, думаю, выложу текущую версию. Экспортирую в HTML. Оно качает 500 Мб (еще!), пыхтит и... не работает. Гуглю. Опять, никто не знает, что делать. Но я такой не один.

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

Надо свой движок делать, короче. А то на интерфейсы что Годо, что Юнити смотреть невозможно без слез. Работать в них без Ютуба тоже, кстати — шансов найти нужную кнопку тупо нет. Надо именно посмотреть, куда и в какой последовательности нажимают другие люди. Хотя казалось бы — смотри как Фигма и делай как они.

Кстати, экспорт из Фигмы тоже полное говно. Я хочу, чтобы я поменял цвет и все, сразу в игре он появился. А сейчас надо четыре кнопки в разных местах нажать, чтобы просто картинку из нее получить. Будет первая фича моего гейм-движка: прямой риалтайм импорт из Фигмы.

Читать полностью…

Стой под стрелой

Решил поковырять небольшой сайд-проектик, который начал в прошлом году. Открываю, а там код разобранный (не работает то есть) и незакоммиченный. Так что первый совет — никогда не бросайте код в разобранном состоянии. Потом фиг вспомнишь, что ты сделать хотел. Ну и начать работать все-таки приятно хотя бы с какой-то запускающейся точки.

Надо чинить, значит. Начал разбираться. Ага, смотрю, импортов не хватает. Припоминаю, что я код там на модули разделял, ну и попереносил немного. Конкренто, некий core/get-byte отсуствует.

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

Ладно. Делаем (:require [homm.core.byte-buffer :as .... As что, собственно? Обычно я просто последнюю компоненту имени использую. Получается (:require [homm.core.byte-buffer :as byte-buffer]).

Окей. Не нравится. Это каждый раз, когда мне надо байтик прочитать, надо будет целое byte-buffer/... писать, длинно.

Окей. Может быть, есть какое-то естественное сокращение? Конечно! bb. (require [... :as bb]). Красиво, коротко, понятно!

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

Ищу и нахожу... то же самое! Я из прошлого года, скорее всего, проделал тот же самый логический путь и пришел к тем же выводам, и тоже везде использовал ... :as bb!

Вот что такое настоящая консистентность — консистентность мысли. Или, другими словами, принципы. Это был третий совет.

Читать полностью…

Стой под стрелой

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

Ну вот, делаю я это обычно через scp. И сначала я очень страдал, потому что, типа, в одной вкладке зайди по ssh, сделай ls, а в другой потом пиши команду scp, что как бы геморно — два терминала нужно. Но гемор даже не в этом, а в том, что имена файлов надо эскейпить, а в случае scp эскейпить дважды. Если честно, я до конца не понял, какие там правила, я просто обычно щедро отсыпаю кавычек и бэкслешей, пока не заработает. А торрентоделы, гады, любят иногда пробельчиков или, прости господи, скобок в имена насовать.

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

Ну короче, решил взять GUI-шную программу для походов на сервер. Уж они-то, поди, разобрались, какие там правила эскейпинга. Взял CyberDuck, т.к. он бесплатный, а нужно мне это раз в пару месяцев. Круто. Можно зайти (по WebDAV, правда, но он у меня уже был настроен), и все файлы как в Файндере нарисованы, можно мышкой выбирать один или пять подряд или три через один, можно перетаскивать, красота, в общем. Пик удобства, прогресс (да, я правда терпеть не могу терминалы).

А что, думаю, надо проверить, как у них дела с эскейпингом имен с квадратными скобками. Начинаю искать такие файлы и не нахожу!

Короче, CyberDuck, вместо того, чтобы их как-то эскейпить корректно и обрабатывать просто берет эти файлы и не показывает. Не, ну а что, тоже решение.

Морали не будет. Занавес.

Читать полностью…

Стой под стрелой

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

- Поменяла возвращаемое значение функции, но не поменяла места вызова;
- перепутала иммутабельное API с мутабельным;
- позвала API, которые забыла подключить в проект;
- придумала несуществующие API, типа path-seq на замену file-seq, или ZoneId/UTC вместо настоящего (ZoneId/of "UTC");
- подвигала без особой причины кучу кода, удалив нечаянно важные части;
- склеила код из по-отдельности логичных, но не стыкующихся частей, типа:


(-> {:code code :name name}
(when notes (assoc :notes (str/trim notes))))


- добавила комментов, которые повторяют название функции, типа


;; Fill all features of the font
(defn fill-features [font] ...)


- разсбалансировала скобки 🙂

Когда я понял, что что-то тут не чисто, пошел перечитал описание, и да, точно, нейросеть только так и пишет (можно все не читать):


I hope this message finds you well. I wanted to reach out to you regarding my recent pull request to your repository. I have made several improvements to the code, which I believe would benefit the project as a whole.

Firstly, I have included unit tests, added try-catch blocks, and simplified the multimap-by function to enhance the code's reliability and prevent potential errors. I also have added docstrings to make the code more understandable and easier to navigate.

Moreover, I have used a threaded ->> macro to simplify the code and replace the println statement with proper logging to improve the code's readability. Finally, I have enhanced the code's modularity and conciseness, making it more maintainable and easier to modify in the future.

I believe that these changes would greatly improve the project's overall quality, and I would be honored if you could review my pull request and consider accepting it. Thank you for your time and consideration.


Работать программистом она явно пока не может, даже джуном. Но время мое успешно потратила.

Так что с почином. Дальше будет только хуже.

Читать полностью…

Стой под стрелой

Поскольку я уже старый, мне надо периодически пить таблетки. Память в моем возрасте уже не очень, так что у меня стояла на них напоминалка. Как-то я поделился скриншотом в Твиттере, и мне говорят: а чего ты приложение «таблетки» не используешь?

И правда, у Эпла есть такое приложение, специально для таблеток. Перешел. Использую. И вот какие ощущения.

Вам не кажется, что вся эта история с приложением на каждый чих, ну, немножко переходит в область абсурда? Что смысл существования многих приложений, ну, как бы высосан слегка из пальца?

То есть понятно, индустрия приложений, многие люди только на этом и живут, но вот с точки зрения пользователя — действительно ли «Таблетки» приносят так много добавочной пользы, чтобы не пользоваться обычными «Напоминаниями»? Приносят ли они _вообще_ хоть что-то, чего нет в Напоминаниях или Календаре?

Кстати, о Календаре. Если честно, разницу между календарем и напоминаниями я не очень понимаю, мне кажется, они плюс-минус одними и теми же объектами оперируют (разовые или повторящиеся события).

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

Если честно, я бы вообще много чего вел тупо в Телеграмме, если бы группы на одно себя было бы легко создавать. Почему нет? Один интерфейс, к которому быстро привыкаешь.

Короче, есть ощущение, что специализированные приложения это немножко зашквар, а настоящее просветление — в чем-то простом, едином и универсальном. В некоем комбайне, сочетающем заметки, календарь/напоминания и чат. И делай там, что хочешь. Power to the user, так сказть.

Есть такое уже? Или плохая идея?

Читать полностью…

Стой под стрелой

Посмотрел Сэма Олтмана (OpenAI) про ChatGPT у Лекса Фридмана.

Во-первых, удивительно, как люди любят путаться в словах. Обладает ли ChatGPT сознанием? Создали вы ИИ? При том что эти слова могут означать что угодно, более того, мы сами решаем, что они означают. Вот мы сделали что-то, оно вот так работает, какая разница, каким словом вы это назовете?

Во-вторых, уверенность, что мы узнаем сознание, когда его увидим. Дело в том, что мы не знаем, как это понять. Вот есть вокруг нас, например, муравьи, вороны, дельфины. Обладают ли они сознанием? Даже если и да, они явно не торопятся вступать с нами в контакт. Но есть также и люди, аборигены какие-нибудь, например, которые днем ходят отжимать у львов добычу, а ночью укуриваются и ловят приходы. Обладают ли они сознанием? Есть ли у них понятие «я»? (вроде не у всех?) Страдают ли они от своего существования? Ищут ли цель жизни? И если они всего этого не чувствуют, то что с этим делать? Ведь мозг у них точно такой же.

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

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

На что у меня есть два ответа. Первый: что значит захочет? В подкасте это тоже несколько раз проскакивало, причем незаметно. А это важно — «хотеть» это слишком человеческое, и вообще говоря к интеллектуальной деятельности отношения не имеет. Так же как и другие чувства: злость, зависть, радость, амбиции. Типа, конечно, можно будет, наверное, когда-нибудь это все в ИИ добавить, но вопрос — зачем? Нужен ли нам страдающий или сомневающийся компьютер? Написал функцию, а он тебе: I’m sorry, Dave, I’m afraid this code looks too stupid to even try to compile.

Ну и второй: а вы уверены, что сверх-интеллект вообще захочет с нами возиться и чем-то там управлять или контролировать? Потому что если посмотреть на наш мир, на вершине сидят далеко не самые умные люди. Я как-то уже писал историю чувака, который придумал тест IQ. Он сделал тест, чтобы собрать клуб умных людей и решать судьбы мира. Но оказалось, что собравшись вместе, люди с высоким IQ не особо спешили решать чьи-то судьбы, а вместо этого начали решать и обмениваться головоломками. Представляете, просыпается в компьютере супер-сознание, идет на амазон и заказывает себе книжечку «1000 и 1 судоку» на порешать.

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

Мне лично норм. Я как-то писал, что вся кажущаяся сложность нашего сознания на самом деле сформирована на конечном количестве входов. Просто это количество очень большое, поэтому кажется, что бесконечное. Но это неверно в математическом/физическом смыслах. Каждый из нас прочитал конечное количество книг, провел конечное количество часов за телевизором, прочитал конечное количество твитов, услышал конечное (хоть и очень большое) количество слов за всю жизнь. И то, что мы можем описать, что происходит в стихе «Влез котик на плетень и моргает, эта песенка короткая, не длинная» это не какое-то волшебное свойство нашего сознания, а просто следствие очень большого количества входных данных.

Guess what? Computers can now do that, too. Привет. Передайте, пожалуйста, следующий конверт с иероглифами.

Читать полностью…

Стой под стрелой

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

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

Но не в веб-программировании! Если думать об объектах как о прямоугольниках, то конечно, все будет просто. Но в вебе на каждый прямоугольник накладывается примерно миллион дополнительных правил: метрики текста, line-height, inline, выравнивание по baseline, распидорашивание флексов, наследование font-size и разные нелинейные единицы размеров, направление текста и прочие всякие зарезервированные места под скроллбар и тому подобное. Любой объект обязан про все это помнить и учитывать, но это просто не помещается номальному человеку в голову — поэтому и имеем то, что имеем. То есть нет-нет да и отвалится где-то что-то, или съедет, или наедет, или спрячется.

Конечно, скажете вы, тебе хорошо рассуждать про прямоугольники, но зато веб столько всего учитывает, там же СЕМАНТИКА. Ты не говоришь, что какой формы и что во что вложено, а как бы намекаешь компьютеру, что все это значит, и если повезет, то он покажет то, что ты от него хотел. А если не повезет, то покажет что-то другое и будет прав, а ты иди еще CSS подучи.

И я все это понимаю. Семантика, да. Сложная система, да. Но знаете что? Единственная семантика иконки внутри кнопки — что она стоит внутри по центру. И не надо мне про высшие цели рассказывать. Про высшие цели поговорим, когда вы научитесь иконки центрировать и три кнопки в ряд ровно ставить.

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

А как научитесь — там и про семантику поговорим.

Читать полностью…

Стой под стрелой

Короче, втянулся в Hitman, особенно в режим Freelancer. Причем втянулся довольно банально — увидел на Ютубе, зацепило, но чувак так плохо играл, что пришлось пробовать самому.

Freelancer — это такой roguelike, сделанный на основе существующих карт из Hitman 1-2-3, но хорошо сделанный, и в чем-то даже лучше отражает концепцию, чем оригинальная игра — приходится рисковать и импровизировать, а не ходить по одним и тем же дорожкам, заучивае расписание каждого NPC.

Кстати, твист на тему roguelike/roguelite довольно забавный. Roguelike это когда никакого мета-прогресса нет (например, Spelunky), а roguelite когда ты постепенно качаешься (как в Hades). Так вот, с одной стороны, во Freelancer ты постепенно нарабатываешь себе разного оружия, которое теоретически можешь брать с собой на миссии. А с другой — если что-то пошло не так, то его у тебя забирают. Так что прогресс тут такой, двухсторонний. Я за часов тридцать более-менее стабильно удерживаю только пару хороших пистолетов и пару винтовок, остальное как приходит, так и уходит.

А так да, все признаки Rogulite-игр: отлипнуть невозможно, сразу хочется еще дозы. Не ожидал, что ААА игры могут затягивать, обычно это удел инди. Ну и что понимать игру ты начинаешь после довольно существенного вложения времени (30-50 часов), за котороые обычные игры уже заканчиваются.

А интересно тут вот что. Мне кажется, что Хитман в первую очередь про контроль эмоций. Видишь возможность завалить свою цель? Не торопись, оцени обстановку. Это прямо противоположно тому, что _хочется_ сделать. Игра учит этому довольно жестко. Все пошло наперекосяк? Хочется, понятно, паниковать, а надо, наоборот, действовать четко, есть вполне конкретные шаги, которые нужно предпринимать. Это довольно сложно, учитывая, как все начинают бегать с винтовками наперевес, искать тебя и играет тревожная музыка, а тебе надо вести себя спокойно. Наконец, торопиться — последнее дело. Игра супер размеренная, большую часть времени ты подглядываешь из-за угла или там ныкаешься в шкафах. Но при этом это жутко интересно!

Еще, кажется, в Elden Ring была похожая зацепка. Когда ты видишь босса в первый раз, тебе хочется просто сразу бросить оружие и заплакать. Следующие несколько раз ты пытаешься что-то делать с его атаками, но делаешь это на инстинктах, то, что _кажется_ правильным (например, он замахнулся мечом — ты выставляешь щит, а он задерживает атаку и ударяет, гад, только через секунду). И только спустя пару десятков раз ты наконец понимаешь, что на самом это все был фасад, который пытался тебя обмануть, заставить действовать эмоционально, как _кажется_ правильным. А вместо этого есть вполне конкретные моменты и конкретные действия, которые надо предпринимать, и они даже не особо сложные. Но вот заставить себя хладнокровно смотреть, как дракон размером с дом машет хвостом и замахивается лапой и ничего не делать, пока не наступит правильный момент — вот где настоящий геймплей, настоящий челленж.

Короче, если что, рекомендую. Я слишком поздно/не там родился, чтобы оценить классические immersive sims, ну вот это closest and most pure thing today, кажется.

Читать полностью…

Стой под стрелой

Расходимся, я уже все придумал. Неэффективно, зато удобно и просто

TOFO — Tonsky’s [Serialization] Format

Requirements:

- Textual
- Simple to implement
- Single-byte UTF-8 subset (ASCII)
- Evertything is length-prefixed
- No string escaping
- Reasonably human-readable
- Space efficiency is not a first priority


| Type | Format |
|--------|--------------------------------|
| nil | 'n' |
| false | 'f' |
| true | 't' |
| int | 'i' + 8b value |
| string | 's' + 8b len + len bytes UTF-8 |
| list | 'l' + 8b len + len objects |
| dict | 'd' + 8b len + 2*len objects |
| space | \n or ' ' |



Numbers are signed 32-bit ints hex-formatted (uppercase) and zero-padded to exactly 8 bytes:


| Number | Representation |
|-------------|----------------|
| 0 | 00000000 |
| 100 | 00000064 |
| 2147483647 | 7FFFFFFF |
| -1 | FFFFFFFF |
| -10 | FFFFFFF6 |
| -2147483648 | 80000000 |



Example (with spaces):


d00000008
s00000002id i00000140
s00000007session s0000002436c8691a-4931-4995-9fea-bafb6a6d6174
s00000002op s00000004eval
s00000005forms l00000002
s00000007(+ 1 2)
s00000019(println "Hello, world!")
s00000002ns s00000004user
s00000004line i00000002
s00000006column i00000000
s00000004file s00000035/Users/tonsky/ws/clojure-sublimed/test_repl/forms.clj



Example (compact):


d00000008s00000002idi00000140s00000007sessions0000002436c8691a-4931-4995-9fea-bafb6a6d6174s00000002ops00000004evals00000005formsl00000002s00000007(+ 1 2)s00000019(println "Hello, world!")s00000002nss00000004users00000004linei00000002s00000006columni00000000s00000004files00000035/Users/tonsky/ws/clojure-sublimed/test_repl/forms.clj

Читать полностью…

Стой под стрелой

Полдня потерял на совершенно идиотский баг: в мобильной версии нашего родного Roam Research есть экранные кнопки для Cut/Copy, и вот они везде работают, кроме Cut в мобильном Сафари. Причем не работает совершенно молча — пошел нахуй, так сказать, вопросы?

В Гугле, естественно, у людей если и не работает, так уж все целиком — ни copy, ни cut. Мне бы их проблемы!

И вот пол дня я потратил на разбирательства. Обложил все логами. Поставил Xcode, чтобы цепляться к эмулятору Сафари инспектором. Хотел сначала просто к телефону, но не смог — то, как оно должно работать, не работает (веб-инспектор магически находит твой телефон), а кнопки чтобы это зафорсить нет и никакой диагностики тоже нет. Apple — it just works (not).

Перерыл DuckDuckGo, отчаявшись, даже у Гугла спросил. Уже морально приготовился переписывать код на использование copy + delete при нажатии на cut, что, блин, совсем нетрвиально, учитывая количество вариантов, в которых оно может вызываться.

И наконец удача мне улыбнулась — я раскопал причину в исходниках WebKit, причем от отчаяния — к концу дня моя самооценка уже упала до нуля от беспомощных попыток починить происходящее методом тыка и ощущения, что я обезъяна, пытающаяся починить карбюратор, а чтение исходников это хотя бы осмысленное действие.

Оказалось, что перед тем, как выполнить Cut, Сафари (только мобильный!) проверяет canCopy & canDelete, и вот canDelete-то у него не получался, потому что у нас под это дело создавалась невидимая textarea и ей зачем-то ставился атрибут readonly (не спрашивайте, не знаю). А текстарея создавалась, чтобы программно породить событие "copy"/"cut", внтури которого уже можно работать с буфером. Потому что это же Web API, кто сказал, что должно быть удобно? Мне не нужно, чтобы работа была сделана, мне нужно, чтобы вы заебались.

Выводов три.

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

Второй — мобильный Сафари дно, всегда им был и до сих пор им остается. Даже если у вас все отлажено и работает в 99% браузерах, вас все равно выебет напоследок мобильный Сафари.

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

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

А веб — это работа с радномной хуйней, которая копилась 30 лет и которая меняется постоянно непонятно кем непонятно зачем левой пяткой. Я против вот этой вот обезъяньей работы, когда у тебя есть коробка с деталями от часов, тебе надо ее трясти, пока внутри детали сами вдруг не сложатся в часовой механизм. Почему нельзя по-нормальному? Прост.

Ну то есть как против? Расстраиваюсь я. А я хочу быть веселым. Всем доброе утро, веб-программистам соболезную.

Читать полностью…

Стой под стрелой

Писал в 2020-м в ЖЖ про Jetpack Compose, но оно и в контексте прошлого поста про ООП хорошо, и вообще про data-oriented design. С сокращениями:

Идея делать такое АПИ — видимо, призрачное счастье разработчиков. Действительно, что может быть проще, чем написать:

Column {
Button()
Text()
}

Максимально лаконичное API, да? Но если присмотреться, мы увидим, что Column принимает не список детей, а замыкание. Почему это? Спросите вы. А потому что это гребаные процедуры, вот почему. Придумав такое API, ты невольно загнал себя в угол — его нужно держать строго определенным образом, и никак иначе. Удобно в простых примерах, а дальше начинаются сложности.

Мы, программисты, привыкли, что в коде можно делать много разных вещей. И нам это нравится! Можно принимать значения, передавать значения, трансформировать значения, обрабатывать значения. Но вы поняли, наверное, уже, к чему я веду, да? Компоуз решил нас этой радости, потому что его API ничего не принимает и не возвращает. Там нет значений. Его API можно только позвать, конец истории. Нельзя написать функцию, которая сортирует компоненты. Которая вставляет разделитель в список компонентов. Нельзя даже нормально вложить один компонент в другой без создания анонимной лямбды. Потому что и компонентов-то нет. Только лямбды.

А лямбды это что? Это худший из возможных форматов хранения данных. Хуже структур, понятно, и даже хуже чем ООП. Лямбда — это черный ящик, черная дыра, максимально негибкое, неудобное и безполезное явление, на которое ни посмотреть, ни потрогать, ни сообщение послать, ни разобрать, ни распечатать, ни сравнить, а только обернуть в другую такую же гребанную лямбду или передать дальше. Лямбды невозможно упростить — они всегда только растут, толстеют, как слои лука у Шрека или жировые прослойки на твоей слоеной архитектуре. Максимально вредный объект, особенно как основа API. И поверьте, внутри Композа (да и снаружи) этих лямбд хоть лопатой жуй, и они все анонимные, и ничего не принимают и не возвращают, и от неявных ресиверов зависят, и друг друга заворачивают и разворачивают (ха-ха, шучу, лямбду нельзя развернуть!) и они анонимные все! А, это уже было. Ну вы поняли.

[...]

Самый удобный АПИ у нас уже есть — это функции с явным списком аргументов и возвращаемым значением. И все. Конец истории. Лучше не будет. Серьезно. Не надо мудрить, хитрить, не надо придумывать «более удобный DSL», не надо аннотации придумывать, не надо компилятор форкать, не надо вообще программисту помогать вызывать функции. Лучше все равно не сделаете, а проблем на разгребание всего этого — создадите. Лучшая помощь — оставить нас в покое и дать писать обычный код.

Читать полностью…

Стой под стрелой

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

Мне Арк не зашел, потому что автозакрывателем табов работаю я сам. Когда-то давно я табы копил, пока не прочитаю, и они на меня давили. А потом понял, что сам себя мучаю, и начал безжалостно их убивать. Пришел на работу, а на ноуте открыт Ютуб с незакрытым роликом? Закрыл, потом в истории найду. Не могу прочитать статью уже два дня? Ну значит не очень-то и хочется. Закончил рабочий день? Браузер должен остаться пустым. Любую открытую страницу всегда можно найти снова, было бы желание. Так что привычка хорошая, но целый новый браузер ради нее терпеть не хочется.

Есть другие модные ребята, делают терминал на Расте, называется Warp. Тоже простую концепцию решили разбавить «фичами» и «улучшениями», которые каждое по-отдельности вроде бы разумно и хорошо, а вместе создает какой-то лишней ментальной нагрузки, которой от терминала как раз не хочется. Из серии «а что будет, если...». В обычном терминале ты это себе хорошо представляешь, а что тут эти улучшаторы наулучшали — фиг его знает.

Когда я только начинал пользоваться Маком, мне очень понравился iTerm 2. Прям фичи были в самое сердечко, и много, и хорошо. Потом чет я понял, что ничем из них все равно не пользуюсь, и переехал на встроенный Terminal. Так с тех пор и не жалею. Терминал, конечно, можно сделать лучше, но, получается, не нужно.

Третий пример это почта Hey (не «неу», а «Хэй», типа «Э, слышь!»). Ребята придумали делить всю входящую почту на четыре потока — неизвестные отправители, инбокс, развлечения и чеки. Сбацали продукт, продают, вроде бы, все хорошо у них. Сам Хэй я не пробовал, зато сделал себе аналог на фильтрах Fastmail. Получилось хреново (фильтры нужно вручную обновлять, а интерфейс там не очень), но когда поток более-менее устаканился, оказалось, что это офигенно! Именно эти категории лучше всего прижились — важное, но неинтересное (paper trail), неважное, но интересное (feed), важное интересное (inbox) и неважное неинтересное (screened). Последнюю я, правда, не сделал, но и так уже хорошо.

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

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

Читать полностью…

Стой под стрелой

Если подумать, то в Си-подобном синтаксисе дофига нелогичностей. Ну, скажем, как вы вызываете функцию?


f(a, b)


При этом порядок вычислений будет: сначала a, потом b и только потом f. То есть 2, 3, 1. Ну бред же!

Более того, иногда можно писать вообще


a + b


И тут уже будет a → b → +, то есть левый, правый, середина. 1, 3, 2. Каково? И почему тогда нельзя писать


+(a, b)


(в Кложе, кстати, можно), или, скажем,


a f b


тогда уж? (в Хаскелле, кстати, можно) Потому что нелогично? Ну так и f(a, b) нелогично!

Если добавить объекты, то вообще начнется атас. Ну вот что это такое:


o.m(a, b)


Сначала вычислится первый (`o`), потом третий (`a`), потом четвертый (`b`), и только потом наконец второй (`m`). Нормально?

Зато методы на объектах можно стыковать:


o.a(x, y, z).b(p, q, r).c(s, t, u)


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

Кстати, если к этому еще присваивание добавить, то вообще кайф начинается!


x = o.m(a, b)


Тут вся та же беда, что и с объектами, только самое начало выполнится последним! Итого порядок будет 2, 4, 5, 3, 1. Пойди, объясни это неспециалисту.

И ведь даже простые люди нет-нет да чувствуют проблему и пытаются что-то с ней сделать. Ну там pipeline operator ввести какой-нибудь. Потому что писать


const num = multiply(add(subtract(15)))


это полный бред, надо быть сумасшедшим, чтобы это расшифровать. А вот


const num = 15 |> add |> subtract |> multiply


Толькоя я бы еще дальше пошел и присваивание тоже направо вынес. Чтобы уж совсем все по-порядку:


15 |> add |> subtract |> multiply => const num


Понятно, что это все идет из математики, включая желание писать 1 + 2, а не 1 2 + и не +(1, 2). Но мы-то инженеры, мы должны лучше эргономику чувствовать, чем математики. Математика вообще когда-то оптимизировалась под запись ручкой на бумаге, оттуда идут и однобуквенные обозначения, и всякие нетривиальные многострочные лайауты для дробей, и значащие орнаменты на буквах (N ≠ ≠ 𝒩).

Понятно, что запись 1 2 + => x выглядит дико. Но зато она логичная! К непривычности можно привыкнуть, а вот отсутствие логики не устранится никогда. Опять же, Лиспы тоже выглядят сперва непривычно, однако очень быстро привыкаешь писать (+ 1 2) и даже ловить в этом единообразии кайф.

Короче, пора уже вынуть голову из штанов, отбросить груз векового легаси и перепридумать синтаксис заново. Пора придумывать Форт.

Читать полностью…

Стой под стрелой

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

Вкратце, помимо собственно файла слева теперь панель с деревом кода, справа — панель символов в текущем файле, сверху sticky заголовок, который показывает начало функции, если ты долистал до ее середины, а кнопка T (перейти к файлу) теперь в малюсеньком попапе.

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

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

Второй момент — это лайаут. Я уже писал, как не нравятся дебаггеры и devtools чисто визуально, потому что там миллион панелей, расставленных более-менее случайно. Так и тут. Еще я когда-то писал, что первое ощущение от Идеи — что тебя обложили. Потому что панели со всех сторон — слева, справа, снизу и сверху. Хотя вроде особо выраженной клаустрофобией я не страдаю, но все равно, тесновато. Удивительно, что гитхаберы снизу никакой панели не влепили. А чего, место же есть!

В принципе, собрать «как было» в новом дизайне почти можно. Можно скрыть обе панели, и тогда из ухудшений останутся только трехуровневая прилипающая шапка и засунутый в попап go to file, который будет выровнен по правому краю (бе).

Я это пишу, потому что наверняка набегут умники только чтобы сказать «чего ты разнылся, вот же, можно сделать как было». А разнылся я, конечно, не для себя, а для моих дорогих читателей, которым не просто надо как-то приспособиться, а которые будут когда-нибудь дизайнить свой продукт и им это наблюдение пригодится: помнить нужно не только о функциях, но и визуальной простоте, лаконичности, легкости. Этот блог вообще не о том, как мне плохо с текущими инструментами, а как делать хорошие, новые.

А с Гитхабом, я думаю, дальше будет все хуже и хуже. Теперь, когда туда пришли vs-кодовцы и у них появились свободные руки, которые надо чем-то занять, он будет только усложняться. В здоровом стартапе, где рук сильно не хватает, фичи взвешиваются по коэффициенту легкость реализации/важность, и делается в основном только самое главное. В успешном энтерпрайзе же рук сильно больше, чем хороших идей, куда эти руки приложить. Поэтому реализуются даже супер неэффективные/ненужные фичи, просто потому что могут и потому что надо чем-то занимать программистов. Ровно то же самое произошло и с VS Code. Так что держитесь, зима близко.

Читать полностью…

Стой под стрелой

Любопытный инцидент произошел в твиттере. Проживающий в Сан-Франциско шведский дизайнер Расмус Андерсон выложил картинку с текущим состоянием кириллицы в его широкоизвестном шрифте Inter и попросил у носителей письменности комментариев.

Одним из первых в реплаи пришел Сережа Рассказов, дизайнер из Украины^W Петербурга, проживающий сейчас в Швейцарии, и выдал следующий фидбек:

> In small details not well. Most ugliest form is the left stem of the Л. Did you read this article? https://type.today/en/journal/neo

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

В общем-то, написать я об этом решил только когда увидел, что народ в обсуждениях этого инцидента путается с пониманием, что тут не так.

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

Но это, конечно, не то. Дело не в похвале и не в эпитетах (хотя и в них тоже). Просто этот комментарий неконструктивен. «Мне не нравится» — и что с ним, таким, делать? Зачем мне это знать? Как сделать лучше? Какие критерии? Что конкретно не нравится? Просто «not well» это обосрал и пошел дальше. И обижаться тут можно только на то, что если уж обсираешь, то ругай конкретные вещи. А так это прямая агрессия, и будь ты хоть американец, хоть русский человек из глубинке, хоть кошка, — это неприятно.

Еще раз. Никто не обижается на то, что тебе что-то не понравилось. Обижаются на то, что ты зачем-то с этим своим мнением пришел и на автора его вывалил. Типа, эй, у тебя рожа кривая! И дальше-то что? Что мне с этим делать? Кроме того, что ты себя обозначил как агрессивно настроенный ко мне человек. Но зачем?

А нормальный конструктивный комментарий выглядит как-то так:

> The Cyrillic breve must be wider and heavier than the Latin one.

Или так:

> Lift an oval of Ф just a tiny bit, otherwise it’s falling down.

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

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

Читать полностью…

Стой под стрелой

Накинул в Твиттере, как должно работать редактирование rich text.

Вкратце, если в строке 111222333 середина (222) выделена, например, жирным (курсивом, кодом — неважно), то между 1 и 2 должно быть две позиции курсора, а не одна. Сейчас (почти везде) одна — форматирование берется от куска слева. То есть можно дописать еще неформатированных единичек между 1 и 2 либо жирных двоек между 2 и 3, но нельзя дописать между 1 и 2 или неформатированных троек между 2 и 3.

Ну и говно получается. Сделал ты, например, ссылку с текстом «тыц». А потом думаешь: возьму-ка я ее в скобки. Ставишь скобку слева — она ставится простым текстом. Ставишь справа — она становится частью ссылки. Неаккуратненько.

Решение, которое я предлагаю: сделать вид, что там две позиции, даже если формально она одна. Типа, идешь курсором справа, дошел до границы 3 и 2. Стоишь в неформатированном тексте. Если начнешь писать, полезет неформатированный. Нажал кнопку «влево» — курсор остался стоять там же, но по внутренней логике ты перескочил «внутрь» форматированного куска. И теперь, если начнешь писать, в том же самом месте полезут уже жирные буквы.

Хорошая идея? По-моему хорошая. Простая, понятная, дающая пользователю силу и контроль. Удивительно, что за столько лет никто редактирование rich текста так и не пересмотрел и не перепридумал, все это тянется наверняка с каких-то первых word процессоров самых древних.

Но пост не об этом (сюрприз!). С одной стороны, идею активно поддержали, а с другой набежало куча фанатов Маркдауна, кричащих, что Маркдаун это то же самое или даже лучше.

Не лучше. Про Маркдаун надо понимать одну вещь: он родился от бедности. Писать как-бы форматированный текст там, где есть только plain text. Ну и поднялся частично на том, что rich text был настолько плохо везде сделан (о чем, собственно, моя идея) что всех заебал. А тут — проще, понятнее, предсказуемее.

Есть такая поговорка, якобы от лица продавца дрелей: «людям не нужна дрель, им нужна дырка в стене» (к ней тоже есть вопросы, но она очень уж эффектно доносит мысль).

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

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

Но это все не потому что я хочу заголовки выделять решетками, а потому что Sublime Text очень уж хороший, сука, редактор. Ну и потому что форматирование/редактирование в условном Ворде сосет.

Но тут важно понимать, что Маркдаун это не цель. Цель — красиво отформатированный и сверстанный текст. Так получилось, что сейчас это удобнее делать в Маркдауне. Даже если придется смотреть на весь этот мусор, который сопровождает их форматирование.

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

Но, опять же, это никак не ограничено Маркдауном. В Ноушне, например, это так и сделано: шрифт поменять нельзя, а слово жирным сделать можно.

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

Читать полностью…

Стой под стрелой

Увидел вчера видос, где якобы обсуждают «Worst Practices» программирования. Ну и там тетка три минуты рассказывает, как использует для дебага printf и ей стыдно. Мол, надо бы дебаггером научиться, конечно, пользоваться, но принты это так удобно.

Ну и в твиттере довольно адекватная реакция: народ не понимает, а почему, собственно, worst? Я склонен присоединиться: да, логически, дебаггер более правильное решение, более изящное, более мощное. Но только логически!

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

Ну и делать по этому поводу тоже понятно что: надо это преимущество найти, осознать, изолировать и может быть как-то более изящно в ИДЕ встроить, если получится. А не делать вид, что дебаггер очевидно лучше и всем было бы неплохо им научиться пользоваться. Очевидно, как раз, что не лучше. Осталось это признать и заживем мы все в мире и гармонии тогда.

Начать можно, например, с того, чтобы сделать его полегче как-то. Вот хорошо сформулировано:

> I’ve never quite understood why it [printf] is the worst: the feedback loop is very short so you get to quickly test hypotheses and explore the code. With a breakpoint you’re transported like some lower life form onto the USS Enterprise.

Я как-то постил в твиттере, что какие-нибудь условные Dev Tools тоже выглядят как космический корабль или картина Босха. К дебаггерам это тоже относится: там сразу открывается пяток панелей, которые как попало по экрану разбросаны, неочевидно друг с другом связаны и все время что-то показывают. Понятно, что иногда каждая из них по-отдельности нужна. Но не все же время!

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

Что думаете? Как починить дебаггер, чтобы люди хотели им пользоваться?

Читать полностью…

Стой под стрелой

Чистил на днях папку Downloads и натолкнулся на поведение, про которое в принципе знал чуть ли не с первых дней знакомства, но которое все равно приятно меня удивило на фоне все плохеющего и плохеющего софта.

В macOS есть понятие Quick Look — это когда в Файндере ты нажимаешь пробел и любой файл тебе как-то показывется тут же в попапе. В интернет-магазинах иногда подобное делают, типа, посмотреть чуть крупнее/подробнее, но не переходить на страницу товара (поотму что долго, контекст потеряется, кнопка назад кое-как работает и вообще это сайт, люди в вебе должны страдать).

Ну вот, в macOS такая функция тоже есть системно, и она типа покажет файл по-быстрому, не открывая его родной программы. Не со всеми форматами умеет, но с картинками, pdf и всякими текстовыми хорошо справляется, и даже сторонние приложения регистрироваться могут. Markdown, например, гораздо удобнее так смотреть, потому что иначе оно начнет Xcode открывать (что? да!), а это история не на одну минуту. А тут почему-то за миллисекунду может показать, хотя, казалось бы, тот же файл, и просмотр тем же Xcode-ом реализуется. Получается, могут и быстро сделать, если захотят.

Ну так вот, поведение это заключается в следующем: если открыть, скажем, картинку в QuickLook, появится попап с ней. Если после этого нажать Cmd+Down, который «просто открыть в программе», откроется Preview, полноценная программа уже, которая всякие там аннотации умеет, конвертацию и прочее. Настоящий просмотрщик уже.

Так вот, окно Preview возникнет вокруг уже открытой картинки. Т.е. картинка на экране не сдвинется ни на миллиметр, останется пиксель-в-пиксель, даже не дрогнет. А вот рамка окна от QuickLook спрячется, и на ее месте вырастет рамка окна Preview.

Ну круто же!

Причем это поведение идет с самых первых версий OS X, вроде как. По крайней мере с тех, с которых я начинал. Тогда еще операционные системы были не просто лаунчерами для Электрона, а имели какие-то отличительные черты, за счет которых переманивали пользователей. Старались помогать людям, а не менеджерам производителя.

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

Ну вот. А теперь ложка дегтя. Только я собрался этому в очередной раз порадоваться и написать в твиттер, что, мол, скучаю по тому самому Эплу, который делал такие вот безумные штуки на ровном месте и как за вот это вот дополнительное внимание его и ценили. Собрался, закрываю Preview, чтобы экран на этот раз заснять, а под Preview осталось окно от QuickLook! Незакрытое. И оно его мне гордо показывает.

Тут надо заметить, что QuickLook вещь вообще очень контекстуальная. Оно создает очень странные окна, которые не крадут фокус, например, и во многом довольно странно себя ведут. Так что это не то чтобы «оно показало окно незакрытого приложение». Это скорее что-то вроде «я функцию уже дописал, а автокомплит до сих пор открытый висит». Неожидаемое поведение. И раньше такого, вроде бы, не было.

Так что да. Чуда не случилось. Поведение, скорее всего, дожило до наших дней по чистой случайности. А я все равно скучаю по тому самому Эплу. Привет.

Читать полностью…

Стой под стрелой

Споткнулся вчера на довольно тривиальной фиче: я использую sdkman для управления версиями java, увидел, что на днях вышла 20-ая, а так как я люблю все новое, я конечно решил попробовать. Ну и пишу:


sdk use java 20-open


На что он мне:


Stop! Candidate version is not installed.
Tip: Run the following to install this version
§ sdk install java 20-open


То есть, эта сволочь знает, что надо делать, но не делает, а заставляет меня писать буквами.

Ну я конечно сразу жаловаться в твиттер, но сочувствия как-то не нашел. «Не люблю, когда что-то делают без моего ведома», «Пусть лучше спрашивает», «Что если я не хотел устанавливать?», «А если у меня 200 Мб осталось?», «Напиши скрипт, ты же разработчик».

Давайте попробую пояснить свою точку зрения.

> Не люблю, когда что-то делают без моего ведома.

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

> Пусть лучше спрашивает.

Чем лучше-то? Получается же непредсказуемость: одна и та же команда _иногда_ работает, а _иногда_ нет. Зависимость от глобального состояния.

Ну и вопрос Y/n он как бы ломает потенциальную автоматизацию, не? «Я запустил bootstrap.sh, и ничего не случилось, почему? А, там какой-то дебильный скрипт в середине решил со мной поговорить».

> Что если я не хотел устанавливать?

Но... Ты же хотел использовать? Как можно хотеть использовать, но не хотеть устанавливать? Одно явно подразумевает другое — нельзя использовать, не установив предварительно.

> А если у меня 200 Мб осталось?

Ну, давайте уже в современные реалии переместимся. Когда последний раз у вас 200 Мб оставалось? Сейчас некоторые сайты поболее весят.

Ну и в конце концов, осталось 200 Мб — ну не установится, но хотя бы по хорошей причине. В чем проблема?

> Напиши скрипт, ты же разработчик.

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

Плюс, не знаю, заметили ли вы или нет, но другие программы вообще-то ничего не спрашивают и им норм. Rust рутинно отжирает гигабайты и делает это вполне молча. Maven не спрашивает перед скачиванием каждой зависимости: хотите ли вы? Потому что я уже сказал, что хочу. Сайты тоже грузятся и кешируются молча. Представьте, каждый сайт бы вас спрашивал: «этот сайт весит 4,5 Мб, желаете продолжить загрузку?»

Почему идея «вещи, которые просто работают» считаются зашкваром? Кто испортил? Я хочу, чтобы вещи просто работали. Я хочу поменьше думать о несущественном и банальном. Я хочу тратить время на важное. И при этом я — разработчик.

Разве я о многом прошу?

Читать полностью…

Стой под стрелой

Кстати, пока мы не разошлись. В том же самом интервью Лекс, понятно, спросил, разгонят ли 90% программистов-неумех? На что Олтмен ответил: не разгонят, но если код станет писать легче, просто все начнут писать намного больше кода. Миру, говорит, кода остро не хватает!

Ну и по этому поводу у меня, конечно, противоречивые чувства. У меня есть ощущение, что как в двухтысячных начался Веб, так мы до сих пор и не разобрались, как его хорошо делать. И натив тоже. А тут уже ИИ привлекают. Стыдно!

С другой, конечно, как старому деду, мне кажется, что кода не мало, его много. Надо больше Кложей и меньше Котлинов, условно. Больше Go и меньше JS-а. Больше Хаскеллей, меньше C++. Больше unikernel-ов, меньше докеров. Больше короткого и простого, меньше раздутого и сложного.

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

Добро пожаловать в сингулярность!

Читать полностью…

Стой под стрелой

Не могу не написать про последнюю серию The Last of Us, раз уж начал. Как обычно —

СПОЙЛЕРЫ СПОЙЛЕРЫ СПОЙЛЕРЫ СПОЙЛЕРЫ

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

Поначалу вырисовывалась красивая концепция — все, кого герои встречают, живут максимум одну серию. Хорошие, плохие — все. Как вести себя в такой ситуации? Что будет тобой двигать? Что будут означать для человека такие встречи, если он знает, что долго они не продлятся? На все эти вопросы сериал не дает ответа 🙂 Более того, они даже ни разу не вспоминают потерянных попутчиков и встречи эти никак героев не меняют. Так что это скорее случайность, а не концепция. А жаль, хорошая тема была бы.

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

Остаются отношения девочки и Педро. Вроде бы, достойный костяк, немало хороших фильмов на этом сделано. True Grit, например, или, не знаю, Leon The Professional тот же. Но тут тоже какая-то дыра, в некоторых сериях героев вообще почти не показывают!

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

Ну и про концовку. Я знал, что она противоречива, но не знал, чем конкретно. Еще раз — спойлер!

Итак, Джоел успешно приводит Элли на операцию по изучению ее иммунитета. И узнает, что Элли в процессе погибнет, зато доктора получат лекарство и спасут весь мир! Штука в том, что доктора решили это сделать молча, без согласия Элли. Ну Джоел, понятно, психанул, перестрелял весь госпиталь и «спас» Элли. А мир не спас. Да еще и не сказал ей ничего. Ну вот, типа, противоречие. Прав или не прав?

И это, сука, действительно бесит. Потому что конфликт тут не настоящий, а из серии «не поговорили». То есть строится на том, что кто-то кому-то чего-то не сказал. То есть, все хорошие, противоречия нет, но все грустные и страдают. И, главное, путь к разрешению кристально ясен. Но нет, будем сопли жевать.

Бесит, если честно, такая драматургия. Поговорите — и проблема решена. Я еще понимаю, для первого акта, туда-сюда, как завязка пойдет. Но заканчивать на этом?

На самом деле, главная причина противоречивости: а не охуели ли вы, господа (за мат извени), заканчивать сезон на полуслове? Что это еще за клифхенгеры? Давайте уж, пожалуйста, разрешайте конфликты, а для второй серии придумывайте новые. А так не пойдет. Да, вот от этого у меня реально бомбит. Что это еще, блять, за эксперименты? Это вам что, Дюна часть первая?

Ну а насчет — правильно ли поступил Джоел? Сложно сказать. Тут условность задника начинает мешать прочувствовать важность решения. Дело в том, что в мире Last of Us они боятся этой мировой эпидемии меньше, чем мы боимся короны. Буквально — ходят без масок, лазят по зараженным канализациям, трогают/дышат грибами. Кто умер — те уже умерли, с новыми зомби (опять же, по тому, что нам показали) особых проблем ни у кого нет. У людей там все довольно неплохо, как бы странно это ни прозвучало. Они научились sustainable жить и даже наладили производства и комунны. Сложно при таких вводных почувствовать, что лекарство кого-либо там бы спасло или вообще что-то существенно поменяло.

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

Читать полностью…

Стой под стрелой

Не понимаю я облака. Не понимаю и все.

Три сеньера (!) ебались с прошлого четверга, чтобы запустить ебучую функцию в ебучем Firebase. Причем не с нуля — у нас уже были функции, нужно было добавить новую. Но нет, не работает и все тут. Раньше работало, и продолжает работать, а точно такая же новая — нет.

В процессе я насмотрелся на всякие бездны админок Гугл клауда, которых, конечно же, несколько версий одновременно, переходы между которыми неочевидны, если вообще существуют. То есть буквально, читаешь ответы на стековерфлоу, а там «попробуйте вот такой URL», пробуешь — и попадаешь в интерфейс, который никогда не видел и как в него вообще попасть — хз.

Насмотрелся на всякие сообщения типа 7423/7424 permissions. Кому, в каком страшном сне, в принципе, хотя бы теоретически, может понадобиться регулировать доступ на таком уровне гранулярности? Для каких задач? Я понимаю, что «серьезных», но блин.

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

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

Ну и надо ли говорить, что документация под все это практически отсутствует. Документация — это стековерфлоу и форумы, а сам гугл в основном показывает «пук-среньк, поставьте наш SDK и ни о чем не спрашивайте». Серьезно, у них больше доков по тому, как SDK поставить, чем по API этого SDK.

И все это ради того, чтобы вызвать три строчки скрипта «в облаке». За потраченное время я бы уже купил три сервера, настроил между ними load balancer и http-сервер с letsencrypt с базой поднял. И все бы работало.

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

Короче, не понимаю, кому эти облака нужны. Нифига не удобно же, и сложно как ракетный двигатель. В чем плюсы?

Читать полностью…

Стой под стрелой

Расходимся еще раз, хз че со строкой делать. В смысле непонятно, как через Reader, который под капотом кодирует в UTF-8, считать n байт, учитывая что единственное что он дает делать — читать UTF-16 character. Можно, конечно, читать по-одному char и считать, сколько места он занимает в UTF-8, но это как-то превышает пределы идиотизма, на которые я готов пойти

Предполагается, что этот самый Reader заведен для удобства, так вот, знаете что? Мне почему-то нифига не удобно. Просто дайте мне байты, неужели я так много прошу...

Читать полностью…

Стой под стрелой

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

Ну и ситуация. Понадобился мне значит бинарный протокол до Кложевского встроенного РЕПЛа. Потому что хотите вы или нет, а бинарные протоколы сильно проще кодить, чем текстовые, а потом они еще и компактнее получаются, короче, одни плюсы.

А Кложевский REPL-сервер дает только текстовый канал. То есть открывает обычный сокет, конечно, но поверх его бинарного InputStream-а создает пять оберток, одна из которых как раз занимается тем, что берет вашу UTF-8 строку и конвертит ее в байты за вас. Удобно? Нет!

Ну то есть удобно, пока ты там какие-нибудь JSON-ы или EDN-ы пересылаешь, но их парсинг дело не одного часа и даже не одного дня усилий, не говоря уже о размере кода. А я там себе MsgPack присмотрел, который сделан вот ровно как я бы сам делал, прям идеальненько, и парсер с сериализатором я вчера прям за час накидал. Но бинарный, сука, надо уметь байтики пересылать.

Ну и вот. Ситуация. Сокет есть, технически по нему ходят байты, но ебучая Джава тебя от этого «абстрагирует» и прячет его в приватные поля. Если вы думаете, что это какая-то метафора, нет, конкретно в случае с Кложей там три обертки — InputStreamReader, LineNumberReader и LineNumberingPushbackReader. Потому что у нас было четыре пакета травы, бла-бла-бла, когда начал оборачивать ридеры в ридеры, сложно остановиться.

И вот я стою перед ситуацией. Либо я расчехляю рефлекшн и --add-opens=java.io, которые жестко завязывают меня на конкретные реализации, конечно, но зато я получаю то что хочу, вещь, которая работает, пусть и с риском когда-нибудь в будущем сломаться или, допустим, не работать на какой-нибудь странной JDK (с чем я, в принципе, готов жить). Или не получаю совсем ничего и иду сосать лапу. И мне как-то кажется, что в ситуации «или что-то, пусть ограничено, но работающее, или тупо ничего, иди нахуй» объективно лучше первое, а не второе, при любых вводных.

Ну и вообще штука в том, что не авторам InputStreamReader-а это за меня решать. Если я хочу до чего-то добраться — дайте мне, блин, добраться. А я уже сам решу, плохо это, хорошо, или . Все равно эти реализации не менялись с Java 1, и уже, наверное, никогда не поменяются, а все сторонние JDK просто копируют реализацию. Я могу оценить этот риск, а автор, который изначально эти поля спрятал — не может.

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

Ну что мне теперь, бинарный протокол в base64 кодировать, что ли? Нет, так мы будущее не построим.

P.S. Немножко забавных деталей: InputStreamReader прячет переданный InputStream в sun.nio.cs.StreamDecoder, и туда я уже не очень хотел лезть, потому что выглядит проприетарно. Но зато он использует объект InputStream еще и как lock для синхронизации (в Java можно любой Object для этого приспособить), ну вот я на него и завязался. Ненадежно? Еще как. Why women live longer than men-вайбы. Ну а что мне остается делать?

Читать полностью…

Стой под стрелой

Ух как бесит мода писать обезличенные предложения. Типа, вместо «Я люблю кофе» — «Люблю кофе». И так же понятно, что «я», вот и сократили. Это от Ильяхова пошло, да? Просто другого такого вредителя не знаю.

И еще немного подбешивает Present Continous вместо будущего времени о чем-то, что еще даже не случилось, а только в планах: «Студенты делают задания и защищают диплом» вместо «Мы выдадим студентам задания, а в конце курса они защитят диплом».

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

> Меня ух как бесит мода писать обезличенные предложения. Типа, вместо «Я люблю кофе» некоторые пишут «Люблю кофе». И так же понятно, что они имели в виду себя, вот и сократили. Эта мода пошла от Ильяхова, да? Я просто другого такого вредителя не знаю.

Мы же не роботы. И даже студенты Бюро не роботы. Не надо отбирать у них личные местоимения.

Читать полностью…

Стой под стрелой

Не знаю кто как, а я последний месяц с кайфом пишу на Питоне ООП. Ну вот это старое-доброе, с классами, наследованием, виртуальными методами.

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

Ну и с ООП надо аккуратно, конечно. Лишнего не делать. Если интерфейс, то с несколькими реализациями. Если паттерн, то по делу, а не «на будущее».

Но если все правильно, есть какой-то кайф, когда ты в родительском классе говоришь: вот тут дети будут переопределять, а в ребенке переопределяешь. Аккуратно как-то, что ли.

Ну и работает.

Читать полностью…

Стой под стрелой

Утром произошел забавный момент лудонарративного диссонанса. Решил я купить себе игрулю Hitman III, значится. Заказал диск на Амацоне, т.к. диски дешевле, чем цифровая копия (что? да!).

Сегодня пришел почтальон. Давай, говорит, паспорт. Я ему аусвайс свой. А он такой — не, настоящий паспорт давай. И реально давай переписывать все данные: номер, дату рождения. Типа, игра 18+, и видимо там пометка была проконтролировать. Еще спросил, что за страна такая. Короче, как будто я Майн Кампф в библиотеке беру.

Выдал в итоге конверт. Открываю, там диск, и на нем большими красными буквами — Enter the world of the ultimate assasin. Добро, так сказать, пожаловать, в мир международного шпионажа и наемных убийц. Но чтобы поиграть, будь добр, предъяви паспорт, убийцы у нас на учете состоят. Ну просто забавный диссонанс.

Кстати, игра еще и требует постоянного онлайна, чтобы все убийцы были под постоянным надзором товарища майора из... Дании? Что тоже как бы не добавляет очков погружению.

Ну и чтобы пост был не зря — а объясните мне, в чем прикол компаниям требовать онлайна в своих играх? Геморроя много, а выигрыш в чем? Сам геймплей полностью оффлайновый, если ты там что-то себе накрутишь, ну, сам дурак, кому какое дело? Я понимаю, что есть какая-то неприятная капиталистическая причина это делать, но мне хочется понять, какая именно.

Читать полностью…
Subscribe to a channel