Горящий фронтендер
102 subscribers
65 photos
3 videos
83 links
Погромист переднего края. Нихуя не работает! Фронтенд проклят! Мы все умрем!

Бложик: https://dskr.dev
Tg: @dskrylnikov
Канал с фоточками: @dskr_pic
Тви: https://twitter.com/dskr_dev
Download Telegram
В канале ещё две части крутого рассказа про время. Но я всё ещё считаю что время слишком сложная и кривая штука, с кучей легаси и её обязательно нужно отрефакторить
Forwarded from Стой под стрелой (Nikita Prokopov)
Работа со временем, часть 3/3

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

Другая штука — путешествие в прошлое. Как вы видели, Unix timestamp начинается с 1970-го, но можно ли продолжить его в прошлое? Немножко можно, насколько позволяет tz database, но там уже начинается неполнота данных о часовых поясах и прочий разброд. Если совсем сильно продолжать, то начинаются вопросы, скажем, переход между Юлианским календарем и Грегорианским был довольно долгим и хаотичным географически и зафиксирован не очень точно.

Сколько дней в феврале? 28-29, да? Часов в сутках? 23-25, как мы определили выше. А вот сколько секунд в часе? 3600, да? Не всегда 🙂 Про високосный год все знают, а как вам високосная секунда?

Но давайте по порядку. В 1972 запустили атомные часы, которые без остановки и прочего булшита отсчитывали по одной секунде каждую секунду 🙂 Их время называется International Atomic Time (TAI) и является, наверное, самой базовой величиной которая у нас есть (да, я говорил, что unix timestamp, но нет). С момента запуска они обогнали UTC на 37 секунд.

Далее есть UT1. Это время, основанное на вращении Земли, в предположении, что каждый новый год наступает ровно в 00:00:00 по UT1. Но! Штука в том, что вращение Земли, во-первых, замедляется, а во-вторых неравномерно и непредсказуемо (!! да, блин! Потому что по ней всякий хлам типа морей, магмы и материков болтается) и в итоге каждый год (по астрономическим наблюдениям вращения Земли) имеет слегка разную продолжительность в секундах.

UTC это компромисс для удобства обычных людей: это тот же TAI (т.е. атомные стабильные секунды), к которому иногда добавляют или отнимают по одной секунде в год, чтобы Новый год наступал как можно ближе к 00:00:00 по UT1 (астономическому).

Пока секунды только добавляли, обычно это делают как 23:59:60 31 декабря или 30 июня. Это происходит нерегулярно, основано на астрономических измерениях и никто заранее не может сказать, когда и сколько их в будущем будет добавлено. Последнюю добавляли в 2016-м.

Как это все переносится на Unix time? А никак 🙂 В Unix time такое понятие не заложено. Если число делится на 3600000, значит это граница часа. Удобно — но также и слегка неправда.

Что же делают компьютеры? Вариантов немного — можно либо повторить 23:59:59 два раза (перевести на секунду назад), либо заморозить часы, либо размазывать эту секунду тонким слоем на целые сутки (вроде Гугл этим хвастался, но не подскажу где).

Именно поэтому Unix time это очень удобная точка отсчета в практическом смысле, но немножко неправда до самого конца. Но на деле — скорее всего, о високосной секунде вам париться не придется. Правда в JVM был какой-то баг на эту тему (скорее всего, что-то про немонотонность часов), и я лично вроде как в 2012-м что-то там из-за этого у нас перезапускал.

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

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

И да, всегда и везде используйте менеджер паролей с уникальными паролями для каждого сервиса
Немного нестандартного использования технологий во фронтенде.
Решили мы интерфейс между node.js и беком поменять. И бек решил что реализовывать кучу кастомных штук с настройками не правильно, и вместо этого в некоторых местах запроса можно передавать вот прям функции.
Функции имеют ограниченный синтаксис с самыми необходимыми функциями: and, or, eq, gt, lt и т.д.
А выглядит это дело как-то так:
Но, писать кучу буковок в json формате немного лениво. И показалось что это можно оптимизировать.
Первое что пришло в голову это использовать jison. Тем более что такой опыт уже был.
jison это bison на js.
А bison это парсер для грамматики. Грамматику можно описать примерно любую.
Но есть один минус, грамматику там нужно описывать на специальном языке. А разбираться в нём мне лениво, да и поддерживать потом это дело сложно. Вот пример калькулятора: https://github.com/zaach/jison/blob/master/examples/calculator.jison
И тут я вспомнил про jsx. В нём можно описать такие штуки достаточно просто. Правда у jsx есть небольшой минус, его нужно транспилировать. И хотя нода и так написана на ts, а значит уже транспилируется, добавлять ещё и jsx туда не хочется.
Плюс будут сложности если захочется реализовать несколько разных языков.
Но у jsx есть клёвая альтернатива. Это HTM. Транспиляция не нужна так как используются шаблонные литералы. А остальной синтаксис очень похож на jsx.
Реализация функции h() функции для пары функций будет выглядеть как-то так.
Конечно надо бы ещё всяких проверок добавить, но это уже рабочая штука
А вот так будет выглядеть использование
Ну и так как htm похож на jsx, можно писать что-то такое
Как не пугая фронтендеров предложить им использовать монады?
Ну, можно просто не говорить что это монада)
В issues даже жалуются что по слову монада, её на гитхабе не найти)
Что такое монада?
В комменатриях спрашивают: «А что такое эти ваши монады?»

Всем конечно же известо что монада - это моноид в категории эндофункторов 🙃

Если совсем просто, монада - это контейнер с парой определённых методов.
Монад есть несколько разных видов. Если мы говорим об адекватном программировании, а не о фп извращениях типо хаскеля или скалы, то чаще всего используют монады Maybe, Either и Task. Называться они могут по другому, например Option, Result и Future.

Maybe либо содержит в себе результат, либо нет. Нужна она чтоб у нас не возникало проблем типо undefined is not a function.

Either либо содержит результат, либо ошибку. Нужна она чтоб не бросать исключения по каждому чиху.

Task нужно для выполнения асинхронных действий. У фронтендеров есть Promise, это плохая породия на Task, но в целом можно и с ним жить.

На самом деле в фп есть не только монады. Кроме них есть функторы и аппликативы. И всё это дело собирается в матрёшку.
Функтор - это контейнер у которого есть метод map. Map это функция которая как-то изменяет значения в контейнере.
Аппликатив - это функтор у которого есть метод ap. Ap позволяет вставить функцию внутрь контейнера, чтоб потом её можно было применить к нескольким контейнерам(в реальной жизни это примерно никогда не нужно, если вы конечно не захотите написать свою реализацию монад)
Монада - это аппликатив у которого есть метод chain. Chain позволяет взять значения из двух контейнеров, что-то с ними сделать и получить новый контейнер.

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

Если вдруг всё равно нияего не понятно, есть клёвая статья с красивыми картинками: Функторы, аппликативные функторы и монады в картинках

Если хочется чуть глубже погрузится в фп в контексте фронтенда есть клёвая книга: Mostly adequate guide to FP (in javascript)
И перевод её на русский язык: Mostly adequate guide to FP (in javascript, translated to russian)

Если не понятно, а как в реальности то эти ваши монады могут помочь фронтендеру есть крутой доклад про обработку ошибок: Дмитрий Махнёв Артём Кобзарь — (не|ну)жная монада Either на практике и в теории

И эти же авторы написали достаточно удобную реализацию монад Either и Maybe для js: @sweet-monads

А если вы вдруг совсем упоролись и хотите писать на TS как на хаскеле, то есть прекрасная библиотека: fp-ts
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Сегодняшний день я потратил на сражение с 👩‍💻 S3.

S3 это протокол и амазоновский сервис для хранения файлов. Кроме амазона его юзают примерно все.

Вот и у нас тоже стоит селфхостед что-то(я даже не знаю что) умеющее в s3. Один из продуктов его использует и там всё ок. Нужно было добавить всё то-же самое во второй продукт. Казалось бы всё просто, скопировал код прослойки, добавил нужные вызовы и готово. Но тут начались странности. Бакет создаётся нормально, а значит с адресом/аутентификацией проблем нет. Но записать туда файл не выходит. При этом ошибка максимально странная. getaddrinfo ENOTFOUND. Какого-то чёрта амазон решил что будёт клёвой идеей в качестве эндпоинта юзать имя_бакета.хост/
И конечно же это не работает если у тебя селфхостед s3.
Но как же этот код работал в другом продукте? По случайности там в имени бакета используется нижнее подчёркивание.

Ебучий амазон 🖕 Ебучие неочевидные дефолты 🤮 Никогда так не делайте.

Проблема решилась добавлением в конфиг флага forcePathStyle.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🔥1
Вдруг кому делать нечего. Тут начался декабрь, а значит и новый #adventofcode

Первый день совсем простой. Особенно если писать на чём-то высокоуровневом)

https://adventofcode.com/2022
🔥2
Live stream finished (1 hour)
Пробовал сегодня постримить решение AoC. В целом схема рабочая, но меня подвел obs, в какой-то момент завис захват экрана(
Если будет не лень, завтра повторю попытку.
Запись доступна на ютубе, но учитывая что большую часть времени там зависший экран, смотреть не рекомендую)
https://youtu.be/qNLEyPCLHP4
Продолжил стримить AoC. В этот раз задача была простой, я не тупил и обс не тормозил. Поэтому справился меньше чем за 30 минут.
Единственная сложность задачи это распарсить входные данные. Ну и да, GitHub Copilot здорово помогает)

https://youtu.be/-4c2EdhvnyM
3