Стендап Сьогодні

Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті

Підписатись на RSS
📢 Канал в Telegram @stendap_sogodni
🦣 @stendap_sogodni@shevtsov.me в Федиверсі

04.07.2025

Elixir - єдина мова. від якої я відскочив

Пару днів тому згадав про мову Elixir - перший раз за майже 3 роки існування каналу. Певно, це вже достатньо говорить про те, наскільки вона мені не зайшла, хоча я професійно писав на Elixir принаймні кілька місяців. Було це десь у 2017-2019. Тож може за цей час багато змінилося. Он, виявляється, по версії Stack Overflow це друга за привабливістю мова. Але то таке — хочуть, але не вчать чомусь?

Elixir - це чисто функціональна мова на основі віртуальної машини Erlang. ЇЇ створили як швидкісну мову для проєктів на Ruby… як я з нею й познайомився. Синтаксис Elixir багато в чому нагадує Ruby, та й підходи та ідіоми теж. Наприклад, тут є інтерактивна оболонка, гнучкість DSL, символи та блоки.

З усім тим, Elixir працює зовсім не так, як Ruby. Наприклад, в головному фреймворку Phoenix операції з базою відбуваються через функціональну структуру changeset. Бо в функціональній мові дані течуть за програмою, а не зберігаються у змінних. Це не те щоб погано, але для рубістів тут криється багато сюрпризів.

Зокрема, мені було незручно через Erlang. Erlang - це цілий світ, з власною віртуальною машиною, дивною моделлю рівночасності, та незнайомими підходами в цілому. Причому принаймні у 2019 ці підходи лізли з кожної помилки в Elixir, тож їх не можна було ігнорувати. (Я все ще хотів би вивчити колись Erlang, але навіщо, поки не знайшов.)

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

Отже, як я пішов з того проєкту, більше ніколи за Elixir братися не хотілось. Залишилося пару PRів в проєкт до якого, певно, так само втратили інтерес.

А що, може є тут діючи еліксирісти? Як воно вам? Є прогрес в мови за останні 5 років?


03.07.2025

Як зробити власний, незалежний блог

Поступив запит: “як та на чому зробити власний блог”. В мене такий вже… понад двадцять років? Тож можу поділитися. Інструкція задумана для (не-веб) програмістів, тож передбачає певний компʼютерний хист.

Домен. Власність в інтернеті починається з домену. Бо домен — це те, як тебе знаходять люди. Поки в тебе є домен — все інше можна підлаштувати. (Володіти доменом, звісно, не вийде — ти тільки його орендуєш. Але це найбільш стійка власність в усьому Інтернеті.) Домен реєструється в одного з реєстраторів — наразі я рекомендую Namecheap. Реєстратор — це не навічно, потім можна перенести за потребою.

(Та, домен коштує грошей — зазвичай близько $10 на рік. Але сьогодні дізнався, що у нас в Україні є безплатна зона pp.ua. Щось знаєте про неї?)

Чисто технічно, домен можна привʼязати до будь-якого конструктора сайтів — хай то WordPress чи SquareSpace, чи Wix - та вже мати власний сайт. А потім — спокійно переїхати на інше рішення. Але ж ми тут говоримо про “власний” блог, то нумо рухатись далі.

Зміст сайту. Хоч ми проживаємо час вебзастосунків, але стара добра модель “сайт — це колекція файлів HTML” теж жива-здорова. Це називається статичний сайт. Можна взяти та написати цей HTML вручну (або ще й зберегти з Ворду!) Але типове сучасне рішення для блогів — це генератор статичних сайтів.

Генератор статичних сайтів — це програма, яка бере теку із текстовими постами та робить з неї сайт — з оздобленням, навігацією, категоріями тощо. Я рекомендую Hugo. Вже після першого налаштування в тебе буде можливість писати у свій блог статті та бачити їх на сайті. А головне — експериментувати з оформленням, як заманеться — бо саме для того й роблять свій блог.

Розміщення. Нарешті, щоб його побачили люди, сайт треба розмістити в інтернеті. (Можна хоч вдома — але це не для початківців.) Хостинг — річ утилітарна, тому не варто довго на ній зациклюватися. Його також легко замінити пізніше. Моїм улюбленим рішенням залишається Firebase, який ще багато чого вміє, але нам потрібний мінімум. Головне, що з Hugo розгорнути в Firebase можна однією командою: hugo && firebase deploy. Але спочатку не забудь привʼязати до Firebase свій домен.

Якщо робити все за інструкціями 1 2 та не хапатися відразу за нюанси, то зробити власний, на 100% особливий блог цілком можливо за вихідний. А розваг потім — на роки вперед. 😉


02.07.2025

Mise = ASDF + direnv + make

Коли я писав, що ASDF - не наймодніша штука, то мав на увазі насамперед Mise. Вона зібрала в себе й керування версіями, й встановлення змінних оточення, й словничок скриптів — тобто повсякденні потреби кожного проєкту. Я поки не перейшов на Mise повністю, бо в мене вже є готові рішення та купа багажу — але якщо починати з нуля, то, певно, має сенс.

Порівняно з ASDF, тут є одна величезна відмінність (та багато дрібних.) Mise не має теки з прокладками! Натомість вона збирає $PATH зі шляхів до кожної обраної версії. Такий підхід багато кому знайомий, до менеджерів версій я саме так і робив би. Тобто, якщо ми обрали Ruby 3.2.2, то в шляху буде ~/.mise/ruby-3.2.2/bin.

Завдяки такому підходу запуск інструменту не потребує звернення до менеджера для визначення потрібної версії (як це робить ASDF.) Вся робота менеджера відбувається під час переходу в нову директорію (а точніше, під час зміни обраних версій.)

Автор Mise каже, що це ще й швидше за ASDF, але я не дуже помічаю різницю. Але в мене є інша проблема з ASDF - коли якийсь інструмент встановлений бодай в одній версії мови, в нього зʼявляється прокладка. Відтоді запуск цього інструменту завжди йде через ASDF. Не дуже гарна архітектура.

Щодо заміни для direnv та make поки нічого не можу сказати, бо не користувався. Взагалі в команді такі зміни важко впроваджувати. Гарно що хоч що Mise, що ASDF можуть читати “ідіоматичні” файли версій, як, наприклад, .ruby-version, тож не потрібно всіх відразу примушувати до зміни менеджеру.


01.07.2025

ASDF - універсальний менеджер версій

Раз вже тема піднята, розповім про ASDF. Я з цією утилітою вже скоро років 10, та вона вже навіть не наймодніше, що є, але то не привід нею не користуватися.

Якщо ти працюєш з Ruby, Node.js, чи Python, то точно знаєш про rbenv, nvm та pyenv. Всі ці утиліти дозволяють мати кілька версій мови та перемикатися на потрібну для кожного проєкту. Бо в кожній версії є маленькі та великі відмінності та нам важливо зафіксувати, яка версія використовується в проєкті — та переконатися, що як на сервері, так і в кожного розробника встановлена саме вона. В професійній розробці ніяк не вистачає apt-get install ruby.

…А якщо ти працюєш відразу з кількома мовами, то підтримувати цілий зоопарк менеджерів версій стає витратно. Для того й існує ASDF - вона заміняє відразу всі вище згадані утиліти, та підтримує ще багато інших мов та пакетів. Завдяки підтримці плагінів ASDF покриває сотні інструментів. От навіть XCode. Також постійно використовую для Go та Terraform. А почалося використання ASDF в мене, здається, з Elixir, для якого аналогу rbenv просто не було.

Працює ASDF дуже просто — він генерує теку shims зі скриптами-“прокладками”; наприклад, там є скрипт ruby, який прочитає з оточення поточну версію Ruby та запустить відповідну програму. Прокладки створюються не тільки для програм з самого пакету мови (gem, irb тощо), але й для тих, які належать встановленим бібліотекам (terminal-notifier).

Причому якщо у мови є власний формат файлу версії, то ASDF здатний його читати. Наприклад, .nvmrc. Тому на нього можна переїхати тихенько, не треба вмовляти всю команду. Хоча… згодом можна й вмовити та перейти на спеціальний для ASDF .tool-versions.

В мене ASDF - один з незамінних інструментів, та й вам раджу спробувати.


30.06.2025

Noasdf - скрипт для обходу asdf

Оце написав вчора та думаю: ASDF це дивовижний засіб для розробника, якому треба мати кілька версій оточення… особливо коли в тебе технологій цілий зоопарк. (Ну або mise, якщо ти на часі.) (Я трохи здивований, що ніколи про нього не писав окремо.)

Але користувачу він життя ускладнює. Бо з ASDF в тебе кожної мови півдесятка версій. На кожну версію — власні пакети та виконувані файли. Оновлення версій зі збереженням пакетів немає, є тільки встановлення нової версії.

Отже, якщо хочеш встановити собі якусь утиліту — наприклад, terminal-notifier - через gem або npm тощо — та так, щоб вона була доступна завжди — то ASDF в цьому тільки перешкоджає. В нього за призначенням ця утиліта буде доступною тільки поки ти не обереш локально іншу версію Ruby чи JS. Навіть якщо встановити її в “глобальну” версію, навіть якщо в системну — не допоможе.

А раз так, знайшов вихід, який поки працює: вимикати ASDF. Його механізм дії — додати свій шлях до $PATH. Підчистити шлях — та ASDF як не було:

noasdf() {
  shims_path="$HOME/.asdf/shims"
  clean_path=$(echo "$PATH" | tr ':' '\n' | grep -v "^$shims_path\$" | paste -sd ':' -)
  PATH="$clean_path" "$@"
}
# наприклад:
noasdf npx perplexport

Таким чином ми отримуємо доступ до системної версії мови (тобто такої, що знайдеться в $PATH.) Щоправда, кожного разу, щоб запускати утиліти доведеться писати noasdf, але в теорії це можна й спростити (бо нам лише потрібний чистий $PATH, а його можна підсунути різними шляхами.)


29.06.2025

Perplexport

Як і збирався: yarn global add perplexport - утиліта для експорту діалогів з Perplexity. Я поки боюся, що з браузером будуть якісь складнощі, але подивимось. Є ще варіант з Puppeteer переїхати на Playwright.

(Взагалі я дуже не люблю утиліти, написані на JS за те, як вони встановлюються. А коли ще то цього домішується ASDF - то й зовсім. Втім, маємо те що маємо.)

В мене потреба повністю закрита: можу тепер додавати кожен діалог до Obsidian. Разом із Markdown зберігаю поруч вихідний JSON, про всяк випадок; до того ж JSON містить більше інформації, хоч вона поки здається мені зайвою (наприклад, перелік виконаних запитів.)

Тепер я вже зберігаю і світлини з результатів (до речі, вони не є копіями, а посилаються на першоджерело), і відео (здебільшого це посилання на YouTube.)

Для порівняння стандартного експорту та мого. Там посилання на джерела вказуються просто як URL. А я побачив, що в даних для кожного джерела є й назва, й зазвичай фрагмент тексту — та вказую все це. Джерела — це цінність сама собою, це фактично закладки на тему.

Звісно, в самому Perplexity є ціла “бібліотека” діалогів, але, по-перше, їх там значно важче знайти, а головне, в Obsidian їх можна відредагувати, бо зазвичай з діалогу тільки мала частина дійсно відповідає на питання.

Все це дійсно наближує мене до браузера, який я хочу… хіба що замість сторінок тут пошук з перетравленням ШІ.


28.06.2025

Експорт з Perplexity - простіше, надійніше, краще

Минула версія скрипту для експорту з Perplexity трохи завʼязла через обмеження частоти запитів. До того ж експортований Markdown був досить неповноцінним та не містив, наприклад, знайдених зображень. А оце сьогодні вдалося зробити з усіх боків краще!

Сиджу та думаю: ну якщо я вже відкрив сторінку з діалогом, то навіщо мені ще експортувати — в такий “джерельний” формат, як Markdown - коли в теорії можна просто забрати зміст зі сторінки?

Подивився журнал запитів (вкладка “Мережа” в інструментах розробника корисна, як завжди.) Та дійсно — бачу смачний запит до API, який віддає зміст в усіх подробицях (/rest/thread, якщо будеш шукати для себе.) Там не тільки Markdown діалогу, а й перелік посилань, зображень, навіть розʼяснення плану пошуку. Абсолютно все.

Але найкраще навіть не це. У таких запитів майже немає обмежень! Бо це звичайний перегляд сторінки. Коли я зробив паузу між сторінками у 2 секунди, то успішно забрав всі свої 500 діалогів.

Я вирішив не робити ті запити до API напряму, а все ж взаємодіяти зі сторінками так, як це робить звичайний користувач. В Puppeteer дуже легко забирати будь-які запити, що відбуваються: достатньо зробити page.on('response'). А там вже фільтрувати за URL та зберігати в файли.

Єдине (хороше!) ускладнення — дані я отримую у JSON. Це чудово, бо можна так їх і зберігати та сподіватися, що це вичерпний експорт. Але документ Markdown з них ще потрібно збудувати. На щастя, кожна відповідь генерується вже в Markdown, тобто їх залишається просто склеїти. Найбільше проблем створили посилання на джерела: вони помічені просто як [1], а мені довелося будувати список посилань з внутрішніми якорями ^0-1, а потім на них посилатися: [[#^0-1]]. Ну то дрібниці.

Чекайте на випуск через кілька днів, я думаю, ці зміни піднесуть утиліту з іграшки до чогось дійсно корисного.


27.06.2025

Цінність коду відʼємна

LLM вражають своєю здатністю генерувати код. Багато коду. Та набагато швидше, ніж його може хоч надрукувати людина. Це дійсно приголомшує, особливо тому, що цей код не такий вже й поганий.

Тому важливо нагадати, що код не тільки не має цінності сам собою, а й створює майбутні витрати. Цінність може мати функціонал програми — це те, за що платитимуть клієнти, це економічний продукт. Але кожний рядок коду, який ми вклали в реалізацію цього функціоналу — це витрата.

Я гадаю, людям складно думати про код, бо це зовсім новий ресурс. З фізичними ресурсами практично завжди зрозуміло, що більше витрат — не краще. (Хіба якщо ви отримуєте відкати за цеглу. Що можна порівняти з оплатою за рядки коду.) Але код — це інформація, вона нічого не важить. Коли пишуть для людей, то всі знають, що треба писати стисло. Але код не читають, як книжку. До того ж як взагалі виміряти видачу програміста, окрім як кодом? “Реалізований функціонал” це щось зовсім уявне.

Тому й маємо абстракцію: кладемо в програміста гроші, отримуємо з іншого боку код. Але це нісенітниця: з програміста отримують робочу програму, а код — це тільки аспект реалізації.

Та це й навіть не головна складність. Також більша частина роботи програміста складається з редагування коду, що теж ні в яку аналогію не вкладається. А чим більше коду, тим складніше з ним працювати. Та це витрати категорично більші, ніж на первісне написання коду! Тому я завжди хочу., щоб коду було якнайменше… звісно, його завжди доводиться писати, але то так саме, як завжди доводиться витрачати клей чи цвяхи. А ще згадайте — в рідкісних випадках, коли видаляють великий шматок коду, вся команда радіє.

…Я, здається, придумав пояснення для тих, хто не програмує. Код — це уречевлена складність. Оце нехай думають, чи потрібно її більше.


26.06.2025

Федиверс та Mastodon - що то є

Сьогодні у Федиверсі виникла дискусія — що таке Pleroma та чим вона відрізняється від Mastodon. Оце захотілося ширше про все це розповісти, бо я для себе копався, коли робив адаптер для Mastodon до OmniWOPE.

Федиверс — це децентралізована соціальна мережа. Соціальна — значить, в ній є облікові записи. На них можна підписуватися, стежити за ними, надсилати ним повідомлення. Децентралізована — значить, містить не один сервер, а всі сервери в інтернеті, що підтримують протокол ActivityPub (та інші.) З різним керуванням, різним ПЗ, різним всім.

Якщо це звучить надто абстрактно, то так воно і є. Бо хоча ActivityPub чітко задає логістику повідомлень, але їхній зміст залишає відносно вільним, щоб охопити будь-який зміст. Тому Федиверс містить не тільки умовний Твітер, але й базу туристичних маршрутів Wanderer, відеохостинг PeerTube, аудіохостинг Funkwhale, також інтеграції від WordPress або Discourse та, звісно, Mastodon.

(Та все це не конкретні сервіси, а програмне забезпечення, яке можна розгорнути для себе. Або доєднатись до одного з безлічі серверів, що вже існують.)

Але окрім серверів, є ще клієнти — хай то буде вебзастосунок чи повноцінний, але клієнт буде привʼязаний до якогось конкретного сервера, бо клієнти не використовують ActivityPub для спілкування з сервером. Та тут, я гадаю, набуває вагомості Mastodon.

Сам собою Mastodon - дуже успішний клон Твітеру для Федиверсу. Але ще важливо, що API для клієнтів Mastodon став де-факто стандартом, тому такі сервери, як Pleroma чи GoToSocial, його реалізують. А клієнти, як Mona, Tusky, чи Ivory, таким чином підтримують не тільки Mastodon, але й ці сервери теж. (Не завжди ідеально.)

От, виходить, коли кажуть Федиверс — то йдеться про загальну світову децентралізовану мережу. А коли Мастодон — то про її потужний твітеро-форматний сегмент, який має спільні клієнти та загальні домовленості про зміст повідомлень. Але не тільки сам Мастодон, присутня певна генералізація. 🦣


25.06.2025

Клавіатура — це питання смаку

За ті пару років, які минули з попереднього поста про клавіатуру, знову багато змінилося. Зараз в мене Lofree Flow84. Але головне — я, нарешті, зрозумів, що клавіатура — це питання смаку, та щоб не марнувати гроші у гонитві за новим та модним, варто зрозуміти, який смак у тебе. Ось що я поки зрозумів про себе:

🫓 Я люблю пласкі клавіатури. А не товстенні друкарські машинки на кшталт Keychron Q1. Зокрема, коли ти час від часу працюєш на ноутбуці, контраст допікає. Але також мені не подобається вигинати кисть догори, навіть із підставкою під долоні, яка з Q1 стає майже обовʼязковою.

📏 Я люблю розмір 84. Це теж наближено до клавіатури ноутбука. Більше клавіш не потрібно, та вони тільки заважають на столі. Проте я не хочу відмовлятися від функціонального ряду або повнорозмірних стрілочок.

🚝 Мені потрібний металевий фрезерований корпус. Бо клавіатура повинна бути важкою та точно не гнутися. (Зокрема, в мене є Keychron K3 зі штампованим корпусом, яка трошки, але помітно зігнулася, та хитається з кожним натиском.)

🪨 Мені потрібні клавіші з PBT. Головний аспект відчуття від клавіатури — це які на дотик клавіші. Поки я знаю, що ABS - це не моє, а PBT - гладенький, щільний, надійний. Хотілося б колись випробувати екзотичні керамічні та деревʼяні клавіші.

🍞 Мене влаштують будь-які тактильні “тихі” перемикачі. Взагалі міняти перемикачі — це розвага для тих, кому в дитинстві не вистачило незручних крихких конструкторів. Та єдиний раз, коли я побачив фундаментальну різницю від перемикачів, це коли замовив приглушені Gazzew Boba U4 та страждав від їхньої “в’язкості”.

🌚 Мені не потрібна підсвітка. Ну не дивлюся я на клавіатуру взагалі, вона тільки відвертає від екрана. До речі, це єдиний недолік Flow84 - смужка світла на передній грані, яку неможливо вимкнути. На щастя, натомість її можна заклеїти чорною ізострічкою (незамінний засіб!)

🔌 Мене не важлива бездротовість. Клавіатура майже не рухається, тож наявність дроту практично не заважає (на відміну від миші). До того ж кабель залишається найшвидшим та найнадійнішим способом підключення.

⚙️ Мені не важливе програмне забезпечення. Ну… мінімально. Бо різні клавіатури мають сюрпризи, коли доходить до поведінки функціональних клавіш тощо. Майже для всього іншого є Karabiner Elements.

Ось так, якщо бути впевненим в таких рішеннях, відразу зрозуміло, сподобається нова клавіатура чи ні. Звісно, в кожного вони будуть свої.