в чем принципиальное отличие сигналов от любой другой штуки с подпиской на изменения (например zustand, RxJS, mobx etc..)?
Отличный вопрос. Ведь все это разные способы реализовать реактивность. В чем же отличительная особенность сигналов? Для этого разберем остальные подходы
RxJS:
Основная суть в потоках данных и управлением этим потоком. Те трансформация этих данных и перераспределения между потоками. Это отлично ложится в концепции асинхронных потоков данных и событий. В противовес сигналы сосредотачиваются не на потоках данных, а на самом состоянии и отношениях между сигналами: разделение на состояния и вычисляемые состояния. RxJS это про push-based reactivity, те при отправке значения его цель уведомить всех подписчиков о новом событии и так пойдет по всем каналам, что может значительно сказываться на перфе при наивной работе с ними, так как вычисления не отсекаются по умолчанию. Сигналы же будут сосредоточены на ОБНОВЛЕНИИ состояния и оптимизации распространения обновления: если присвоить одинаковое значение или в результате вычисляемого свойства будет получен тот же результат, то распространение изменения будет пресечено. Также сигналы чаще сосредотачиваются на Pull/PushPull системах реактивности, те инициатором вычисления и обновления служат зависимости и если никто не подписан на сигнал, то и вычислен он не будет.
Итого: Push vs Pull, концентрация над потоком данный vs концентрация на связях и состояниях
Redux / Flux:
Основная задача этого подхода создать однонаправленный поток данных c прозрачными обновлениями: State -> View -> Action -> Reducer -> Actions. По сути эта модель описывает суть этого подхода. Мы здесь не видим ни зависимых состояний(как в сигналах), ни последовательных трансформаций(как в RxJS), мы тут полностью сосредоточены над контролем над обновлением состояния в 1 точке, все остальное остается за пределами. Нет тут ни подписок на отдельные части(в RTK мы имеем селекторы, но по факту они тоже подписываются на весь стор целиком, только обновление вызывают при изменении конкретной выбранной части), ни оптимизаций тому нужны ли кому-то данные эти в сторе. Здесь тоже используется Push-based реактивность: наша задача обновить состояние в Reducer-е изолировав обновление до одной точки, а остальное ему не интересно. При этом это моносторы и работа с разделением их на отдельные независимые части требует дополнительных усилий(RTK это делает за вас во многом). Сигналы же более точечно выбирают что и как им надо и каждый сигнал это и есть сам себе стор, поэтому они независимы и могут легко создаваться и уничтожаться в рантайме, что достаточно сложно для моносторов
Итого: Push vs Pull, концентрация на прозрачности обновления данных vs концентрация на связях и состояниях
Zustand:
По сути облегченные Redux или Flux, упростили API и сделали более простым для разбиения на несколько сторов вместо моностора. В остальном это тот же Flux подход со всеми его плюсами и минусами. Тоже Push-based реактивность сосредоточенная на 1 точке для обновления состояния.
MobX:
Я не так много с ним взаимодействовал, так что могу ошибаться, но MobX вполне могу назвать сигналами: я вижу что он не делает лишних вычислений, те это точно не Push-based реактивность и отсекает излишние вычисления. В нем легко создавать реактивные значения на лету (как и сигналы) и менять взаимосвязи. Также примитивы могут создаваться отдельно (зависимые значения - computed и эффекты - autorun).
Итого: тоже сигналы (по моему мнению)
Существуют и другие концепты: Effector (вечногорячие обсерваблы), $mol_wire (каналы, которые по своей сути тоже сигналы, но со своими фишками), обычные EventEmitter-ы (но они по сути глупые версии реактивных потоков из RxJS). Но их разберем как-нибудь в другой раз
👍32🔥21🤯4
Одна из больших диллем для меня была как часто сюда писать и какой контент тут генерировать.
Первое что стоит признать: у меня очень разношерстная аудитория, тут и реактеры с гигантским стажем и вьюшники и даже те кто фронту отношения вообще не имеют и многие другие. И я очень этим ОЧЕНЬ доволен, не хочу чтобы этот канал замыкался только на Vue или фронтенде.
И тут следующий момент: Я бы не хотел отвлекать всю массу людей частыми и мало полезными новостями. Этот канал будет оставаться для новостей и крупных постов с разборами или анализами от меня. Но часто у меня бывает желание постить что-то в сиюминутном порыве или просто небольшие интересности и для этого я выделю отдельный канал Vueist. На 80%+ он будет сосредоточен только на Vue контенте или чего-то что его окружает. И количество постов там будет кратно большим чем тут.
Такое разделение позволит мне оставить этот канал как нейтральную территорию полезную или интересную для широких масс, а Vueist сделать своим уголком для мира Vue чего от меня уже ждут давно и просят.
PS. Я уже давно мечтал сделать этот шаг (канал Vueist создан еще в 2023 и просто ждал своего момента). Раньше весь мой контент это был распределено по куче сообществ в которых я состоял, теперь же оно будет централизовано в одном месте
Vueist: обучающие материалы по Vue, советы, новости и прочий шитпостинг от влюбленного во Vue 💚 всем сердцем человека
Первое что стоит признать: у меня очень разношерстная аудитория, тут и реактеры с гигантским стажем и вьюшники и даже те кто фронту отношения вообще не имеют и многие другие. И я очень этим ОЧЕНЬ доволен, не хочу чтобы этот канал замыкался только на Vue или фронтенде.
И тут следующий момент: Я бы не хотел отвлекать всю массу людей частыми и мало полезными новостями. Этот канал будет оставаться для новостей и крупных постов с разборами или анализами от меня. Но часто у меня бывает желание постить что-то в сиюминутном порыве или просто небольшие интересности и для этого я выделю отдельный канал Vueist. На 80%+ он будет сосредоточен только на Vue контенте или чего-то что его окружает. И количество постов там будет кратно большим чем тут.
Такое разделение позволит мне оставить этот канал как нейтральную территорию полезную или интересную для широких масс, а Vueist сделать своим уголком для мира Vue чего от меня уже ждут давно и просят.
PS. Я уже давно мечтал сделать этот шаг (канал Vueist создан еще в 2023 и просто ждал своего момента). Раньше весь мой контент это был распределено по куче сообществ в которых я состоял, теперь же оно будет централизовано в одном месте
Vueist: обучающие материалы по Vue, советы, новости и прочий шитпостинг от влюбленного во Vue 💚 всем сердцем человека
Telegram
Vueist
Vue шитпостинг, желтуха, советы и мысли
Дополнительный канал к @zede_code от @zede1697
Дополнительный канал к @zede_code от @zede1697
🔥39💩11👍8👎2
Pipeline operator in JS.
Самая ожидаемая фича от JavaScript уже в течении многих лет, но продвижение которой по стейджам tc39 предложений уже не происходит очень давно.
Почему она так ожидаема и почему она так долго идет? Для начала разберемся с проблематикой
Вот у нас есть получение некоторых данных на основе, очень частый кейс который приходится писать в работе с данными:
Строка длинная и естественно ее можно разбить на строки, пытаться отформатировать или разбить на переменные (имена которые порой ой как больно придумывать, потому что нам они НЕ ИНТЕРЕСНЫ, нам нужен лишь результат, а не 10 промежуточных значений). Форматирование строки тоже не даст много полезных результатов, так как тут есть некоторая вложенность. Что же предлагает нам пропозал?
Строка стала чуть длиннее, зато нам теперь совершенно очевиден порядок для разбиения
Теперь суть кода считается последовательно и без запоминания каких-то контекстов и это совсем базовый сценарий. Магия происходит когда мы задумываемся как мы раньше пытались сделать вот такой "поток" мысли: правильно, чейнингом. Функция возвращала объект в котором лежат методы которые вновь возвращают объект и так далее. Но мы с вами упирались в один момент: методы уже должны быть заложены в объекте. Те возьмем обработку массива
Те как только нужно было использовать метод которого нет в объекте, то вся магия тут же ломалась и мы вынуждены были либо делать уродливое вложение, либо создавать сущность которая нам не интересна (единственная ее задача переложить прошлое значение как аргумент)
И вот тут приходит на помощь pipe
Как мы видим в пайплайне ему не интересно чейнинг у нас или наши кастомные методы, он позволяет расширять возможности при использовании не пытаясь расширить прототипы для удобства. Особенно сильно это заметно на таких возможностях, которые подсаживают на чейнинг, как например Iterator Helpers
Суть думаю ясна, что такие API очень завязаны только на встроенные возможности и юзать что-то свое с ними тем самым расширяя API не слишком и приятно. И вот такие API мог бы полностью раскрыть Pipeline Operator так как он может в 1 цепочку объединять разнородное API.
Самая ожидаемая фича от JavaScript уже в течении многих лет, но продвижение которой по стейджам tc39 предложений уже не происходит очень давно.
Почему она так ожидаема и почему она так долго идет? Для начала разберемся с проблематикой
Вот у нас есть получение некоторых данных на основе, очень частый кейс который приходится писать в работе с данными:
const = Object.fromEntries(Object.entries(someData).filter(([,value]) => !!value).map(([key, value]) => [key, value * 2]))
Строка длинная и естественно ее можно разбить на строки, пытаться отформатировать или разбить на переменные (имена которые порой ой как больно придумывать, потому что нам они НЕ ИНТЕРЕСНЫ, нам нужен лишь результат, а не 10 промежуточных значений). Форматирование строки тоже не даст много полезных результатов, так как тут есть некоторая вложенность. Что же предлагает нам пропозал?
const = Object.entries(someData) |> %.filter(([,value]) => !!value) |> %.map(([key, value]) => [key, value * 2])) |> Object.fromEntries(%)
Строка стала чуть длиннее, зато нам теперь совершенно очевиден порядок для разбиения
const = Object.entries(someData)
|> %.filter(([,value]) => !!value)
|> %.map(([key, value]) => [key, value * 2]))
|> Object.fromEntries(%)
Теперь суть кода считается последовательно и без запоминания каких-то контекстов и это совсем базовый сценарий. Магия происходит когда мы задумываемся как мы раньше пытались сделать вот такой "поток" мысли: правильно, чейнингом. Функция возвращала объект в котором лежат методы которые вновь возвращают объект и так далее. Но мы с вами упирались в один момент: методы уже должны быть заложены в объекте. Те возьмем обработку массива
Object.entries(someData)
.filter(([,value]) => !!value)
.map(([key, value]) => [key, value * 2]))
// и вот следующего оператора нет в Array, зато он есть в Object
Object.groupBy(/*тут должен был быть наш массив*/)
Те как только нужно было использовать метод которого нет в объекте, то вся магия тут же ломалась и мы вынуждены были либо делать уродливое вложение, либо создавать сущность которая нам не интересна (единственная ее задача переложить прошлое значение как аргумент)
И вот тут приходит на помощь pipe
Object.entries(someData)
|> %.filter(([,value]) => !!value)
|> %.map(([key, value]) => [key, value * 2]))
|> Object.groupBy(%, grouper)
|> logAndReturn(%)
|> sendToClient(%)
Как мы видим в пайплайне ему не интересно чейнинг у нас или наши кастомные методы, он позволяет расширять возможности при использовании не пытаясь расширить прототипы для удобства. Особенно сильно это заметно на таких возможностях, которые подсаживают на чейнинг, как например Iterator Helpers
Iterator.from([1,2,3,4,5,6])
.filter((num) => num % 2)
.map((num) => num * 2 + 1)
.drop(1) // откидываем первое число
zip() // а вот zip в нем нет, думайте сами как сюда такую функцию вкорячить
Суть думаю ясна, что такие API очень завязаны только на встроенные возможности и юзать что-то свое с ними тем самым расширяя API не слишком и приятно. И вот такие API мог бы полностью раскрыть Pipeline Operator так как он может в 1 цепочку объединять разнородное API.
🔥19👍9
Интересный вопрос. А есть ли у нас уже что-то подобное? Ответ смешной но есть... около-монадические промисы. Попробуем написать это на них
Работает? Работает. Эффект схожий с пайплайном? Схожий. А что по типизации? Все шикарно с типизацией. Тогда в чем минусы? А минусы как раз в монадичности, мы не можем просто так извлечь значение из контекста, нам нужно его вытянуть а для этого нужен await и сами понимаете как это сильно окрашивает функции. Но это не единственный минус. Также такой код сложнее оптимизировать, так как движку нужно по сути каждый такой стейдж развернуть и заинлайнить (что будет сделано очень крайне маловероятно). В то время как pipeline operator может оптимизироваться компилятором на раз, так как это по сути 1 выражение.
Это я все к чему? Да все к тому, что мы реально заждались возможности которая перевернет мир построения API и уберет потенциальные проблемы как необходимость захламления методами в объектах, уродливые вложения и имена констант которые никому не нужны. Жаль и очень жаль, что уже 3 года 0 движений по нему... хотя каждое собрание tc39 я вижу одни и те же сообщения "- а что там по пайлпайну? - а ничего, мы его в этот раз не обсуждаем"
new Promise(Iterator.from([1,2,3,4,5,6]))
.then((x) => x.filter((num) => num % 2))
.then((x) => x.map((num) => num * 2 + 1))
.then((x) => x.drop(1))
.then((x) => zip(x, [1,2,3])) // никаких проблем
Работает? Работает. Эффект схожий с пайплайном? Схожий. А что по типизации? Все шикарно с типизацией. Тогда в чем минусы? А минусы как раз в монадичности, мы не можем просто так извлечь значение из контекста, нам нужно его вытянуть а для этого нужен await и сами понимаете как это сильно окрашивает функции. Но это не единственный минус. Также такой код сложнее оптимизировать, так как движку нужно по сути каждый такой стейдж развернуть и заинлайнить (что будет сделано очень крайне маловероятно). В то время как pipeline operator может оптимизироваться компилятором на раз, так как это по сути 1 выражение.
Это я все к чему? Да все к тому, что мы реально заждались возможности которая перевернет мир построения API и уберет потенциальные проблемы как необходимость захламления методами в объектах, уродливые вложения и имена констант которые никому не нужны. Жаль и очень жаль, что уже 3 года 0 движений по нему... хотя каждое собрание tc39 я вижу одни и те же сообщения "- а что там по пайлпайну? - а ничего, мы его в этот раз не обсуждаем"
GitHub
GitHub - tc39/proposal-pipeline-operator: A proposal for adding a useful pipe operator to JavaScript.
A proposal for adding a useful pipe operator to JavaScript. - tc39/proposal-pipeline-operator
🔥26👍6
Первый крупный проект на Rolldown кажется уже существует. А недавно был создан репозиторий vite-rolldown в котором уже тестируют их вместе. Значит относительно скоро мы сможем увидеть новую эпоху в мире Vite и сборщиков для веба в целом
Ссылка на оригинальный пост в X
Ссылка на оригинальный пост в X
👍25🔥20
Первый раз пишу об ИИ-шках на канале, но этот момент должен был настать и игнорировать эту тему нереально.
Но сейчас у меня новость о выгрузке системного промпта у v0 (генератор приложений от Vercel). Что это такое и почему это важно?
Казалось бы многие текущие AI-инструменты это просто обертки над LLM-ками, но вся магия скрывается за тем как формируется запрос и какой системный промпт за этим стоит. Так как именно в системном промпте часто спрятано как будет мыслить AI. Поэтому же нельзя сказать что Cursor условно и Windsurf одинаковы, просто разные UI-ки, нет, там спрятано куда больше разной работы от индексирования кодовой базы, до как раз системного промпта, который как выяснилось у Windsurf крайне забавный. До этого интересности нашли у системного промпта новой сервиса с LLM Grok3
В целом изучать системные промпты всегда интересно, так как они дают понимание зачастую какие техники можно использовать для получения лучших результатов или попытки получить нужное поведение.
А удавалось ли вам вытянуть что-то интересное из AI-ки или сервиса с которым вы работаете? Пробовали ли вообще заняться своеобразным реверс-инжинирингом AI-сервиса?
Но сейчас у меня новость о выгрузке системного промпта у v0 (генератор приложений от Vercel). Что это такое и почему это важно?
Казалось бы многие текущие AI-инструменты это просто обертки над LLM-ками, но вся магия скрывается за тем как формируется запрос и какой системный промпт за этим стоит. Так как именно в системном промпте часто спрятано как будет мыслить AI. Поэтому же нельзя сказать что Cursor условно и Windsurf одинаковы, просто разные UI-ки, нет, там спрятано куда больше разной работы от индексирования кодовой базы, до как раз системного промпта, который как выяснилось у Windsurf крайне забавный. До этого интересности нашли у системного промпта новой сервиса с LLM Grok3
В целом изучать системные промпты всегда интересно, так как они дают понимание зачастую какие техники можно использовать для получения лучших результатов или попытки получить нужное поведение.
А удавалось ли вам вытянуть что-то интересное из AI-ки или сервиса с которым вы работаете? Пробовали ли вообще заняться своеобразным реверс-инжинирингом AI-сервиса?
GitHub
GitHub - x1xhlol/system-prompts-and-models-of-ai-tools: FULL v0, Cursor, Manus, Same.dev, Lovable, Devin, Replit Agent, Windsurf…
FULL v0, Cursor, Manus, Same.dev, Lovable, Devin, Replit Agent, Windsurf Agent, VSCode Agent, Dia Browser, Xcode, Trae AI, Cluely & Orchids.app (And other Open Sourced) System Prompts, Tool...
🔥15👍5
Forwarded from HolyJS — канал конференции
#подкаст
Разбираемся, кто, зачем и как обновляет JS.
Присоединяйтесь к обсуждению пропозалов — уже через час!
Новый выпуск «Тяжелого утра» в 11:00:
— на YouTube
— в VK Видео
Разбираемся, кто, зачем и как обновляет JS.
Присоединяйтесь к обсуждению пропозалов — уже через час!
Новый выпуск «Тяжелого утра» в 11:00:
— на YouTube
— в VK Видео
🔥14👍3
Хочу похвалить команду Lynx(если вы как-то пропустили новость, то это "Убийцы" ReactNative/NativeScript), ведь кроме документации они еще реализовали целую спеку! Я почитал ее и написана она весьма хорошо, как минимум обильное описание каждого термина есть, а это уже много стоит. Хорошо приправлена ссылками на отдельные части, язык более чем понятный и сама спека не такая уж и длинная. Алгоритмы в нем описаны весьма интересно, через под-заголовки и описание действия в них(стейджи), прям алгоритмов как в спеке ES или HTML там нет.
Наверное это тот случай, когда спека имеет смысл и скорее объясняет чем отпугивает. Круто, что такое реализовали
PS. готовлю еще один пост про Lynx на vue-канале относительно текущих дел со Vue + Lynx
Наверное это тот случай, когда спека имеет смысл и скорее объясняет чем отпугивает. Круто, что такое реализовали
PS. готовлю еще один пост про Lynx на vue-канале относительно текущих дел со Vue + Lynx
lynxjs.org
Empower the web community and invite more to build cross-platform apps
👍22🔥3💩3
TS СТАЛ BLAZING FAST
Пока все в экстазе носятся с ускорение TS в 10 раз, я призываю вас подумать о выборе golang. Да, авторы объяснили свой выбор и я полностью уважаю его с технической и менеджерской точки зрения (минимизация расходов, скорость перехода, уменьшение кол-ва потенциальных проблем и тд). И в целом перф круто, все дела! Но я немного попробую посмотреть негативную сторону, чтобы уравновесить настроения.
DISCLAIMER! Я полностью уважаю экспертизу специалистов из Microsoft и верю, что они делали выбор исходя из технических аспектов, как они неоднократно заявляли. Я лишь пытаюсь заглянуть на разные стороны медали и приглашаю к обсуждению
Я не просто так зачеркнул BLAZING в заголовке. Думаю все догадались о чем пойдет речь: почему не Rust. И я не хочу сейчас обсуждать что из них круче. Будем обсуждать это исключительно с точки зрения влияния на экосистему.
1. Экосистема туллинга на языках
Rust уже состоялся как основной язык для туллинга в мире JS. Я уже писал об этом в старом посте. И количество этого туллинга с момента поста только росло. А почему это важно? Так как таким образом было бы гораздо проще делать интеграции с уже кучей туллинга написанного на Rust, возможно даже появилось бы какое-то переиспользование. Относительно gonalg: битву за туллинг он проиграл во многом по причине ниже. С другой стороны если не брать экосистему туллинга, а JS/TS разработчиков. То full-stack связка с go очень даже популярна и возможно сподвигнет появлению большего количества контрибьютеров
2. Производительность в WASM.
Да, перф Go в WASM это тема отдельного обсуждения. По ссылке вы найдете еще ссылки на другие обсуждения и так можете погружаться в тему сколько хотите. Но факт есть факт - go не самый производительный в контексте WASM. А зачем нам это? Плейграунды, web-container-ы и прочие ситуации когда у нас все гоняется в браузере не супер редки. Другая сторона: вполне возможно это станет мотивацией наконец-то довести перф Go в WASM до должного уровня или Microsoft инвестирует в инструмент который сможет это реализовать лучше(например в tinygo или другую альтернативу). Потыкать WASM GO (НЕОФИЦИАЛЬНАЯ ВЕРСИЯ) можно тут [исходники] (там выводится скорость компиляции в браузере)
Конечно много вопросов в целом есть у людей, благо на них оперативно достаточно отвечают в дискуссиях. Также отличный разбор интервью от artalar.
В остальном же радуемся и ждем TypeScript 7 (версия с которой Go версия станет основной).
Пока все в экстазе носятся с ускорение TS в 10 раз, я призываю вас подумать о выборе golang. Да, авторы объяснили свой выбор и я полностью уважаю его с технической и менеджерской точки зрения (минимизация расходов, скорость перехода, уменьшение кол-ва потенциальных проблем и тд). И в целом перф круто, все дела! Но я немного попробую посмотреть негативную сторону, чтобы уравновесить настроения.
DISCLAIMER! Я полностью уважаю экспертизу специалистов из Microsoft и верю, что они делали выбор исходя из технических аспектов, как они неоднократно заявляли. Я лишь пытаюсь заглянуть на разные стороны медали и приглашаю к обсуждению
Я не просто так зачеркнул BLAZING в заголовке. Думаю все догадались о чем пойдет речь: почему не Rust. И я не хочу сейчас обсуждать что из них круче. Будем обсуждать это исключительно с точки зрения влияния на экосистему.
1. Экосистема туллинга на языках
Rust уже состоялся как основной язык для туллинга в мире JS. Я уже писал об этом в старом посте. И количество этого туллинга с момента поста только росло. А почему это важно? Так как таким образом было бы гораздо проще делать интеграции с уже кучей туллинга написанного на Rust, возможно даже появилось бы какое-то переиспользование. Относительно gonalg: битву за туллинг он проиграл во многом по причине ниже. С другой стороны если не брать экосистему туллинга, а JS/TS разработчиков. То full-stack связка с go очень даже популярна и возможно сподвигнет появлению большего количества контрибьютеров
2. Производительность в WASM.
Да, перф Go в WASM это тема отдельного обсуждения. По ссылке вы найдете еще ссылки на другие обсуждения и так можете погружаться в тему сколько хотите. Но факт есть факт - go не самый производительный в контексте WASM. А зачем нам это? Плейграунды, web-container-ы и прочие ситуации когда у нас все гоняется в браузере не супер редки. Другая сторона: вполне возможно это станет мотивацией наконец-то довести перф Go в WASM до должного уровня или Microsoft инвестирует в инструмент который сможет это реализовать лучше(например в tinygo или другую альтернативу). Потыкать WASM GO (НЕОФИЦИАЛЬНАЯ ВЕРСИЯ) можно тут [исходники] (там выводится скорость компиляции в браузере)
Конечно много вопросов в целом есть у людей, благо на них оперативно достаточно отвечают в дискуссиях. Также отличный разбор интервью от artalar.
В остальном же радуемся и ждем TypeScript 7 (версия с которой Go версия станет основной).
Microsoft News
A 10x Faster TypeScript
Embarking on a native port of the existing TypeScript compiler and toolset to achieve a 10x performance speed-up.
👍18💩8🔥3👎2
The pit of Failure (or Success)
Часто при проектировании API кроме того что нам важно думать не только о фичах и возможностях которые он дает, но и какой импакт этот API несет при использовании. И тут есть 2 противоположных концепта: Falling Into The Pit of Success/Failure или при переводе Упасть В Яму Успеха/Неудачи.
Какие же ключевые принципы разработки за этим скрываются? Если сократить и упростить, то выйдет: Делай так чтобы правильно было использовать легко, а неправильно сложно. Те наша задача мотивировать людей и поощрять правильное использование API и делать так, чтобы некорректное использование всем видом кричало, что тут дела обстоят не так (fall into the pit of success). Обратный пример, когда API словно подталкивает использовать себя грязно, а использовать корректно больше похоже на тернистый путь или полосу испытаний (Я думаю каждый сталкивался с таким ощущением)
Давайте возьмем пару примеров из API и рассмотрим их:
React:
И тут нам интересно API
И вот сегодня я увидел обратный пример из мира Svelte:
Это сегодняшний анонс долгожданной фичи, чтобы вычислимые значения могли быть временно изменены. Крутая же фича? В целом да, ее запрашивали и ждали, а без нее приходилось использовать костыли. И вроде как надо радоваться? Нам же дали возможность и маловероятно, что оно что-то сломает... Но вот тут как раз всплывает тема того к чему мы подталкиваем дизайном нашего API.
В реактивной системе необходимость делать writable вычислимые поля достаточно редка. Кроме того нам дали возможность делать только прямую запись, а не условный сеттер который бы позволил сделать two way connection, нет, это не тот случай! Те мы можем просто лезть в кэш вычислимого свойства и подменять его до изменения значения. Ну надо же людям эту фичу, в чем проблема? А в том, что в 99% случаев эта фича не нужна, а вот все 100% $derived полей стали вместо read-only теперь writable. И никакой вас TypeScript не спасет от записи в него случайно (например, при рефакторинге) и вы больше видя перед собой $derived не можете быть уверены записывают что-то в него или нет, эта информация лежит где-то в другом месте компонента и пока вы не прочтете код компонента полностью вы больше не можете быть в этом уверены.
Таким образом эта возможность не подталкивает к правильному использованию сигналов, делает так что допускать случайные ошибки стало проще и при этом осталось относительно скудным по возможностям (как и написал это не дает возможность делать two way connection). С другой стороны мы покрыли возможность 1% от случаев. Вот это пример, когда мы видим собой
Как этого можно было избежать?
Использовать отдельный нейминг
Или использовать отдельный параметр
Или на худой конец если мы хотим оставить магию в нашем мире, то создать явное API
Это все еще лучше, чем выкинуть забор и дать неявное по смыслу API.
Не думайте что это "написать плохо на чем угодно можно" /"вопрос прямых рук". НЕТ! Вы, как автор API, должны формировать у людей прямые руки, а кривые выпрямлять. Пожалуйста, прикидывайте в голове эти сценарии: "мотивирую ли я делать что-то плохое" и "поощряю ли я правильное использование". Спасибо...
Часто при проектировании API кроме того что нам важно думать не только о фичах и возможностях которые он дает, но и какой импакт этот API несет при использовании. И тут есть 2 противоположных концепта: Falling Into The Pit of Success/Failure или при переводе Упасть В Яму Успеха/Неудачи.
Какие же ключевые принципы разработки за этим скрываются? Если сократить и упростить, то выйдет: Делай так чтобы правильно было использовать легко, а неправильно сложно. Те наша задача мотивировать людей и поощрять правильное использование API и делать так, чтобы некорректное использование всем видом кричало, что тут дела обстоят не так (fall into the pit of success). Обратный пример, когда API словно подталкивает использовать себя грязно, а использовать корректно больше похоже на тернистый путь или полосу испытаний (Я думаю каждый сталкивался с таким ощущением)
Давайте возьмем пару примеров из API и рассмотрим их:
React:
<div dangerouslySetInnerHTML={{ __html: "Hello" }} />
И тут нам интересно API
dangerouslySetInnerHTML
, видите что оно делает? Да, оно всем своим видом кричит, что вы делаете что-то опасное и нехорошее, а громоздкость с { __html: "Hello" }
дополняет картинку. В добавок вам еще будет сложнее точно сходу вспомнить правильное написание и вы пойдете в документацию, где вам еще раз дадут понять: "скорее всего ты делаешь что-то не то". Это прекрасный пример того, как с помощью API вам не дают применить нечто потенциально опасное.И вот сегодня я увидел обратный пример из мира Svelte:
let double = $derived(count*2);
double = 3.14;
Это сегодняшний анонс долгожданной фичи, чтобы вычислимые значения могли быть временно изменены. Крутая же фича? В целом да, ее запрашивали и ждали, а без нее приходилось использовать костыли. И вроде как надо радоваться? Нам же дали возможность и маловероятно, что оно что-то сломает... Но вот тут как раз всплывает тема того к чему мы подталкиваем дизайном нашего API.
В реактивной системе необходимость делать writable вычислимые поля достаточно редка. Кроме того нам дали возможность делать только прямую запись, а не условный сеттер который бы позволил сделать two way connection, нет, это не тот случай! Те мы можем просто лезть в кэш вычислимого свойства и подменять его до изменения значения. Ну надо же людям эту фичу, в чем проблема? А в том, что в 99% случаев эта фича не нужна, а вот все 100% $derived полей стали вместо read-only теперь writable. И никакой вас TypeScript не спасет от записи в него случайно (например, при рефакторинге) и вы больше видя перед собой $derived не можете быть уверены записывают что-то в него или нет, эта информация лежит где-то в другом месте компонента и пока вы не прочтете код компонента полностью вы больше не можете быть в этом уверены.
Таким образом эта возможность не подталкивает к правильному использованию сигналов, делает так что допускать случайные ошибки стало проще и при этом осталось относительно скудным по возможностям (как и написал это не дает возможность делать two way connection). С другой стороны мы покрыли возможность 1% от случаев. Вот это пример, когда мы видим собой
pit of failure
, да нас не мотивируют прямым образом использовать этот функционал неправильно, но "заборчик" рядом с ямой куда-то унесли.Как этого можно было избежать?
Использовать отдельный нейминг
let double = $writableDerived(count*2);
double = 3.14;
Или использовать отдельный параметр
let double = $derived(count*2, { writable: true }); // или любая другая явная модификация
double = 3.14;
Или на худой конец если мы хотим оставить магию в нашем мире, то создать явное API
let double = $derived(count*2);
$modifyDerivedCache(double, 3.14); // мы сделали неудобное, но однозначное API
Это все еще лучше, чем выкинуть забор и дать неявное по смыслу API.
Не думайте что это "написать плохо на чем угодно можно" /"вопрос прямых рук". НЕТ! Вы, как автор API, должны формировать у людей прямые руки, а кривые выпрямлять. Пожалуйста, прикидывайте в голове эти сценарии: "мотивирую ли я делать что-то плохое" и "поощряю ли я правильное использование". Спасибо...
👍60🔥11
Дождался. Доклад по Шестеренкам реактивности Vue наконец-то вышел. В нем были разобраны базовые механизмы на которых основана работа реактивности во Vue.
- Ссылка на презентацию
- Ссылка на карту реактивности
И так полезный сопровождающий материал:
- Chibivue [Ru]
- Курс от Michael Thiessen
- Ссылка на презентацию
- Ссылка на карту реактивности
И так полезный сопровождающий материал:
- Chibivue [Ru]
- Курс от Michael Thiessen
YouTube
Денис Чернов — Шестеренки реактивности Vue
Подробнее о конференции HolyJS: https://jrg.su/EM4wwV
— —
Мы любим Vue за простоту и скорость разработки на нем. Но часто говорят, что в нем много магии и подкапотной работы. Однако ощущение магии развеивается, если разобраться, как работают все шестеренки…
— —
Мы любим Vue за простоту и скорость разработки на нем. Но часто говорят, что в нем много магии и подкапотной работы. Однако ощущение магии развеивается, если разобраться, как работают все шестеренки…
🔥74👍7🤔1🤯1
Когда речь заходит о изучении TypeScript в голову сразу приходит Matt Pocock. Настоящий маг TypeScript-а и автор лучших статей по этому языку. И вот он выкатил нам новый подарок: Total TypeScript Essentials.
Это книга по всему TypeScript который нужен разработчику, да она не охватывает все таинства языка, но базу дает очень хорошую. Книга совершенно бесплатная и при быстром обзоре мне показалась очень хорошо структурированной и наполненной. Вполне возможно, что на данный момент это наиболее актуальная и лучшая книга для изучения TypeScript (так как книга была выложена лишь недавно, то прочесть полностью ее я не успел, чтобы это утверждать однозначно).
В целом появление таких ресурсов всегда радует. А если содержания книги вам покажется мало, то однозначно рекомендую ознакомиться с его статьями и youtube каналом, где разбираются уже более узкие темы подробно
#ts #материалы
Это книга по всему TypeScript который нужен разработчику, да она не охватывает все таинства языка, но базу дает очень хорошую. Книга совершенно бесплатная и при быстром обзоре мне показалась очень хорошо структурированной и наполненной. Вполне возможно, что на данный момент это наиболее актуальная и лучшая книга для изучения TypeScript (так как книга была выложена лишь недавно, то прочесть полностью ее я не успел, чтобы это утверждать однозначно).
В целом появление таких ресурсов всегда радует. А если содержания книги вам покажется мало, то однозначно рекомендую ознакомиться с его статьями и youtube каналом, где разбираются уже более узкие темы подробно
#ts #материалы
Total TypeScript
Total TypeScript Essentials
Learn how to use TypeScript to level-up your applications as a web developer through exercise driven self-paced workshops and tutorials hosted by TypeScript wizard Matt Pocock.
🔥65👍8🤔1
С минуты на минуту (в 19:00мск) приму участие в Frontend-свояке от SiberiaCanCode (большое спасибо за приглашение Диме!). Думаю будет много веселых вопросов и неожиданных тупняков. В целом приглашаю весело провести с нами время!
Площадки: twitch, youtube
Площадки: twitch, youtube
YouTube
🏆 sigame своя игра по фронтенду (Глеб Михеев, Александр Стародубцев, Денис Чернов, Антон Непша)
Поддержка автора 🧊
boosty - https://boosty.to/siberiacancode
donatealerts - https://www.donationalerts.com/r/siberiacancode
Социальные сети 🔥
boosty: https://boosty.to/siberiacancode
telegram: https://t.iss.one/siberiacancode
vk: https://vk.com/siberiacancode…
boosty - https://boosty.to/siberiacancode
donatealerts - https://www.donationalerts.com/r/siberiacancode
Социальные сети 🔥
boosty: https://boosty.to/siberiacancode
telegram: https://t.iss.one/siberiacancode
vk: https://vk.com/siberiacancode…
🔥17👍2👎1
С минуты на минуту будем заполнять The State Of HTML 2025 и обсуждать текущее положение веба.
Ожидается огромный поток информации на выпуск :D
Ожидается огромный поток информации на выпуск :D