Мой уголок – Telegram
Мой уголок
273 subscribers
2 photos
28 links
Щит-репосты и посты о всяких технологиях и не только. @bondiano
Download Telegram
Channel created
Недавно столкнулся с проблемой, что требуется https для локальной разработки. Решение нашел довольно быстро: Ngrok. Это платформа с удобной CLI утилитой (написана, кстати, на node.js), которая позволяет организовать удалённый доступ на веб-сервер, ну или любой другой сервер, запущенный на ПК. ПК при этом может не иметь статического IP адреса или быть за NAT'ом.
Так что если вам нужно показать что-то локально поднятое, а ещё желательно, чтобы SSL или TLS сверху накинули эта тулза отлично подойдет.
https://ngrok.com/
#w_corner_tools
Чисто лол-кек, В Хроме, 6**9 === Math.pow(6, 9) //false.
Очередная крутая фича браузера и зачем нам эти браузерные войны в статье Саши Майорова.
https://medium.com/@frontman/funes-8-math-pow-не-равно-972955382594
З.Ы. в комментах-таки говорят, что в Chrome Nightly уже поправили
Деструктуризация динамических полей
Совсем недавно задумался над тем, как получать значение поля, которое было назначенно динамически.

const myActionName = 'ACTION'
const actionByActionName = { [myActionName]: action }

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

const { [myActionName]: actionName } = actionByActionName
child_process

В ноде есть 4 способа запуска дочернего процесса:
child_process

.spawn - начинает асинхронно отдтавать данные сразу, как запустится процесс. Его выгодно использовать при работе с большими объемами данных, например, с огромными файлами или выводом результатов утилит вроде curl. Данные получаем при помощи event-listener'а(.on('data', () => {...})).

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

.execFile - как exec, но напрямую запускает исполняемый файл, без оболочки.

.fork - как spawn, но позволяет обмениваться сообщениями с дочерними процессами через функции send/on.
#w_corner_nodejs
keyof в поисках типа

Жили были функции без типов. Среди них были такие,
как prop, возвращающие поля из объекта.


const prop = (obj, key) => obj[key]

Когда наступило время раздора и хаоса и пришли типы, неопытные программисты часто ошибались в том, как организовать верный вывод типов таких функций, но для любого поля результат был any. (и жили они без noImplicitAny)


const prop = (obj: {}, key: any) => obj[key]
const example = { meow: 'meow' }
prop(example, 'meow') // type: any


"Как так!", — восклицали они, — "Ведь мы видели, что по ключам всегда получаем тип!"

И были правы. В TypeScript существует поиск типов (Lookup Types) , который и позволяет получить связанный с ключем тип.

Тогда к ним пришел важный тип и дал новое магическое слово - keyof.

Оно давало особую способность проникать в публичные имена ключей типов и создавать литеральный объединенный тип (Union).*


const example = { meow: 'meow', murr: 'murr' }
type CatSays = keyof typeof example // "meow" | "murr"


Благодоря знанию о keyof и Lookup Types они быстро сообразили, как затипизировать их функцию prop:


const prop<T, K extends keyof T>(obj: T, key: K) => obj[key]

Теперь они смогут спокойно жить и припевать в типобезопасном мире, типизируя любые функции, которые как-то получают только нужные поля объекта!


* с помощью keyof можно получить все публичные не статические ключи пренадлежащие именно типу, потому в примере мы вынужденны получать запросом типа typeof.
#w_corner_ts
TSLint to ESLint

TSLint обещает скоро уже стать deprecated. И уже пора бы переносить все проекты с ним на новые рельсы. Очевидно, что единсвенный выбор сейчас - ESLint. Ну и куда же в современном проекте без Prettier'а. Пройдемся немного по шагам, которые сделал я для подобного переноса.

1. Во первых, не хотелось переформатировать проект, потому я сразу пошел искать тулзу, которая мне переконвертирует все мои правила из TSLint, и супер, что такая уже есть - tslint-to-eslint-config.

Запускаем npx tslint-to-eslint-config

2. Тулза оказалась достаточно не плохой. Но все нужные пакеты для использования ESLint она сама не поставила :(. Поставим сами, за одно добавим Prettier. (хотя и создатель сказал не использовать, но я продлжаю выбирать yarn в качестве своего менеджера зависимостей, как минимум тк я подсел на workspaces)

yarn add eslint eslint-config-prettier eslint-plugin-prettier prettier @typenoscript-eslint/parser @typenoscript-eslint/eslint-plugin @typenoscript-eslint/eslint-plugin-tslint -D


3. Перименуем eslintrc.js в .eslintrc.js, либо придётся добавить флаг в скрипте -c eslintrc.js.

4. Обновим поле noscripts в package.json.
"lint": "eslint --ignore-path .gitignore --ext .js,.jsx,.ts,.tsx"

5. Добавим Prettier. Сперва в массив plugins - plugins: [..., 'prettier'], затем в rules - rules: { 'prettier/prettier': 'error', ... }

6. Почему-то tslint-to-eslint-config генерирует несколько не сущесвующих правил в плагине @typenoscript-eslint/eslint-plugin, тч после первого запуска lint'a вам придется их подтереть или поискать альтернативы.

6. PROFIT! Можно удалять tslint и избавляться от правил из @typenoscript-eslint/tslint плагина.

Некоторые мои проекты хранятся в монорепо, тч для нормальной работы ESLint потребовалась небольшая докрутка: parserOptions.project в .eslintrc.js поддерживает также массив, тч потребовалось внести каждое приложение, содержащее tsconfig.json отдельно.

Также vscode сразу не хотел обрабатывать нужные конфиги, не беда, в issue к плагину vscode-eslint предложили рабочее решение.

P.S. Все же с tslint-to-eslint-config некоторые правила останутся не перенесеными, тч смотрим также созланный тулзой файл tslint-to-eslint-config.log.
#w_corner_ts
Второй подход к снаряду поиска типов

Сколько же решений по типизации экшенов выдает Stackoverflow, вплоть до пакетов с тремя звездочками на Github и каждый способ не лишен изъянов.
Возьмем например довольно очевидный способ создания экшена "в лоб":

interface Action<T, P> {
readonly type: T;
readonly payload?: P;
}

const createAction = <T extends string, P>(type: T) => (payload: P): Action<T, P> => {
return { type, payload };
}

В таком случае от нас TS будет требовать пробрасывать вторым аргументом в дженерик payload, что нам не всегда нужно (тк нельзя в дженерик с двумя аргументами передавать только один, ну и если попробуем от этого избавиться, то все равно в конце концов мы теряем тип от type).
И по общей договоренности с командой мы решили, что тип поля type обязательно должен быть строкой.

И так, приступим исправлять типизацию.

Что же для нас такое этот createAction в итоге.
Это функция, принимающая type и payload и возвращающая объект с этими двумя полями, а главное сохраняющая типы.

const createAction = (type) => (payload) => ({
type,
payload,
})

И первый тип, с которым надо нам надо разобраться - это тип Action, содержащий payload, type и более базовый тип - ReduxAction (для него достаточно поля type)

interface ReduxAction<T extends string> {
type: T
}

export interface Action<Type extends string, Payload = void> extends ReduxAction<Type> {
payload?: Payload
}

Тут все довольно просто. Обернем в это createAction.

const createAction = <T extends string, P>(type: T) => (payload?: P): Action<T, P> => ({
type,
payload,
})

Чтож, мы пришли примерно к тому же, что и было в примере с SO. Только payload вне зависимости от экшена не обязательный, а типы этого поля так и не выводятся. Добавим магии lookup types и посмотрим, что у нас получится.

export const createAction = <A extends Action<A['type'], A['payload']>>(type: A['type']) => (payload: A['payload']) => ({
type,
payload,
})

Теперь у нас выводится типы тайпсрипта по типу экшена. Так мы не можем доказать тайпчекеру, что тип у A['type'] - строка, и это не сработает (пример). Впрочем, мы и не пытались.
Чтобы это сделать мы воспользуемся таким вот хитрым хелпером, который позволит доказать, что тип действительно строка (если у вас есть идеи как это сделать проще - велком в личку).

type StingTypeField = {
type: string
}

type LookupStringTypeField<T, K> = K extends keyof T ? (T extends StingTypeField ? T[K] : never) : never

В LookupStringTypeField мы говорим, что поле в объекте точно есть поле K и оно точно строка, а иначе и не может быть (never).

Итоговый createAction:

const createAction = <A extends Action<LookupStringTypeField<A, 'type'>, A['payload']>>(type: A['type']) => (payload: A['payload']) => ({
type,
payload,
})

И конечно ссылка с примером.

P.S. В примерах не исключены ошибки ☺️

Всех с наступающим!🎄
#w_corner_ts
Небольшой пост по безопасности на фронтенде, куда вообще смотреть? Заметил, что мало кто в этой теме разбирается даже на базовом уровне, а тема важная.
Основные вопросы:
Виды атак, какой вектор, какая цель?
XSS, CSRF, clickjacking.
Как защититься?
CORS + SOP, CSP, Cookie: secure, httpOnly, SameSite
https://application.security/free-application-security-training - в интерактивном режиме показывается как можно произвести атаку и как от нее защититься
https://developer.mozilla.org/ru/docs/Web/HTTP/CORS
https://developer.mozilla.org/ru/docs/Web/HTTP/CSP
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
https://developer.mozilla.org/ru/docs/Web/HTTP/Cookies#secure_(%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D1%8B%D0%B5)_%D0%B8_httponly_cookies
https://habr.com/ru/post/340146/ - про то, как работает JWT
#w_corner_secure
MSW
Часто вам приходилось разрабатывать интерфейс без готовой ручки на бэкенде? Все эти временные данные на уровне стора или Promise.resolve с данными на уровне сервисов/sdk и прочие подходы, обеспечивающие нам одни и теже данные. А писать e2e тесты, когда чтобы замокать результат запросов всегда приходилось придумывать свои велосипеды (да-да, е2е с фейковыми данными запросами ужас и моветон - мы всегда поднимаем весь стек и ждём, что нигде ничего не отвалится и нашей машинке хватит сил).
Хватит. Почти всегда для того, чтобы подсунуть фэйковые данные на уровне сети я выбирал nock, но время идёт, индустрия движется, а подход к моку сервера в тестах остаётся прежним. Только не с Mock Service Worker и вот вам несколько причин перейти на него:
1. Простая установка
2. Возможность запускать одни и те же обработчики и для серверных (например,в случае с SSR) и для клиентских тестов из коробки
3. Возможность делать более умные обработчики на этапе жизни «без нужной бэкендовой ручки», а затем переиспользовать их в тестах
4. Поддержка rest и grqphql
5. Максимально прозрачное поведение и простота отладки
6. Ваши обработчики похожи на реальные express мидлвары
Ставим пакет, запускаем npx msw init public/ --save и вперед. Не забываем читать доку, и экспериментировать, думаю, обязательно найдете больше юзкейсов для себя.
#w_corner_testing
Да будет Typenoscript
С этого поста хочу начать последовательный цикл дипдайва в тайпскрипт, в самом широком смысле: от причин использования, простейших типов и их юзкейсов, до устройства системы типов, транспилятора, точек его расширения и всего вокруг этого чудесного инструмента.
Начнем с самого начала: с базовых типов, из которых выводится все остальное.
То, что TypeScript является типизированной надстройкой над JavaScript, от которой после компиляции не остаётся и следа, означает, что первый перенял от второго всю его идеологию. Одним из таких моментов является разделение типов данных на типы значения (примитивные) и ссылочные типы.
Корнем всей иерархии типов можно считать unknown, который является типобезопасным аналогом any. Все типы совместимы с типом unknown, в, то время как сам тип unknown совместим только с самим собой и типом any.
Произвольный тип any — с него для многих и начнется знакомство с системой типов TypeScript.
Далее идут простые примитивные типы, имеющие свои аналоги в JavaScript: number, string, boolean, bigint, symbol. Важно понимать, что типы, идентификаторы которых начинаются с прописной буквы представляют объектные типы (ссылочные типы) описывающие одноимённые типы из JavaScript (Number, String, Boolean и т.д.). В Typenoscript их можно расширить (через extends) и реализовать (через implements).
В отдельную категорию можно вынести примитивные типы null, undefined, void, never, считая их в некотором роде «типами отсутствия».
Enum - перечисление также считается примитивным типом.
Для каждого из этих типов есть литеральный подтип, которые, как можно понять из названия, представляют литералы обычных примитивных типов.
#w_corner_ts
React Testing Library и Enzyme
Все больше и больше проектов уходят с Enzyme и переходят на RTL. Про это сейчас пишут статьи, делают доклады и даже оффициальная дока Recat рекомендует React Testing Library. Чем же так не угодил Enzyme и почему от него стоит отказаться.
1. Он завязан на кишки React, а значит очередное обновление ломает обратную совместимость и требует обновление Enzyme (а также вероятно написанных тестов)
2. Enzyme родился в Airbnb, но сейчас фактически поддерживается одним человеком.
3. Enzyme периодически вынуждает тестировать реализацию как «белый ящик», что также делает тесты более хрупкими.
Как начать писать тесты с RTL? Лично я рекомендую для старта почитать документацию, посмотреть мой доклад и этот плейлист. Для более заинтересованных в тестах также не могу оставить без внимания интенсив Hexlet по тестированию фронтенда.
#w_corner_testing
Заметки

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

За последние лет 8 я попробовал минимум 30 приложений для ведения заметок, дел, чеклистов, WTR, финансов и прочих потоков информации, которые хочу структурировать. 
А хотелось структурировать все. GTD для всех дел. Цеттелькастен для всех заметок. Выжать максимум из приложений для финансов. Еженедельная очистка want to read инбокса. 
Косу нужно было идеально заточить, чтобы косить. 
В результате вместо того, чтобы выполнять задуманную работу, куча времени уходило на поиск и освоение очередного разухабистого инструмента для GTD, обвес и настройка плагинами Obsidian’а, докрутка базы знаний в Notion. В конце концов полное отчаяние от того, что в итоге снова получилось слишком сложно. 
Тогда я решил зайти с противоположного конца. Завел просто файлик в облаке. 
В него писал короткий список с перечислением проектов, над которыми я фокусируюсь в текущую неделю. Сразу под этим списком вписывал все дни недели, а каждый вечер писал список из нескольких пунктов под следующим днем. Тоже самое сделал с финансами.
Через несколько недель такого упрощения я понял, какие именно элементы в моей системе продуктивности были лишние, избавился от них и смог вернуться в Things3.
Так же поступил с моим Obsidian. Создал новый сейф, избавился от всех лишних плагинов и сложных структур в заметках, оставил только самое необходимое.
В итоге пришло осознание, что для Zettelkasten'а достаточно папки с текстовыми файлами, куда я записываю сформировавшиеся мысли и иногда перечитываю их.
Для написания больших текстов вернулся к org-моду emacs.
Итогом пусть будет мысль, что практика - хорошо, а паралич выбора и FOMO - плохо. Надеюсь этот виток ведения дел окажется более удачным.
🔥3❤‍🔥1
Type Programming

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

Это достигается простейшим описанием объектного типа или интерфейса. Куда реже мы переопределяем стандартные типы, вроде чисел и превращаем их в брендированные типы - другой мощный механизм, ставший возможным благодаря широким возможностям системы типов.

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

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

Чтобы решить подобные вопросы в “классических ООП” языках были выделено множество паттернов, которые заставляют стелить соломку абсолютно везде - стратегия на интерфейсе абстрактного класса, не должно быть классов не имплементирующих какой-то интерфейс. И прочие прелестные Джава-чсв “из умных книжек” догмы ака паттерны. А все изначально от ограничений. Пока не завезли дженерики даже достаточно типобезопасной функции мап было не сделать. Првильно, стратегии. Привет, любители Го.

В языках с динамической типизацией отродясь таких проблем не было. Они не задают совершенно никаких ограничений. Действительно хорошие попытки задать подобные ограничения в динамических языках - контрактное программирование, но лично я встречал его только на слайдах. Реальных ограничений в них нет. Что сейчас и привело к различным гибридным подходам к статической системе типов.

На другой чаше весов замечательные языки для “небожителей” аля Хаскель, Идрисы и прочие Окамелы. Из более хайпящих сейчас - Раст. Ух сколько радостей и головоломок приносят типы для тех, кто пишет на них библиотеки. И сколько бы я их не пробовал везде одна проблема - система типов сильно проникает в бизнесовый код. Реальный мир вошел в радужное царство единорогов-математиков. Как итог вместо фабрик, синглтонов и прочего из банды четырех мы получаем монады, монады-трасформеры и прочие монады-состояния. (тут важно разделить ФП и программирование на типах - не путаем)

И тут у Тайпскрипта неплохая позиция. Да, для типичных пользователей это все еще часто недосягаемый уровень. Как запрограммировать обход структуры на системе типов или даже написать обобщенный класс - загадка для многих, решаемая только чат гопотой или везением со SO. Но сама возможность прекрасна и при достаточном желании можно даже писать так, чтобы типы эти не лезли в бизнес слой и ребята продолжали описывать простейшие интерфейсики и объектные типы.

А для тех, кто решит преисполниться в программировании на типах могу порекомендовать курс https://type-level-typenoscript.com - без такого введение в программирование на типах входить было куда сложнее. Только как войдете помните пожалуйста о цене программирования на типах и не заставляйте входить в этот мир других.
🔥3🦄2😱1
Top-down и bottom-up команды

Два разных подхода: продумать и сделать или сесть и начать с экспериментов. И быть готовым выкинуть несколько прототипов.

Оба подхода имеют право на жизнь. В одном мы силами системных архитекторов и аналитиков проектируем систему и потом делаем, а в другом мы должны что-то постоянно пробовать делать.
Провальный подход карго-культа на проектирование классно описан в книге про Agile (про разработку системы для полиции), а провалы вторых можно наблюдать в каждом третьем стартапе и сломанных ad-hoc процессах в ваших компаниях.

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

Хорошо - когда ты понимаешь какая команда у вас и как вам комфортно двигаться вместе. Плохо - "ломать людей" и навязывать свой путь решения проблем.
🔥3
FSMoothy

Сходил на Kolesa.conf. И тут подъехали видео докладов.
Самой мякоткой для меня, конечно, был доклад про конечные автоматы.

Когда узнал, что Кирилл собрался делать доклад на тему КА - я поднапрягся и доделал свою либу для TypeORM (typeorm-fsm). До того, как в проектах мы переехали на нее использовали какой-то огрызок с самописной обвязкой. Тут же я приложил чуть больше своего api-дизайнерского скилла и вроде даже получилось скрестить суть-фундамент с практической пользой.

Как мне кажется, основой такой библиотеки в приложении к самомой логике автоматов должны служить два подхода: Observer (реакция на события), DI (использование внешних систем на переходах).

Пробывал ли я еще что-то? Да, посмотрел много вариантов в npm. Везде свои трейдофы. На фронтовом проекте я ранее применял XState. Давайте рассмотрим что меня в нем не устроило:

- Портянка для описания в виде js объекта. Переходы описываются вербозно (зато есть визуализатор), поддерживает стандарт State Chart'ов.
- Observer на action'ах. Описывается очень вербозно. В разных частях портянки объекта-описания.
- Активный конечный автомат (actor). Круто! Но, в таком виде на бэке скорее очень мало куда подойдет.
- Персист данных встроенный в саму либу. На самом же деле логика персиста ложится на клиентскую часть. В экосистеме готового ничего нет.
- Своя система работы с эффектами. Выглядит прикольно, но на деле в таком виде нужно только для активного конечного автомата.

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

- Гварды. Условия на переходах. Без них никуда. Иначе логика также размажется по коду.
- Не все события можно отследить. В моем понимании у события есть следующий следующий жизненный цикл: покидаем предыдущее состояние (onLeave), входим в новое (onEnter), меняем состояние (transition), сработали глобальные подписчики, окончание перехода (onExit). Отсутсвие части этих подписчиков также заставляет размазать часть логики из перехода в клиентский код.
- Вложенные и паралельные состояния. Когда горит красный сигнал светофора - может загореться зеленный сигнал для пешехода. Согласование состояния - одна из фундаментальных фишек автомата. Мы можем сделать отдельное состояние для этого случая или сделать вложенный автомат для состояния "красный сигнал" у светофора. Наличие этой фичи решает проблему роста автомата (state explosion problem).
- Вложенные данные. Автоматы также могут содержать дополнительные атрибуты. Например, счетчик времени. И использовать их на переходах.
- Асинхронные подгрузки. Может потребоваться подгружать начальное состояние и вложенные данные из внешних источников.
...
- и на самом деле много чего еще

Моим решением стало написание собственной либы - fsmoothy. В ней все описанные вещи заложены в дизайн и уже реализованны. Дальнейшее расширение планируется за счет написания отдельных пакетов поверх нее и расширения экосистемы.

Выделяйте автоматы у себя в коде явно, думайте о них при проектировании. Берегите свою кодовую базу! 💎
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍1🦄1
Стримы

В последнее время я регулярно стримлю на канал MemeBattle. У нас кончились кредиты на AWS и мы в рамках стримов сейчас переезжаем на Яндекс Клауд.
Но это не все темы для стримов. Недавно закончился Advent of Typenoscript и мы совместно с @xufostation и другими ребятами, которые прошли весь этот челендж, застримили решение почти всех задачек с довольно подробным разбором. В итоге получился такой мастер класс по Type Level программированию. Думаю, те, кто захочет повторить и послушать как решать такие задачки вынесут много полезного.
В планах на следующие стримы продолжить переписывать одни из наших сервисов для хранения истории Ligretto игр на Platformatic (что это и зачем можно также узнать из стримов), переписать несколько babel плагинов на swc на Rust'е и много чего еще полезного.
В общем, агитирую подписаться на наш канал, ставить лайки, жать на колокольчик чтобы первыми узнавать о предстоящих стримах и конечно же приходить нас смотреть!

https://www.youtube.com/@memebattle_dev/streams
🔥8
Двадцать дней как состоялся релиз первой версии языка Gleam, который должен ознаменовать стабильность и готовность языка к продакшен моментам. И двадцать дней как я пробую этот язык с разных сторон. и мне зашло

Давайте посмотрим, что включено в первый релиз и отмечено core-командой как стабильное:
⭐️Дизайн языка. Все четко, язык похож на Rust+Elixir, но максимально минималистичнее - я бы сказал, что даже минималистичнее Go
⭐️Компилятор. Тут тоже есть чем удивить: реализация TCO для JS, довольно понятный как Erlang, так и JS код на выходе. Написан на Rust’е, так что все работает быстро
⭐️Build Tool. За то время, что пользуюсь ощущение, примерно как от Cargo, четенько
⭐️Форматирование. Немного вкусовщины, но в целом все по кайфу
⭐️Языковой сервер. Пока самая слабенькая часть. Нет, например, подсказок по маркированным(labeled) аргументам, автодополнение довольно глуповатое, не всегда ошибки там где надо показываются и еще пяток мелочей. Но в репозитории языка висит довольно много PRов улучшающих LSP.
⭐️Компилятор в WASM и JS-биндинги. JS-биндинги имеют свой вполне очевидный рантайм оверхед. Прелюдия не большая, что в простых примерах ворочающих списки дает меньший выхлоп в бандл чем тот же ReScript.

Экосистема языка показалась мне не большой, но все минимальное для вебчика уже есть. wisp в качестве минималистичного web-фреймворка. lustre - elm-like фронтенд фреймворк. Есть свой индекс для пакетов - можно посмотреть что вообще есть.

Сам Gleam в первую очередь направлен хоститься на виртуальной машине Erlang - BEAM, что довольно четко очерчивает границы применимости и нишевость языка. Однако хороший интероп в JS с простым FFI и без расскраски функций - сильно расширяют его возможности.

Если вас заинтересовало - для быстрого ознакомления есть тур на оффициальном сайте, а чтобы попрактиковаться есть бесплатный трек с обучением на Exercism.
Please open Telegram to view this post
VIEW IN TELEGRAM
🦄7👍52
Провел сегодня две замечательные сессии на TechTrain в роли эксперта, что поставило окончательную точку после трех месяцев подготовки в роли члена программного комитета. Время пролетело незаметно и как по мне, так вышло очень хорошо.

Мне в целом, нравится помогать готовиться ребятам и наблюдать за тем, что у них получается в итоге. Утренний доклад с Давидом из @it_kachalka про ООП однозначно рекомендую всем к просмотру! Прям хорошая рефлексия и выводы, которые привели его к Функционально Ориентированному Программированию🦀. Дискуссия в конце вообще безумно зарядила меня на ближайшее время.

Если у вас есть что рассказать и вы еще думаете выступать или нет - выступайте. Если думаете о том, стоит ли ходить смотреть доклады - ходите. Ведь митапы, пусть и онлайн - это даже не столько доклады, где вы что-то новое узнаете. Но и тусовка, где можно обсудить свои боли и идеи. Я лично всегда очень тепло вспоминаю, как у нас проходили митапы в Новосибирске, те кулуарные темы и крутые движухи, которые мы устраивали после мероприятий с друзьями. 🌈
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥3🔥2🦄22