Функциональное программирование от А до Я. ФП на JS. Монады, функторы, каррирование, композиция

Ғылым және технология

В этом видео мы поговорим про функциональное программирование на javascript. Разберем такие темы как: Декларативность, Чистые функции и сайд эффекты, Иммутабельность (неизменяемость), Функции первого класса, Функции высшего порядка, Композиция/конвейер, Частичное применение и каррирование, Chaining, Контейнеры, Функторы и аппликативные функторы, Монады, Спецификация Fantasy-Land
Мой курс "Продвинутый Frontend. В production на React", скидка 20% - ulbitv.ru/frontend
Таймкоды:
00:00 ➝ Введение
01:30 ➝ План на урок
04:00 ➝ Что такое ФП? Сравнение с ООП
07:20 ➝ Концепции ФП
09:00 ➝ Декларативность vs императивность
13:25 ➝ Чистые функции и сайд эффекты
18:10 ➝ Иммутабельность (неизменяемость данных)
22:40 ➝ Минусы мутабельности и преимущества иммутабельности
24:20 ➝ Функции первого класса
26:40 ➝ Функции высшего порядка
31:20 ➝ Смысл концепций ФП
33:10 ➝ Композиция (compose)
37:00 ➝ Конвейер (pipe)
37:45 ➝ Каррирование и частичное применение
45:50 ➝ chaining (цепочки вызовов)
46:40 ➝ Контейнеры
52:05 ➝ Функторы и монады
58:55 ➝ Аппликативные функторы
01:03:10 ➝ Спецификация Fantasy land
01:04:10 ➝ Другие монады (either, future, writer)
01:06:40 ➝ Время ставить лайки и писать комментарии) всем спасибо!
Ссылка на мой телеграм канал - t.me/ulbi_tv
Поддержать меня и мой канал вы можете по ссылкам ниже.
Patreon/boosty (доступ к бонусам) - boosty.to/ulbitv
Qiwi кошелек - qiwi.com/n/BODYE821
Яндекс деньги - yoomoney.ru/to/4100116193037469

Пікірлер: 231

  • @fatcat4168
    @fatcat416812 күн бұрын

    Сегодня досрочно закрыл испытательный срок на своей первой работе фронтом 🎉🎉🎉 во многом благодаря Тимуру🎉🎉🎉, прошел почти весь курс, не дошел только до последнего раздела. Проходил ещё на первом потоке, у меня там была аватарка с вислоухим котом😺 когда прошел, на полгода забросил, но всё-таки взял себя в руки и устроился😊 всем удачи и верьте в себя!

  • @es7729

    @es7729

    11 күн бұрын

    Мои поздравления! Красавчик!

  • @vladislavkomkov5178

    @vladislavkomkov5178

    9 күн бұрын

    Хвастайся зп в 3 кириешки))

  • @webtensei2327

    @webtensei2327

    8 күн бұрын

    @@vladislavkomkov5178так все с чего-то начинают)

  • @diamondserg-43

    @diamondserg-43

    4 күн бұрын

    Молодец!

  • @Kokurorokuko
    @Kokurorokuko9 күн бұрын

    По-моему, на 51:00 f и g нужно поменять местами. Сначала применяется f (она должна быть внутри), а потом g.

  • @ker4ik13
    @ker4ik1312 күн бұрын

    Обожаю твои уроки. Нет никого, кто объяснял бы понятнее и интереснее

  • @UlbiTV

    @UlbiTV

    12 күн бұрын

    Стараемся, спасиб)

  • @404Negative

    @404Negative

    10 күн бұрын

    неет нееет никого кроме бога одного

  • @dmitrykuskov6715
    @dmitrykuskov67158 күн бұрын

    Интересная тема для меня. В свое время проходил курс по Haskell, поэтому постараюсь дополнительно разъяснить про Монаду и Аппликативный функтор, если кому-то интересно, но не до конца понятно. 1) Монада - это структура, являющаяся наследником Функтора, но для которой дополнительно реализован метод chain. В разных языках/библиотеках название может быть разным. chain очень похож на map, отличие в том, что передаваемая в метод chain функция возвращает не значение (как в случае с map), а сам контейнер, в который запаковано значение. Пример Монады, который прямо под носом, но не был в таком ключе упомянут в видео - это Array. Для него методом chain по своей сути является flatMap: ведь функция, передаваемая во flatMap возвращает сам контейнер - Array: const duplicate = (arr) => arr.flatMap((n) => [n, n]); duplicate([1,2,3]); // [1,1,2,2,3,3] ramdajs.com/docs/#chain Как видно из примера, Монада - это более мощный интерфейс, чем Функтор, потому что позволяет менять не только запакованные значения(в случае с map), но и структуру самого контейнера. При использовании Maybe как Монады мы можем преобразовать Maybe в Nothing (использую псевдо-код): Maybe.of(1).chain(() => Nothing); // Nothing Maybe.of(1).chain((n) => Maybe.of(n * 2)); // Maybe(2) Используя Maybe как Функтор, мы можем изменить только значение, но не сам контейнер: Maybe.of(1).map((n) => n * 2); // Maybe(2) Промис в некотором понимании можно использовать и как Функтор, и как Монаду: Promise.resolve(1).then((n) => n * 2); Promise.resolve(1).then((n) => Promise.resolve(n * 2)); 2) Если кратко говорить про Аппликативный функтор, то он нужен, чтобы применять обычную функцию к упакованным значениям. Важно, чтобы все аргументы функции были одного типа. Например, у нас есть функция сложения, работающая с примитивами: const sum = (a, b) => a + b; Но мы хотим сложить не просто 2 числа, а 2 числа, упакованных в Maybe, причем сделать это лаконично и переиспользуя функцию sum. Maybe является Аппликативным функтором, т.к. реализует метод ap. Поэтому можем решить задачу так: const maybeResult = liftA2(sum, maybe1, maybe2); Если хотя бы 1 из переданных Maybe окажется Nothing, то результат всего выражения будет Nothing: такое поведение прописано в реализации ap для Maybe, которая дергается внутри liftA2. Для других структур поведение может быть своим, главное, чтобы оно удовлетворяло законам Аппликативных функторов. 3) Также можно упомянуть, что любая Монада является Аппликативным функтором, а любой Апликативный функтор является обычным Функтором. Это видно на схеме спецификации fantasy-land. На практике это означает, что если нам нужно объявить какую структуру Монадой, то нам достаточно реализовать только метод chain, а реализация методов ap и map будут выведены автоматически.

  • @-Forever-Young-
    @-Forever-Young-12 күн бұрын

    Сразу лайк! Нет сомнений в качестве

  • @LeonidPolyakov

    @LeonidPolyakov

    12 күн бұрын

    Да, 100 процентов будет адекватно и информативно.

  • @vitalex9383
    @vitalex938311 күн бұрын

    Ролик вышел, как раз за час, до собеса. Решил быстро глянуть. И на собесе, спросили про функциональное программирование и функции высшего порядка. И я как выдал всю базу, которая есть в ролике, даже доп вопросов не задали😂. Спасибо Тимур за твой труд, за твои бесплатные и платный курсы.

  • @user-kw8cq6cd6y
    @user-kw8cq6cd6y12 күн бұрын

    Жду структурное программирование на Rust или Go))

  • @nikitatimofeenko9351

    @nikitatimofeenko9351

    8 күн бұрын

    Поддерживаю, ждем структурное программирование с примерами и на Rust и на Go

  • @user-yq6vo5vb9p

    @user-yq6vo5vb9p

    7 күн бұрын

    @@nikitatimofeenko9351 поддерживаю поддерживание, ждем структурное программирование с примерами и на Rust и на Go

  • @Michael-bf7pm
    @Michael-bf7pm12 күн бұрын

    Твой ролик про ООП был просто шикарен, поэтому я невероятно ждал видео про ФП! Спасибо большое, Тимур!

  • @UlbiTV

    @UlbiTV

    12 күн бұрын

    Спасибо! Жду фидбек))

  • @sidless3862
    @sidless386212 күн бұрын

    Вообще, когда только начинал изучение JavaScript, считал его именно функциональным языком. Да и по факту большую часть времени пишу в функциональном стиле, и люблю его больше чем ООП. По-моему на фронте в ООП пишут только Ангулярщики, но могу ошибаться. Спасибо за очень информативный ролик, как всегда лучший!

  • @midrala
    @midrala10 күн бұрын

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

  • @UlbiTV

    @UlbiTV

    9 күн бұрын

    Спасибо за такие слова ❤️🙏

  • @aliicomua1369
    @aliicomua136911 күн бұрын

    Спасибо за контент. Всё равно на какую тему ролик от этого автора, главное что 100% это будет полезно.

  • @user-uk1cu2hm2f
    @user-uk1cu2hm2f12 күн бұрын

    супер контент!!! ждал! спасибо за труд!

  • @ode2877
    @ode28775 күн бұрын

    Интересна штука особенно про монады, захотелось попробовать применять для избавления фигурных скобочек if error try catch и тд, единственное не хочется терять в производительности из за красоты, не знаю насколько v8 оптимизирует такие функциональные фокусы

  • @adelinaromanova8353
    @adelinaromanova835312 күн бұрын

    Лайк! 🎉

  • @user-rw3gf4te4e
    @user-rw3gf4te4e12 күн бұрын

    просто шикарно!

  • @user-dw8lb8lc7u
    @user-dw8lb8lc7u12 күн бұрын

    Спасибо ЮЛЬБИ!!! уникальный качественный контент

  • @konstantinsologub9568
    @konstantinsologub956812 күн бұрын

    Не понимаю как я не подписался на тебя раньше, хотя просматривал твои ролики до этого момента. Очень доходчиво объясняете и отличная дикция!

  • @UlbiTV

    @UlbiTV

    12 күн бұрын

    Спасибо!

  • @solovievss
    @solovievss12 күн бұрын

    Очень наглядное руководство по ФП! Разработчики, поделитесь опытом, может кто-то использовал ФП у себя в проектах? У меня дальше carry,compose,map в рамках ramda и lodash дело не пошло. С ts типизацией очень громоздкий код получался.

  • @user-yt9he6ud5r
    @user-yt9he6ud5r10 күн бұрын

    Фунцкиональный стиль в JS это богоугодное дело! Жду не дождусь когда в спецификацию JS добавят конвейерный (pipeline) оператор |>

  • @awenn2015

    @awenn2015

    6 күн бұрын

    Я лично жду когда в js добавят выражение по типу этого (выражение раннего выхода как в котлинине) const a = 5 ;((a: number) => { const b = a-5 || return false }) (a) Что бы не проверять ифами какую то тему и выходить в ифе

  • @Roger-qj4wu
    @Roger-qj4wu12 күн бұрын

    Спасибо, что продолжаешь давать нам ценный контент!

  • @tahrizade
    @tahrizade12 күн бұрын

    ждем - про Микросервери , микрофронтенд И так далее 😊

  • @falsetrue7910
    @falsetrue791012 күн бұрын

    Качество видео растет от ролика к ролику, смотрю почти каждый ролик и точно могу это сказать 😂 отличное введение в фп, но как ни крути, для полноценного фп надо писать не не js

  • @nikman5541
    @nikman554112 күн бұрын

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

  • @VolodymyrSirenko
    @VolodymyrSirenko12 күн бұрын

    Для меня очень полезное видео, спасибо!

  • @barbatage5078
    @barbatage507812 күн бұрын

    Сразу лайк не глядя! ❤

  • @barbatage5078
    @barbatage507812 күн бұрын

    Юлби, жги! Мы тебя любим 🫶🏼 каждый ролик долгожданный!

  • @helenit4365

    @helenit4365

    12 күн бұрын

    Да!!!✨️🌟🔥

  • @MAKS-FISHER
    @MAKS-FISHER6 күн бұрын

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

  • @sattorerror
    @sattorerror12 күн бұрын

    безусловно лайк!

  • @nk_77777
    @nk_7777712 күн бұрын

    Лайк со старта)❤

  • @user-zb3fy2je8b
    @user-zb3fy2je8b12 күн бұрын

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

  • @Sershir
    @Sershir12 күн бұрын

    Спасибо

  • @eunicsi
    @eunicsi12 күн бұрын

    Лайк и комментарий для продвижения автоматически, спасибо!

  • @ammoney159
    @ammoney15912 күн бұрын

    Хороший видос, апдейт по монтажу хороший, спасибо

  • @kowkavn2356
    @kowkavn235611 күн бұрын

    Лайк однозначно, коммент для продвижения, и вопрос по другой теме - снимаешь разбор Rx.js? Могу ошибаться, но она в стиле фп вроде. И как продолжение темы, или в принципе для расширения кругозора интересно услышать твое мнение и опыт в ней.

  • @musicthreads
    @musicthreads12 күн бұрын

    Лайкос тебе, дружище, за работу!

  • @WinchesterD
    @WinchesterD12 күн бұрын

    Круто, спасибо за видео! 👍

  • @psycho0sis
    @psycho0sis12 күн бұрын

    очень интересно, спасибо!

  • @samiracle9852
    @samiracle985212 күн бұрын

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

  • @alexsibrin715
    @alexsibrin71512 күн бұрын

    Дай бог тебе здоровья мужик

  • @Feniks20000
    @Feniks2000011 күн бұрын

    Спасибо за ролик, как всегда, качественно и наглядно

  • @user-gd4vi6fv1z
    @user-gd4vi6fv1z10 күн бұрын

    Это ОЧЕНЬ классный ролик, спасибо огромное! действительно, ни где не встречала так четко структурированной информации.

  • @yohohowowowo9471
    @yohohowowowo947112 күн бұрын

    О, это для меня! Я, конечно, не программист, но иногда приходится писать код, причём в основном на Лиспе или VBA, где ООП не реализовано. И именно в Лиспе, функции - это основной и довольно мощный инструмент. Из-за специфики кода, при написании программы, сначала приходится прописывать все функции последовательно от самого высокого уровня вложенности до самого низкого.

  • @miRorshik
    @miRorshik3 күн бұрын

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

  • @Vadym_Lantukh
    @Vadym_Lantukh11 күн бұрын

    Дуже чудовий розбір, мені як новачку дуже пізнавально

  • @yakut54
    @yakut5412 күн бұрын

    Феноменально! Как и всегда. Снимаю шляпу!

  • @lolimon58
    @lolimon5812 күн бұрын

    Лайк префом. btw я scala разраб

  • @alexstepanchhuk683
    @alexstepanchhuk6837 күн бұрын

    Как всегда супер-годный контент!!!! Спасибо!

  • @n1kaka
    @n1kaka12 күн бұрын

    Сразу лайк и коммент, огромное спасибо за видео😊

  • @kristinavolk2660
    @kristinavolk26606 күн бұрын

    Спасибо огромнейшее за тонкость и глубину контента. Заставляет явно провернуться шестеренкам в голове 🤓 со шлейфом, что что-то понял )) Эстетично и со вкусом 🌹 считывается, что ты в теме не просто шаришь, знаешь концепции, но ещё и Чувствуешь 💛 гармонично ориентируешься, но и подставляешь себя под критику, чтобы динамически расширить познание и критического мышления, развить его живость, эластичность и остроту. Редкость. Ценно 🫶🏻

  • @HaywasterChannel
    @HaywasterChannel9 күн бұрын

    Блин, я искал буквально 3 дня назад видео по сравнению парадигм ООП и ФП, не нашел. И тут бабах! Очень кстати) Спасибо большое, Тимур!

  • @vetero4eg
    @vetero4eg4 күн бұрын

    Уникальный Ulbi, спасибо! Как всегда, очень крутой контент.

  • @03Rai
    @03Rai10 күн бұрын

    благодарю ♡. топчик 😍

  • @user-fw1ws8lr8n
    @user-fw1ws8lr8n5 күн бұрын

    Очень круто и информативно! Спасибо ♥️

  • @skyranor6854
    @skyranor68549 күн бұрын

    Спасибо за труд!

  • @KaHcTpykTap
    @KaHcTpykTap12 күн бұрын

    Посмотрю потом, лайк поставил.

  • @LenaFelica_songwriter
    @LenaFelica_songwriter11 күн бұрын

    Супер, супер, супер !! Спасибо❤

  • @user-hu1gl5lw3p
    @user-hu1gl5lw3p12 күн бұрын

    вижу новый видос ставлю лайк

  • @tesohi
    @tesohi12 күн бұрын

    Господи, это превосходно! Я столько знаний получил с этого, мега круто! Причем как знаний по ФП, так и много-много знаний по js и лучшему пониманию того что происходит. А ещё мемоизация это лучший пример замыкания🤩 Тимур, это превосходно, ваш курс стоит покупки более чем! 💯💯💯

  • @nabijonazamov3695
    @nabijonazamov3695Күн бұрын

    Good mentor

  • @talantasanov4973
    @talantasanov497312 күн бұрын

    видео топ(пока не смотрел, но знаю это))

  • @inriinriinriinriinri
    @inriinriinriinriinri10 күн бұрын

    Качество визуализации стремительно растёт! Куда приятнее и легче смотреть на анимации в красивых цветах, чем на скриншоты где что-то непонятное написано от руки) Очень интересный урок! Спасибо!

  • @abylaev8233
    @abylaev823312 күн бұрын

    like

  • @Bespokerug
    @Bespokerug12 күн бұрын

    Спасибо за твои труды! Не мог бы ты сделать подобный ролик про паттерны проектирования?

  • @UlbiTV

    @UlbiTV

    12 күн бұрын

    В todo есть такой ролик

  • @vasil_astrov
    @vasil_astrov5 күн бұрын

    Оч круто, спасибо! Благодарю

  • @user-hy4qw4ki3o
    @user-hy4qw4ki3o10 күн бұрын

    Привет! Видео класс! Подскажи где ты рисуешь видеоряд? Слайды и т.д.

  • @Aristockij
    @Aristockij11 күн бұрын

    это что хоть такое-то? я неделю всасывал урок по вебпаку и тут нннныа и еще один видос подъехал! мне хотя бы половинку такой продуктивности

  • @awenn2015
    @awenn20156 күн бұрын

    2:32 Я хоть и давно в вебе (3 года в js) но последние 5 пунктов вообще хз что это такое, как будто из ассемблера что то)) Хотя посмотрев ролик понимаешь что рано или поздно с опытом даже не зная этих заумных терминов сам приходишь к декларативности

  • @user-zk3bc1lf8k
    @user-zk3bc1lf8k12 күн бұрын

    Лайк!!!!

  • @itproust
    @itproust12 күн бұрын

    Топ)

  • @Ramosok
    @Ramosok12 күн бұрын

    Огнище огненное!! супер контент! спасибо!

  • @olg3089
    @olg308912 күн бұрын

    Вот это тема

  • @Kysok410
    @Kysok41011 күн бұрын

    Спасибо большое Тимур Супер полезный и интересный ролик :) Долго тупил на функции каррирования, но в итоге разобрался)

  • @givename48
    @givename4810 күн бұрын

    Может для фана, ролик по Backend серверу на Haskell? Отличное расширение кругозора! (я просто адепт Haskell)

  • @VolodymyrChernigiv1300
    @VolodymyrChernigiv130011 күн бұрын

    Ого, нічого собі, оце крутяк. За такий контент треба донатить

  • @user-wu8zt4we5n
    @user-wu8zt4we5n12 күн бұрын

    А ты видел nodejs со встроенным gpt? Такой забавный Франкенштейн, но выглядит круто: переход к коду программы на человеческом языке!

  • @grigoryveynin8553
    @grigoryveynin855310 күн бұрын

    Спасибо за ролик! Я не специалист в ФП. Понравилось объяснение функторов и монад. Кажется мир ФП может много чего интересного принести в решение рутинных задач)

  • @adnike7013
    @adnike70136 күн бұрын

    очень интересно, спасибо за видео , познавательно!

  • @vladb3449
    @vladb34495 күн бұрын

    Круто, спасибо за урок, чувствуется хорошая экспертиза!

  • @user-nh8um2dn9s
    @user-nh8um2dn9s10 күн бұрын

    Спасибо за информацию. Довольно интересные подходы. И понимания в этом направлении стало побольше. :)

  • @user-pw6gz6jh3i
    @user-pw6gz6jh3i12 күн бұрын

    наконец-то достойная тема)

  • @user-frond-end_dev
    @user-frond-end_dev12 күн бұрын

    Карта развития или учебы для самостоятельного изучения есть у тебя?

  • @yggllen
    @yggllen11 күн бұрын

    В целом интересная теория, но со стороны большого опыта работы на Java с StreamApi, Function, Optional, Consumer и тп. в JS вся эта структура кажется сложнее, хотя плюс минус тоже самое. Для меня самое сложное было понять как работают кастомные хуки в реакте, как я понимаю это также все выходит из ФП, но так как в java нет прямой аналогии для меня это выглядело как магия

  • @some_body_qtyeeuy
    @some_body_qtyeeuy9 күн бұрын

    Благодарствую!

  • @crap2680
    @crap268011 күн бұрын

    Хорош, братан, контент в кайф, давай еще, ваще красавчик, можно вот этого вот почаще?

  • @user-dn4ry3uw8i
    @user-dn4ry3uw8i12 күн бұрын

    Вижу новое видео, ставлю лайк

  • @yarosav5396
    @yarosav53968 күн бұрын

    следующий шаг, это после этого псевдообьяснение монад и функторов, это объяснить дайрект стайл, алг эффекты и континуации

  • @victormog
    @victormog12 күн бұрын

    Видео - просто бомбическое! Может развить его плейлистом с более конкретными и практическими примерами?..

  • @user-tb5tp2tv6x
    @user-tb5tp2tv6x12 күн бұрын

    Спасибо Круто!!! Ждём nextjs 14 версию))

  • @larrybluesky
    @larrybluesky12 күн бұрын

    Perfect !

  • @andrewkruchini8614
    @andrewkruchini86147 күн бұрын

    Отличное изложение. Только много опечаток. На 37:37 не выдержал.

  • @blatov
    @blatov12 күн бұрын

    🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰🥰

  • @dmitriynemkov1380
    @dmitriynemkov138012 күн бұрын

    В какой программе презентацию делаешь?

  • @user-lf5kk3bx9p
    @user-lf5kk3bx9p6 күн бұрын

    Спасибо!!!

  • @user-wl2ok2mf6n
    @user-wl2ok2mf6n9 күн бұрын

    Как же ты хорош!

  • @awenn2015
    @awenn20156 күн бұрын

    44:55 у меня вопрос, как типизировать такие каррированные функции? Тупо возвращать function и результат?

  • @user-sc5qy2zw9s
    @user-sc5qy2zw9s12 күн бұрын

    Можно ли считать reducer чистой функцией, если у него дефолтное значение - переменная, определенная выше

  • @UlbiTV

    @UlbiTV

    12 күн бұрын

    Можно) это аргумент, такой же, просто с дефолтным значением, на чистоту не влияет

  • @romanb7486
    @romanb748611 күн бұрын

    клааааааааааааааааааааааааааааааааасс

  • @user-on4lv7lc9k
    @user-on4lv7lc9k6 күн бұрын

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

  • @TheArkan777
    @TheArkan77712 күн бұрын

    15:18 5 * 5 * 5 = 125

  • @404Negative

    @404Negative

    11 күн бұрын

    он же об этом и говорит, что MODIFIER могут поменять. неужели это не очевидно ?

  • @ada280202
    @ada28020212 күн бұрын

    На 50:45 разве g и f справа от знака равенства не перепутаны?

Келесі