Это же касается и остальных концептов FP. Я понимаю их ценность, как ими пользоваться. Но я не знаю, как это донести до людей, которые изначально настроенны негативно к функциональному подходу. Не думаю, что это вообще возможно. Практика легко решает это дело, но до неё у людей редко доходят руки.
Я даже не знаю, как ответить на более простые вопросы. Несмотря на то, что пишу на Scala больше 3 лет, я не могу на пальцах объяснить преимущества языка для человека извне. Например, пару месяцев назад мне довелось провести не лучшую дискуссию.
Всё началось с вопроса: “А для кого вообще ваш язык написан?”.
В моей голове вертелись все эти иммутабельности, функции высшего порядка, великая система типов, сайд-эффекты и прочие монады, но я понимал, что это всё не то. Последовавшее уточнение окончательно отправило меня в нокаут: “Вот, например, Java – это язык для белых воротничков”. Тот диалог закончился какой-то несвязной ахинеей про невозможность объяснить разницу без практики.
Мы не умеем продавать FP
Это не просто пересказ личного опыта. Все мы, пользователи функциональных языков, находимся примерно в идентичной ситуации. Мы прекрасно понимаем огромную разницу в сравнении с Blub языками, но остальной мир не хочет нас слышать. Конечно, можно злиться на ограниченность консерваторов, которые хавают “Г”, преспокойно несут чушь, пересказывают друг другу мифы и сказки, твёрдо и уверенно вступают в дискуссии о вещах, на которые даже пары часов не потратили. Можно также винить огромные корпорации с их отрядами маркетологов.
Но мне кажется, в первую очередь, проблема в том, что мы сами не умеем продавать FP. Да, это нелегкая задача. Хотя, когда я вспоминаю, как люди принимают решения, как и какие вещи входят в тренды, то начинаю думать, что это возможно.
В разработке всегда что-то не так.
- Процессы медленные! И вот уже через несколько лет каждое утро, во всех офисах страны люди, стоя у доски, перетаскивают стикеры из одной колонки в другую.
- Деплой медленный! И вот вооруженные ценностями devops, мы делаем по 10 релизов в день, в то время как новое поколение админов заливают это тоннами ruby, python и yaml.
- Приложения сложные! И вот команды в 2-3 разработчика сооружают новую микросервисную архитектуру, детально продумывая ответственности каждого сервиса и делая по 10 пул-реквестов на одну маленькую правку.
Не то чтобы я считал все эти повальные увлечения в индустрии плохими. Просто у них тоже есть немало недостатков. И не все умели или умеют их правильно готовить. Отсутствовал или отсутствует удобный тулинг. Тем не менее, эти подходы стали “де-факто” стандартными для индустрии. И хотя обсуждения про docker в продакшене для некоторых кажется еще не закрытым вопросом, всё уже произошло.
Я уверен, то же самое может произойти и с функциональными языками. Да, это не совсем корректно – сравнивать языки программирования с методологиями и подходами. Но нам есть что позаимствовать в их позиционировании для себя. У всех них есть строго определённая проблема, которую они решают. И это скорость: разработки, коммуникаций, планирования, деплоя, внесения изменений…
Почему мы забываем сказать о самом главном?
В тоже время, с точки зрения позиционирования функциональных языков программирования, сложно сказать что у них есть четкая и понятная цель. Языкосрачи “FP vs OOP” обычно быстро скатываются в мерянье фичами и концептами, ценность которых мало понятна OOP-лагерю. Статьи и доклады формата “Вы посмотрите, как эти монады великолепно композируются” чаще закрепляют в людях мнение, что это им не нужно, чем вдохновляют попробовать. Все эти взаимодействия, крайне редко отвечают на вопрос “А зачем это все?”. Красиво и лаконично? Ну в лучшем случае будет упомянуто о меньшем количестве ошибок.
Самое главное в использовании функциональных языков есть та же самая скорость разработки! И эта скорость достигается вот этими всеми скучными и пугающими терминами, концепциями и свойствами, выходящими из них. Более легкая композиция за счет функций высокого порядка – плюс к скорости разработки. Иммутабельность, помимо надежности и меньшего количества ошибок, равнозначна тому, что даёт больше времени на полезные вещи, вместо траты его на отладку, хотфиксы и поддержку. Ну и так далее, думаю, логика понятна.
Да, это звучит слишком просто и даже очевидно.
Да, я тут вообще не сказал ничего нового. Но важность формулировки и акцентов важна. К сожалению, так уж устроено наше мышление. Для того, чтобы рушить барьеры, одних объяснений недостаточно. Нужна практика! Необходимо, чтобы человек или компания захотели потратить на это время. Отсылки к “академичности” или к относительной красоте мало кого вдохновят провести несколько дней, чувствуя себя идиотом.
Стоит перестать строить из себя умников, сходу раскидываясь терминами направо и налево, доказывая превосходство своего любимого ЯП над Blub. Вместо того, чтобы доказывать полезность фичи X, гораздо проще ее использовать как объяснение какого-то более понятного свойства. Если это получилось у других техник, возможно, нам тоже пора уже взять на себя ответственность и твёрдо заходить с очевидных и простых вещей.
Так что в следующий раз при сложностях ответа на вопрос "А зачем?" не стесняйтесь заходить с козырей, таких как: более высокая скорость разработки, более дешевая поддержка, меньшее количество разработчиков.
Ах, и еще. Ивенты для сообществ тоже играют не малую роль в позиционировании!
Поэтому, мы ждем всех неравнодушных к FP на единственной функциональной конференции в России — FPURE — Казань — 24-25 мая.
В программе: Haskell, Scala, Elixir, Clojure, теория и практика, и конечно же много единомышленников с кем найдется о чем поговорить!
Комментарии (95)
muhaa
30.04.2019 16:50+5Я не знаю, как это сделать и не могу представить, как бы я, например, из настоящего мог бы объяснить это себе из прошлого.
Вот здесь чуть больше чем за час физик сумел объяснить что такое бозон Хигса людям, не знающим физику. При наличии кристально четкого понимания предмета можно объяснить кому угодно что угодно. Нужно просто последовательно описать область применения, круг решаемых проблем и собственно способ их решения.red75prim
30.04.2019 21:07+1А они потом смогли сделать свой бозон Хиггса? Или хотя бы сечение рассеяния на электроне посчитать? Программистам приходится.
muhaa
01.05.2019 09:52Задачи не сопоставимые по сложности кстати. В концепциях программирования может самостоятельно разобраться любой школьник. Проблема только в том чтобы научиться эффективно их применять. Физику хоть до пенсии изучай, все равно будешь дилетантом во многих областях.
red75prim
01.05.2019 10:40Да, но это — в любом случае сложнее, чем сказать: «Как вы здорово всё объяснили, я понял». С теми же монадами тоже не так всё просто — им соответствует множество концепций, на первый взгляд никак не связанных: вычисления на списках, передача состояния, ввод/вывод и т.д.
Пользоваться конкретными реализациями монад просто, но понять что такое монада и начать замечать, что вот эти элементы предметной области с таким-то операциями являются монадой, намного сложнее.
Переизобрести монаду или другую математическую абстракцию, заметив, что совершенно разнородные объекты и операции подчиняются одним и тем-же аксиомам, большинство (включая меня) скорее всего не сможет.
ksbes
30.04.2019 16:58+3Сразу хочу сказать — тезис поддерживаю. Статья понравилась, хотя и коротковата. Хотелось бы более развёрнутого ответа:
Так что в следующий раз при сложностях ответа на вопрос «А зачем?» не стесняйтесь заходить с козырей, таких как: более высокая скорость разработки, более дешевая поддержка, меньшее количество разработчиков.
Простые констатации меня, ярого ООПшника не убедят. Я не вижу более высокой скорости разработки. Не вижу более лёгкой поддержки. Малое количество ФПшиков — вижу. Но это скорее недостаток, чем достоинство.
Разработка — это же не простое кодирование. В нормальном процессе разработки сначала идёт понимание, выраженное в документе. Сначала идёт описание. Текстовое. Устно или письменно. И лишь потом код.
И, как показывает практика, выражать свои мысли, обмениваться ими, пользуясь терминологией и подходом ООП — просто. Понятно даже тем, кто не знает ООП. Собственно под «естественное понимание человеком» этот подход и разрабатывался.
А ФП теряет своего слушателя уже на втором использовании слова «морфизм» и на первом использовании слова «функтор». Я слабо себе представляю как люди проектируют рабочие системы пользуясь диаграммами из теории категорий в техническом задании. (для тренировки попробуйте нарисовать подобное для простейшего веб-сервера, умеющего разбирать пути)
А раз люди друг друга не понимают — то о какой скорости разработки может идти речь? О какой поддержке?
LMnet
30.04.2019 17:46+3А вы случаем не путаете "просто" и "знакомо"? Проектирование систем в фп стиле не означает, что система проектируется с использованием таких штук как "функтор" или "монада". Это проектирование, в котором иммутабельные данные проходят через ряд преобразований внутри функций. А функторы и монады — это уже детали реализации. Фп никаким образом не влияет на возможность людей договориться. Это просто немного другой подход. И, более того, на практике он не сильно отличается от тех же ооп best practices.
ksbes
30.04.2019 18:09+1Не путаю.
Если система (например, банковский биллинг) строится на ООП, то она должна и описываться в терминах ООП в документации. Если строится на ФП, то и описываться должна в терминах ФП (вот у нас есть морфизм из HTTP запроса в HTTP ответ, который является ...). Иначе это _не_ программирование на ФП.
Ещё раз повторяю: разработка — это не просто по клавишам потыкать. Если не можешь на бумажке со стрелочками объяснить как оно работает, то это коддинг в самом плохом смысле этого слова.
И мой вопрос как эти стрелочки выглядят для программы на ФП?LMnet
30.04.2019 18:15+2Точно так же, как и для ооп.
Я открою вам страшный секрет — из одной и той же "архитектуры на листочке" можно сделать программу как в фп стиле, так и в ооп. Никто не проектирует "морфизмами".
solver
30.04.2019 20:05Никто не проектирует «морфизмами»
Это вы так думаете)
А адепты ООП, ничего кроме ООП не видели. И «проектируют» архитектуру объектами.
И в документах описывают объекты. И думают, что все так делат. Потому, что их большинство и ничего другого они во круг не видят… Да и желания у них посмотреть как можно по другому, то же нет. Вот и получается замкнутый круг…areht
02.05.2019 21:16А где смотреть то?
Я сколько статей про ФП вижу — там про функторы и монады. Как будто и правда никто ничего не проектирует.
Ну вот я возжелал посмотреть, открываю вики ООП, вижу раздел «Проектирование программ в целом»
ООП ориентировано на разработку крупных программных комплексов, разрабатываемых командой программистов (возможно, достаточно большой).
Открываю соседнюю вики ФП и вижу вместо него «Стили программирования» с
Императивные программы имеют склонность акцентировать последовательности шагов для выполнения какого-то действия, а функциональные программы к расположению и композиции функций, часто не обозначая точной последовательности шагов.
Чувствуете пропасть между интересами писавших это людей? Наверное, в ФП тоже кто-то проектирует, но продавать все пытаются функторы, монады и примеры на 2 строчки:
# функциональный стиль # языки ФП часто имеют встроенную функцию compose() compose2 = lambda A, B: lambda x: A(B(x)) target = map(compose2(F, G), source_list)
graninas
03.05.2019 12:45+1Вот, смотрите, я пректирую (и пишу книгу про это):
www.patreon.com/functional_design_and_architecture
Монады там тоже есть.areht
04.05.2019 07:30Спасибо, интересно было полистать. Жаль только половина книги, тема TDD не раскрыта.
Но в целом, та же фигня: много низкоуровневого описания возможностей, а чуть выше — ну, типа, сами придумаете.
> In FDD methodology, brainstorming is the preferred method for gaining a deep understanding of things.
Больше похоже не на руководство по архитектуре/методологии, а на сборник полезных советов и паттернов.
PS. «if we don't have a bird’s-eye view of the software we are going to create, how can we make architectural decisions?» — Как обычно: как можем, так и решаем. Потом переделываем. А что, у вас бизнес-требования не меняются вплоть до переписывания с нуля?
JC_IIB
30.04.2019 21:42Мне в этом плане понравился ответ Druu в одном из давних постов graninas, цитирую полностью:
«Ну вам чтобы использовать абстрактную фабрику требуется знание какой-то особенной теории? Думаю, нет. Так и с монадами/функторами — смотрите на это как на определенный интерфейс, который предоставляет определенные возможности.»
Так же и здесь. Никто не пишет «а вот тут абстрактная фабрика будет генерировать… что-нибудь».
trix
30.04.2019 21:18Вы каждый if будете описывать на бумаге? Например, в Яве8 наконец-то появились лямбды и стримы, и народ их начал вполне эффективно использовать, ибо давно наболело. Это самое что ни на есть ФП (\шёпотом\ и даже с монадами, хотя большинство разработчиков даже не знают, что они используют монады), просто ООП это тоже не отменило.
muhaa
01.05.2019 10:20Если система (например, банковский биллинг) строится на ООП, то она должна и описываться в терминах ООП в документации.
ИМХО ФП — это прежде всего метод, позволяющий совладать с очень сложными алгоритмами (сложными алгоритмически а не в смысле количества внутренних интерфейсов и бюрократических процедур, которым алгоритм должен поклониться). Это могут быть алгоритмы для некого принятия решения, оптимизации. Условно говоря, это когда функция получает на входе простой запрос и доступ на чтение к доменной модели, выполняет алгоритм на несколько тысяч строк и возвращает простой ответ. В подобных случаях преимущества ФП бесспорны: четко видно что принимает и выдает каждая часть кода, нет необходимости изобретать кучу странных классов, нет проблем с много-поточностю, хранение промежуточных данных в имутабельных структурах итоге проще, чем в каких-то запутанных временных объектах. Если же проектировать нечто вроде биллинговой системы, то это все равно будет много взаимодействующих компонентов и общая схема системы будет одинаковой для проекта на ООП и на ФП.
graninas
30.04.2019 18:08> А ФП теряет своего слушателя уже на втором использовании слова «морфизм» и на первом использовании слова «функтор». Я слабо себе представляю как люди проектируют рабочие системы пользуясь диаграммами из теории категорий в техническом задании.
Не бывает такого. Не оперируют этими словами во время проектирования. Оперируют обычными терминами: подсистема, интерфейс, имплементация. Потом думают, какие технологии можно применить: FRP, STM, монады. Может, достаточно функций и алгебраических типов данных. Никто из известных мне хаскеллистов в продакшне не проектирует на теории категорий.ksbes
30.04.2019 18:15Подсистема, интерфейс, имплементация — это термины ООП. И если люди их используют, то они программируют на ООП, хоть и кодят в ФП. Тогда и не надо говорить о «программировании на ФП». Тогда и понятен провал — на раскоряку сидеть неудобно.
graninas
30.04.2019 18:28+3Вы глубоко неправы. Это не термины ООП. Это универсальные термины, не связанные с парадигмой или технологиями.
knotri
01.05.2019 13:33интерфейс ~= контракт ~= сигнатура ~= типы параметров функции
имплементация = реализация
подсистема = подсистема (хмм, лол)
как это относится к ООП???
sshikov
30.04.2019 18:31>Простые констатации меня, ярого ООПшника не убедят. Я не вижу более высокой скорости разработки. Не вижу более лёгкой поддержки. Малое количество ФПшиков — вижу.
Ну, мы верим. Собственно, текст об этом — что надо лучше продавать. Надо подать так, чтобы вы увидели.
Я вот вижу слегка другое. Например, ФП в Java-сообществе довольно долго было «на задворках». Кто знает, что была и есть такая штука, как functional java, существующая очень давно? Да почти никто пожалуй и не знает. Зато с появлением Java 8, где некоторые части ФП стали частью языка, вот это вот все, скорость разработки, легкая поддержка — они видны всем, кто вообще хоть как-то интересуется. Яркий пример — то, как преобразились широко известные паттерны ООП с появлением функций в таком виде, что с ними стало реально удобно работать.
Они видны всем, кто работает и с такими вещами, как Spark. Хотя да, было бы очень неплохо не просто сказать «а я это вижу», но и померять.
Насчет ФП как способа выражения своих мыслей — ну это хорошее замечание, хотя вам уже пару раз ответили, что никто не проектирует системы в терминах аппликативных функторов. Кстати, я сильно сомневаюсь, что вы сможете также адекватно спроектировать систему в терминах ООП для любого произвольного применения.
И про диаграммы вы кстати зря. В развитых языках типа хаскеля, с возможностью расширения набора операций, некоторые манипуляции над диаграммами как раз замечательно отражаются в код. Вплоть до стрелочек.pin2t
01.05.2019 17:43Насчет ФП как способа выражения своих мыслей — ну это хорошее замечание, хотя вам уже пару раз ответили, что никто не проектирует системы в терминах аппликативных функторов. Кстати, я сильно сомневаюсь, что вы сможете также адекватно спроектировать систему в терминах ООП для любого произвольного применения.
Для любого произвольного и не надо, системы проектируются под конкретную клиентскую задачу. Система для любого произвольного применения — ОС. Только надо сначала программу написать :) а так любую задачу решает.
Не бывает абстрактных задач, все задачи конкретные.sshikov
01.05.2019 20:53Так я и хочу сказать, что ООП не панацея для любой задачи. Какие-то задачи на нее неплохо ложатся, а какие-то приходится как сову на глобус.
TheShock
02.05.2019 03:22а какие-то приходится как сову на глобус.
Какие к примеру?red75prim
02.05.2019 08:00Библиотеки линейной алгебры, например. Иерархия чисел (целые, с плавающей точкой, комплексные и т.п.).
sshikov
02.05.2019 09:05Из того, что мне лично попадалось недавно, это пожалуй интеграционные задачи разного рода. Их обычно описывают в терминах так называемых EIP (enterprise integration pattern), которые сами диаграммы, и на ООП они ложатся так себе. Не то чтобы их нельзя было в таких терминах описать — а просто пользы от такого описания не будет, и реализация обычно не в этих терминах все равно.
При этом описание другого бизнес-проекта почти на 100% состояло из одной здоровой ER-диграммы, и все отображалось в объекты и манипуляции с ними.
pin2t
02.05.2019 11:38А я как раз про то что в большинстве задач ООП рулит, потому что большинство задач не про то как красиво вычислить числа фибоначи, или очень круто параллельно умножить каждый элемент массива на 2. Большинство задач про то как провести платеж пользователя, передать сообщение в чат, сохранить файл на диск, показать видео в окошке. И в них всех гораздо лучше подходит ООП.
sshikov
02.05.2019 11:56Ну, я в штуках не считал, поэтому про большинство говорить не стану. У меня — где как, в последних проектах на спарке от ООП по большей части тоже рожки да ножки.
Платежи и формочки — да, это как раз случаи, когда бизнес задачи на ООП нормально ложатся. Ну и скажем так — по сравнению с тем, что было до ООП, это несомненно был шаг вперед в плане организации кода.
nlinker
02.05.2019 19:29+2Описать с помощью ООП как корова щиплет траву (там будет
корова.щипать(трава)
,трава.бытьОщипанной(корова)
илиПрирода.поедание(корова, трава)
?).
Есть лужа (совсем необязательно являющаяся сечением шара), в лужу бросили камень (вектор скорости совсем необязательно перпендикулярным поверхности). Задача: описать поведение волн с течением времени. Вот здесь бесполезность ООП лично для меня очевидна — задача поставлена, есть необходимость её решать, но ООП здесь совершенно никак не вклеивается — можно конечно создать классы "Лужа" и "Камень", и описать метод "взаимодействовать", но это даже на миллиметр не приблизит нас к моделированию действительности.
PS: А приблизит нас тоненькая брошюрка "Введение в динамику жидкости" товарища Бэтчелора и такая же тоненькая "Вычислительная математика" Тихонова+Самарского. В первой книжке мы найдём как выписать систему уравнений Навье-Стокса для нашей лужи, а во второй книжке мы найдём методы, как решать системы диффур численно. Покроем лужу достаточно мелкой сеткой, напишем алгоритм числнного решения (с прицелом на кластер) и вот тогда мы приблизимся таки к моделированию нашей действительности. И тут — о чудо — появятся объекты, да. Например, vector, matrix, обёртки над сокетами и тому подобные технические сущности. Причём набор этих сущностей будет существенно зависеть от выбранного способа решения. Однако куда делись лужа с камнем?
pin2t
02.05.2019 19:49Лужа с камнем никуда не делись, камень изменил свои координаты и теперь лежит в луже. Просто Ваше внимание переключилось с лужи и камня на волну, которая возникла на поверхности лужи, для описания формы которой Вы читаете Бэтчелора, Тихонова+Самарского и составляете систему уравнений Навье-Стокса.
pin2t
02.05.2019 19:591, 2. Вы просто как, видимо, функциональщик, акцентируете внимание на действиях, «щипать» и «бросать». НУ в этом смысле да, если «не замечать» объекты, то как бы их и нет :) есть только «функции».
leon_nikitin
02.05.2019 20:24Вообще-то, программирование — это составление программ, т.е. алгоритмов (описания действий). ОПП, ФП, Структурное программирование и т.п. и т.д. — это все о том, как декомпозировать программу (алгоритм). На какие части и как. О том, как сделать кирпичики, чтобы из них собрать программу (алгоритм).
Описание требований и т.п. — это не программирование. И тут ООП не причем. Декомпозиция и описание ИС — это не совсем про программирование, т.е. написания программы.
TheShock
02.05.2019 20:46Описать с помощью ООП как корова щиплет траву (там будет корова.щипать(трава), трава.бытьОщипанной(корова) или Природа.поедание(корова, трава)?).
Ну такой глупый пример и в обратную сторону сработает. На ФП как? Так?
новаяКорова = кушать(стараяКорова, трава)
Или, может так:новаяКорова = кушать(трава, стараяКорова)
Что будет, если я передам траву тигру?новыйТигр = кушать(трава, тигр)
Можно ли так?
новыйТигр = кушать(корова, тигр)
Сработает ли тогда так?
корова3 = кушать(корова1, корова2)
solver
02.05.2019 21:00+1Очень корявое передергивание…
Вы пытаетесь глупыми, за ранее корявыми примерами сместить фокус обсуждения с абсолютно корректного вопроса проектирования в ООП в плоскость семантики конкретного языка.
P.S. Если писать на JS, то все ваши вопросы открыты и ответы зависят от компетенции разработчика. Если писать например на Haskell, то большинство ваших примеров просто не скомпилятся ввиду несоответсвия типов.TheShock
02.05.2019 21:15Я же сразу сказал — это глупый пример в ответ на глупый пример. Вам ваш пример не кажется глупым потому что вы — фанбой. Вся критика ООП кажется глубокой и остроумной, как та глупость с паттерны-против-функций
И вопрос не в семантике. Как бы вы не писали эти примеры — вопрос остается тот же.nlinker
03.05.2019 12:42Да в том-то и дело, что проблемы подобные коровам и траве в реальных проектах встречаются повсеместно, и разработчики далеко не всегда выбирают нужный класс удачно (это во многом зависит от ответственностей, которые навешивают на классы впоследствии). Кроме того, есть много ошибок, связанных с компромиссом "богатый интерфейс + удобство использования vs минималистичный интерфейс + удобство реализации". SOLID опять же, понятие "single responsibility" может варьироваться в широких пределах в зависимости от конкретного человека и его понимания — что для одного single, для другого — multiple.
Теперь как решать указанную задачу в Хаскеле например:
eat :: Cow -> Grass -> Cow eat cow grass = ... newCow -- да, вернём новую корову
попытка подсунуть траву тигру, или траве корову закончится ошибкой от компилятора. Если же так получилось, что мы вынуждены использовать функцию
Grass -> Cow -> Cow
, а нам удобноCow -> Grass -> Cow
, то это делается одной строчкой:
-- используем HOF flip :: (a -> b -> c) -> b -> a -> c eatFlipped = flip eat
Если вам будет угодно, можете
flip
считать паттерном "Адаптер" на кончиках пальцев (а кроме этого есть ещё более легковесный карринг), её можно определить локально, как только она где-нибудь понадобится.
В любом случае, мне не пришлось решать дилеммы выше (куда приклеить функциюeat
, достаточно ли Single Responsible полученная Корова или Трава, и нужно ли добавлять методsize
в корову или и так сойдёт (ведьsize
можно посчитать просто как сумму частей!).
trix
30.04.2019 21:30+2Простые констатации меня, ярого ООПшника не убедят. Я не вижу более высокой скорости разработки. Не вижу более лёгкой поддержки
И не увидите, скорость и простота поддержки зависят в куда большей степени от разработчика, а не от того, на чём он пишет. Тут можно было бы сказать «если нет разницы, зачем платить больше», но у нас есть отличный пример того, как сам ОО подход принимался индустрией. Сначала большинство разработчиков тоже не понимало, зачем так всё усложнять. А потом рост сложности проектов ярко показал выгоды.
ФП существует очень давно, но теперь его внедрение толкает вперед индустрия больших данных и параллельных вычислений, чем больше людей становятся знакомы с ФП-концепциями, тем больше они начинают находить им применение в самых разных областях, Так что лет через 10 говорить будут не «ФП даёт более высокую скорость/лучше поддержку», а «проекты такого уровня сложности никто уже давно не делает на голом ООП».
ppopoff
30.04.2019 17:25Как мне кажется, с задачей "Объяснить монаду" неплохо справился Миран Липовича в своей книжке с голубым слоном. Но в Scala, не используя scalaz/cats это сделать не просто, скажем так.
sergey-gornostaev
30.04.2019 19:56Пол Грэм ещё в 2001 всё необходимое сказал по этому поводу в статье "Побеждая посредственность".
dos65 Автор
30.04.2019 21:07Как раз ее и перечитывал перед написанием. Так что, возможно, получился своего рода трибьют.
С одной лишь разницей, что меня не устраивают его выводы. В отличие от Пола, у меня не появился и врядли появится свой стартап, чтобы преспокойно наблюдать за медленным мейнстримом и держать свое оружие в секрете.
bjornd
01.05.2019 11:16Люди постоянно упускают из виду что современная коммерческая разработка уже давно не про абстракции, ФП, ООП, etc. Она про взаимодействие между людьми. По ссылке пример успеха Пола Грэма с Viaweb написанном на Lisp'е и вроде как ставшим успешным как раз благодаря Lisp'у. Но это же полная чушь, Viaweb был куплен Yahoo! за $45m благодаря организационному таланту и инвесторской проницательности Грэма, а не благодаря Lisp'у. Сколько успешных проектов написано не на языках ФП, сколько проектов обвешаных монадами кануло в безвестности? Люди > технологии. Если вы можете найти команду отличных специалистов ФП среди которых не будет примадон занимающихся самообразованием вместо решения проблем бизнеса — отлично, вам повезло. Но в большинстве случаев вам придется делать проекты с теми разработчиками, которые есть на рынке.
sergey-gornostaev
01.05.2019 12:05Статья не про то, как Грэм продавал проект Yahoo!, а про то, как этот проект делался. Центральная мысль статьи о том, что команда проекта играючи душила конкурентов благодаря возможности легко и быстро изменять код, что в свою очередь было заслугой Lisp'а. Можно быть сколь угодно хорошим предпринимателем, но если инструмент зарабатывания денег не позволяет быстро реагировать на требования рынка, успеха не достичь. Многие современные тенденции в отрасли, упомянутые dos65 — гибкие методологии, DevOps, микросервисная архитектура — предназначены как раз для этого, как можно более быстрой реакции на требования рынка. И мы ещё не затрагиваем вопрос того, что стоимость поддержки существенно выше стоимости разработки, а ФП может помочь эти затраты снизить.
Я в целом согласен, что люди значат больше, чем технологии. Но и тут у ФП преимущество, если верить отзывам компаний, нанимающих clojure-программистов. Они заверяют, что Clojure стоило выбрать уже за то, что тот открыл им рынок высококачественных соискателей и возможность формирования превосходных команд. Впрочем, я думаю, что это связано с относительно высоким порогом входа и пока ещё низким спросом. Уверен, лет через 10 вероятность напороться на примадону будет одинакова как при найме джависта, так и кложуриста.sshikov
02.05.2019 12:13>Центральная мысль статьи о том, что команда проекта играючи душила конкурентов благодаря возможности легко и быстро изменять код, что в свою очередь было заслугой Lisp'а.
Наверняка же знаете такой анекдот: а я на машинке умею быстро-быстро печатать! Такая х-ня получается :) Я тоже могу код легко и быстро изменять, это всегда можно было, только проблема как правило не в коде.
У бизнеса (который обычно представляют аналитики) уходят месяцы на обдумывание. У поддержки уходят месяцы на то, чтобы обнаружить проблему. Разработчик меняет код за 15 минут.
Gorthauer87
01.05.2019 00:35+1Вообще справедливости ради ФП не отменяет ООП, он скорее противоположен императивному программированию.
sergey-gornostaev
01.05.2019 05:34
4lex1v
01.05.2019 01:06Спасибо за статью, надеюсь Вы не бросите попыток освоить глубины функционального программирования!
Нет, это не очередная попытка объяснить монады. Я не знаю, как это сделать и не могу представить, как бы я, например, из настоящего мог бы объяснить это себе из прошлого.
Могу предположить, что Вам неоднократно задавали похожий вопрос, интересно, что Вы отвечали?
Монады весьма забавная концепция, я до сих пор вряд ли смогу объяснить внутреннюю математику в рамках категорий, но с практической точки зрения всегда определял как абстракцию вычислительного процесса. Что такое вычисления понимают все, а абстракция просто говорит о том что мы описываем вычисления не вдваясь в детали контекста (происходит ли это асинхронно, есть результат или нет, может упасть с ошибкой или вернуть результат и т.д). Scala к сожалению скрывает суть за синтаксическими нагромождениями.
Касательно «А зачем это все?», я ответить Вам не смогу, но из моего опыта работы с функциональными языками и общения с ФП коммьюнити, я пришел к выводу, что для многих людей ФП является естественным отражением того как эти люди думаю, подходят к решению задач. Вопрос не в том хуже ООП или нет, это разные инструменты и, на мой взгляд, выбирать надо не с точки зрения скорости разработки, поддержки и т.д, а того с чем вам приятнее и удобнее работать, тогда, может быть, вопроса «А зачем это все?» стоять не будет.
vpatryshev
01.05.2019 08:32Чудесно!
По мне так ответ на эту загадку простой — эти люди сойдут со сцены, и придут те, кто «понимает монады». У нас в группе как-то с этим не видно проблем, например.
Я насмотрелся в жизни и страха перед фортраном, и страха перед си++, и страха перед джавой, и страха перед ООП, и страха перед ФП; теперь вот все баяцца монад. Ну пусть боятся; эти люди ж не вечно на арене. Придут те, что не боятся. map и flatMap для них естественная вещь. Я этих людей вижу каждый день.
Ну и монада не конец света, конечно. Линзы (и вообще оптика), свободные монады (я в них не верю, там нужно сохранение фильтрованных копределов), расширения Кана… жизнь идет. А «любители ООП» (можно подумать, они родились с ООП в голове) уйдут на пенсию, будут ныть там.amarao
01.05.2019 11:10Главная проблема «монады» в её названии. Что такое объект? Что-то, что можно взять, положить, посмотреть во внутрь. Что такое тред? Что-то, что вьётся, у чего есть продолжительность, начало и конец. Что такое pipe? На вход что-то, на выход оно же.
Простые, ясные, бытовые аналогии.
А теперь, какие бытовые свойства у монады? Например, быть непонятной.nlinker
01.05.2019 20:05> А теперь, какие бытовые свойства у монады? Например, быть непонятной.
Сохранение порядка эффектов независимо от способа вычисления (энергичного, параллельного, или какого-нибудь из ленивых — неважно)amarao
01.05.2019 21:04Это вы уже придумали. Откуда слово «монада»? Почему «это» решили назвать «монада», а не «сепулятор»? Очевидно, что все свойства сепулятора так же выполняются.
Я повторю, что для центрального объекта для программирования, использованное слово — катастрофа семантического масштаба.
Сравните с трейтами. Внутри — предикаты на типах. А снаружи? «черты характера, типаж». Мы хотим от структуры иметь такие-то черты характера. Блистательная аналогия.
А монады — семантическая бездна. Кто, вообще, притащил её в математику, откуда и чем объяснял?nlinker
01.05.2019 22:43То есть вас интересует просто этимология термина monad? Лично я не в курсе, но я уверен, это можно разыскать, было бы желание.
Я бы предпочёл вести более содержательную беседу, чем спор о терминах.
Монада для разработчика на Haskell, например, имеет вполне конкретный смысл безо всяких аналогий (это тайпкласс вместе с требованиями на его инстансы).
Если вам легче, можете это назватьChainable
,Sepulator
илиLittleFuzzyThing
, но тем самым вы уничтожите шанс быть понятым другими.
А аналогии вообще вредны почти всегда, ибо дают ложное ощущение понимания.amarao
01.05.2019 22:57Если бы аналогии были вредны, то компьютеров у вас бы не было. Все хорошие компьютерные слова, которые у вас есть, придуманы талантливыми людьми, которые считают термины очень содержательными.
Вот, например, ваши… файлы? Почему это файл? Да ладно, файлы. У вас на экране окно браузера. (два термина, очень хороших). В вашем хаскеле у вас данные организованны в списки и массивы, а память выделяется из кучи. Возвращаемые значения и адреса возвратов складываются в стек, ваши монады называются Maybe и Either, а память вашего компьютера считается в байтах. Каждое из этих слов построено на аналогиях, крайне вредных.
Мы же знаем, что на самом деле ijk f l_n z^k, и те, кто не способен понять смысл этого без "аналогий" просто не хотят тратить время на более содержательную беседу, чем спор о терминах.
vpatryshev
02.05.2019 00:02Монаду не притащили, а открыли путем наблюдений над самыми различными явлениями. Которые обобщаются примерно на такое — «функтор с pure и flatten».
Но, как я погляжу, тут ан масс невежды протестуют против математики. Да не хрен ли с ними, с невеждами. Математику они не отменят; отменят они только самих себя.amarao
02.05.2019 10:42Вы можете сказать, что такое «монада» в отрыве от математики? Происхождение слова?
Вот, например, я понимаю бытовой смысл слова «предел». И слово «решётка» у меня тоже не вызывает вопросов. Даже континуум, каким бы крипи он не был, всё равно имеет бытовой смысл. А «монада»?vpatryshev
02.05.2019 18:08Слово произошло от Лейбница. Можно всегда погуглить.
Насчет же бытового смысла слов, это, конечно, идейка ценная искать материальные метафоры (и я ее поддерживаю), но не знаю, как вы при этом терпите приложения на смартфоне, функции четырех переменных в коде, и моральный закон внутри нас. Можете бытовые метафоры назвать?amarao
02.05.2019 18:13Приложение — слово появилось за долго до компьютеров и подразумевало что-то дополнительное (к компьютеру). Что-то, что делает его «прикладным» (слово появилось до компьютеров и используется в быту).
Функция — вполне используется в быту. (Функция компьютера — считать)
Переменная — вполне вошло в быт, и смысл очевиден из названия (что-то, что меняется).
Мораль в бытовом языке используется похлеще, чем в философии.
Ещё вопросы?JC_IIB
02.05.2019 19:20Ещё вопросы?
Так что там с моральным законом-то? Какова бытовая метафора?amarao
02.05.2019 19:33Закон диктующийся моралью. Слово мораль — бытовое. Закон тоже.
JC_IIB
02.05.2019 20:16Слово мораль — бытовое.
Смысл слова «переменная» очевиден из названия, а вот очевиден ли из названия смысл слова «мораль»?mk2
02.05.2019 21:33Объяснять базовые понятия — это боль. Например, слово «точка». Да, я могу потыкать в. и сказать, что вот это точка — но к четкой формулировке это нас не приближает.
Другое дело, что с точками все знакомятся в школе.
vpatryshev
03.05.2019 02:54Отвык я уже вести ученые беседы с троллями, несущими херню.
TheShock
03.05.2019 12:07-1Дано:
amarao, 200 статтей, 20000 комментариев, 280 кармы
vpatryshev, 0 статтей, 34 комментария, -2 кармы
Внимание, вопрос: Кто из этих двоих — тролль?red75prim
03.05.2019 14:49Не вижу почему бы благородному дону немного не потроллить. По крайней мере очень похоже.
akryukov
03.05.2019 22:09Переменная — вполне вошло в быт, и смысл очевиден из названия (что-то, что меняется).
Не знаю, в чей именно быт вошло слово "переменная". Но описывать ее смысл словами "что-то, что меняется" некорректно. На мой взгляд, упущены такие факты:
1) Переменная всегда как то именуется. Без имени нет никакой определенности в изменении. По имени можно записать значение и прочитать значение.
2) При чтении значения из переменной, оно из переменной не пропадает.
3) При записи нового значения, старое исчезает бесследно.
Есть бытовая аналогия, которая выдерживает все эти пункты?
Функция — вполне используется в быту. (Функция компьютера — считать)
Переменная — вполне вошло в быт, и смысл очевиден из названия (что-то, что меняется).Исходный вопрос вообще был о функции четырех переменных, как о цельном понятии. Что то мне подсказывает, что в этом термине у слова "функция" совсем не то значение, которое вы объяснили.
vpatryshev
02.05.2019 00:10Это не свойство монады, это свойство, э, русских программистов, извините. Все непонятное вызывает страх. Ну, счастливого пути, конечно.
sshikov
02.05.2019 12:15Вот не надо про пенсию. К возрасту это никак не относится. Я тоже каждый день вижу тех, кто не боится flatMap — и среди них есть люди самого разного возраста.
andreyverbin
01.05.2019 10:13А кто сказал, что ФП что-то ускоряет? Я видел как знание предметной области, задачи, железа, ОС, языка, алгоритмов и библиотеки ускоряет разработку. Ещё я видел как разработку замедляет отсутствие нормальных IDE, средств отладки, мониторинга и профилирования. Ещё очень сильно разработку замедляет увлечение всякими «концепциями» типа ООП, ФП при отсутствии знаний перечисленных выше.
411
01.05.2019 10:45Для меня вот пока не особо понятно, какие материалы(книги/статьи/и т.д.) являются хорошими по ФП, чтобы почитать самому и порекомендовать потом другим. Хоть и многие вещи из ФП используются довольно часто мною.
amarao
01.05.2019 11:07Аргументы про иммутабельность — удел слабаков, которые не осилили borrow/ownership model. Объект может быть либо общим, либо мутабельным в один момент времени. И всё, никаких больше проблем и undefined behaviour. А вот как уж язык может это энфорсить — это вопрос открытый.
helions8
01.05.2019 13:42Не туда воюете, IMHO, и смешиваете понятия. Например, странно видеть такую «ФП-приватизацию» иммутабельности. Есть Erlang, который со всех сторон иммутабельный, но который же и один из самых ООП из всех ООП языков, просто не в понятиях «разложим код по классам и методам». ADT есть во вполне себе императивных Rust и TypeScript, функции высшего порядка вообще были много где десятилетиями в явном (JS тот же) или не явном виде (реализация интерфейса с единственным методом apply).
Может, стоит вообще начать с того, чтобы как-то выйти за пределы Blub-области в целом? Что ООП это не Borsch borsch = new Borsch(), а ФП это не только Клейсли ваш любимый, а просто стримы из Java, которые 1) содержат в разы меньше кода 2) ленивые 3) вы уже их используете, бояться поздно. А с ADT было бы удобно обрабатывать ошибки, не выхватывая NPE в щи.
Абстрактные аргументы про «скорость разработки» и «меньше ошибок» без хорошей статистики ничего не стоят, а «легкая композиция» вообще из области вкусовщины.nlinker
02.05.2019 10:11В Эрланге есть функция с побочным эффектом (send, !, посылка сообщения процессу), и этот эффект настолько мощный, что на базе него реализуетмя и мутабельное состояние, и ввод-вывод, и исключения и много чего ещё. И из-за этого также образуются всё те же проблемы, как в оопе — гонки, дедлоки, лайвлоки и прочие. Благодаря иммутабельности объектов, проблем удаётся избежать на уровне процессов, но проблемы уезжают на уровень взаимодействия между процессами.
sshikov
02.05.2019 12:25Насчет стримов… несомненно это тоже ФП. Хотя и частично. Могло бы быть и лучше, но и так неплохо прижилось.
Легкая композиция — да, попахивает вкусовщиной, так как не формализована.
Но с другой стороны, я уже года три как поймал себя на мысли, что вместо try/catch пишу Try.of(()->...). И возвращаю Try вместо String.
Почему? Да все потому же — потому что легкая композиция. Потому что даже если получатель этого Try все еще может сделать .getOrElse(""), и проигнорировать ошибку, по неопытности обычно, но если пару раз дать по рукам, и научить таки пользоваться flatMap, то все становится сильно проще. И это все видят, и тот кто пишет, и тот кто читает.
vvm13
Smalltalk продавали так же («более высокая скорость разработки, более дешевая поддержка, меньшее количество разработчиков») — но продать не сумели.
exception13x
Идеи Smalltalk вполне себе живут в Erlang.
napa3um
тысячи их )