Как стать автором
Обновить

Комментарии 100

НЛО прилетело и опубликовало эту надпись здесь
Идеи Smalltalk вполне себе живут в Erlang.
Повлиял на: Objective-C, AppleScript, C#, Dylan, Groovy, Io, Java, Lisaac, NewtonScript, Python, Ruby, Scala, Self, C++
© Wiki
тысячи их )
Я не знаю, как это сделать и не могу представить, как бы я, например, из настоящего мог бы объяснить это себе из прошлого.

Вот здесь чуть больше чем за час физик сумел объяснить что такое бозон Хигса людям, не знающим физику. При наличии кристально четкого понимания предмета можно объяснить кому угодно что угодно. Нужно просто последовательно описать область применения, круг решаемых проблем и собственно способ их решения.
А они потом смогли сделать свой бозон Хиггса? Или хотя бы сечение рассеяния на электроне посчитать? Программистам приходится.
Задачи не сопоставимые по сложности кстати. В концепциях программирования может самостоятельно разобраться любой школьник. Проблема только в том чтобы научиться эффективно их применять. Физику хоть до пенсии изучай, все равно будешь дилетантом во многих областях.
Да, но это — в любом случае сложнее, чем сказать: «Как вы здорово всё объяснили, я понял». С теми же монадами тоже не так всё просто — им соответствует множество концепций, на первый взгляд никак не связанных: вычисления на списках, передача состояния, ввод/вывод и т.д.

Пользоваться конкретными реализациями монад просто, но понять что такое монада и начать замечать, что вот эти элементы предметной области с таким-то операциями являются монадой, намного сложнее.

Переизобрести монаду или другую математическую абстракцию, заметив, что совершенно разнородные объекты и операции подчиняются одним и тем-же аксиомам, большинство (включая меня) скорее всего не сможет.
Сразу хочу сказать — тезис поддерживаю. Статья понравилась, хотя и коротковата. Хотелось бы более развёрнутого ответа:
Так что в следующий раз при сложностях ответа на вопрос «А зачем?» не стесняйтесь заходить с козырей, таких как: более высокая скорость разработки, более дешевая поддержка, меньшее количество разработчиков.


Простые констатации меня, ярого ООПшника не убедят. Я не вижу более высокой скорости разработки. Не вижу более лёгкой поддержки. Малое количество ФПшиков — вижу. Но это скорее недостаток, чем достоинство.

Разработка — это же не простое кодирование. В нормальном процессе разработки сначала идёт понимание, выраженное в документе. Сначала идёт описание. Текстовое. Устно или письменно. И лишь потом код.

И, как показывает практика, выражать свои мысли, обмениваться ими, пользуясь терминологией и подходом ООП — просто. Понятно даже тем, кто не знает ООП. Собственно под «естественное понимание человеком» этот подход и разрабатывался.

А ФП теряет своего слушателя уже на втором использовании слова «морфизм» и на первом использовании слова «функтор». Я слабо себе представляю как люди проектируют рабочие системы пользуясь диаграммами из теории категорий в техническом задании. (для тренировки попробуйте нарисовать подобное для простейшего веб-сервера, умеющего разбирать пути)

А раз люди друг друга не понимают — то о какой скорости разработки может идти речь? О какой поддержке?

А вы случаем не путаете "просто" и "знакомо"? Проектирование систем в фп стиле не означает, что система проектируется с использованием таких штук как "функтор" или "монада". Это проектирование, в котором иммутабельные данные проходят через ряд преобразований внутри функций. А функторы и монады — это уже детали реализации. Фп никаким образом не влияет на возможность людей договориться. Это просто немного другой подход. И, более того, на практике он не сильно отличается от тех же ооп best practices.

Не путаю.

Если система (например, банковский биллинг) строится на ООП, то она должна и описываться в терминах ООП в документации. Если строится на ФП, то и описываться должна в терминах ФП (вот у нас есть морфизм из HTTP запроса в HTTP ответ, который является ...). Иначе это _не_ программирование на ФП.

Ещё раз повторяю: разработка — это не просто по клавишам потыкать. Если не можешь на бумажке со стрелочками объяснить как оно работает, то это коддинг в самом плохом смысле этого слова.

И мой вопрос как эти стрелочки выглядят для программы на ФП?

Точно так же, как и для ооп.


Я открою вам страшный секрет — из одной и той же "архитектуры на листочке" можно сделать программу как в фп стиле, так и в ооп. Никто не проектирует "морфизмами".

Никто не проектирует «морфизмами»

Это вы так думаете)
А адепты ООП, ничего кроме ООП не видели. И «проектируют» архитектуру объектами.
И в документах описывают объекты. И думают, что все так делат. Потому, что их большинство и ничего другого они во круг не видят… Да и желания у них посмотреть как можно по другому, то же нет. Вот и получается замкнутый круг…
Предметная область в скала-проекте будет описана всё теми же объектами.
Э… вы правда думаете, что ООП это когда есть объекты? ))

Ну тогда вы только подтвердили мой комментарий…
не стоит приписывать оппоненту слова, которые он не говорил.
А где смотреть то?

Я сколько статей про ФП вижу — там про функторы и монады. Как будто и правда никто ничего не проектирует.

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

Открываю соседнюю вики ФП и вижу вместо него «Стили программирования» с
Императивные программы имеют склонность акцентировать последовательности шагов для выполнения какого-то действия, а функциональные программы к расположению и композиции функций, часто не обозначая точной последовательности шагов.

Чувствуете пропасть между интересами писавших это людей? Наверное, в ФП тоже кто-то проектирует, но продавать все пытаются функторы, монады и примеры на 2 строчки:
# функциональный стиль
# языки ФП часто имеют встроенную функцию compose()
compose2 = lambda A, B: lambda x: A(B(x))
target = map(compose2(F, G), source_list)
Спасибо, интересно было полистать. Жаль только половина книги, тема 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?» — Как обычно: как можем, так и решаем. Потом переделываем. А что, у вас бизнес-требования не меняются вплоть до переписывания с нуля?
Больше похоже не на руководство по архитектуре/методологии, а на сборник полезных советов и паттернов.

Именно набором полезных практик (с их теоретическим осмыслением) и является любая методология, это то, что помогает решать проблемы практикующего. Архитектура, в свою очередь, это выбираемый набор ограничений, в рамках которых вы желаете осуществлять своё проектирование. Однако многие, действительно, от методологии ожидают Святого Безупречного Слова, проводящего младенца с его табулой расой до преисполненного мудростью старцы, успешно закрывшего 100500 проектов за 24 часа, отсюда и все эти безадресные претензии «не умеете учить, значит, сами не понимаете!» с одной стороны и культы карго с другой. (Левый комментарий не по теме вашей беседы, если что :))
> Именно набором полезных практик (с их теоретическим осмыслением) и является любая методология

Но не любой набор практик является методологией.

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

Что-то я не уверен, что использование брейнсторминга и майндмапов — это про философию ФП.

А вот открывая руководство по архитектуре от МС я там вижу и проверенные опытом(!) решения, и заложенные в них ограничения, и мне не нужно без опыта ФП(!) пытаться эту мудрость на часовом брейнсторминге воспроизвести с тем же качеством, что и авторы книги.

> отсюда и все эти безадресные претензии «не умеете учить, значит, сами не понимаете!» с одной стороны и культы карго с другой

Во-первых, мне без разницы почему «учитель» не умеет учить.
Во-вторых, культ карго — это попытка повторять без инструкции умных людей, то есть, собственно, внимательного прочтения хорошей книги.

Вот нужен вам велосипед — сначала прочитайте документацию, сделайте также. Это не культ карго — это ката.
Мне в этом плане понравился ответ Druu в одном из давних постов graninas, цитирую полностью:
«Ну вам чтобы использовать абстрактную фабрику требуется знание какой-то особенной теории? Думаю, нет. Так и с монадами/функторами — смотрите на это как на определенный интерфейс, который предоставляет определенные возможности.»


Так же и здесь. Никто не пишет «а вот тут абстрактная фабрика будет генерировать… что-нибудь».
Вы каждый if будете описывать на бумаге? Например, в Яве8 наконец-то появились лямбды и стримы, и народ их начал вполне эффективно использовать, ибо давно наболело. Это самое что ни на есть ФП (\шёпотом\ и даже с монадами, хотя большинство разработчиков даже не знают, что они используют монады), просто ООП это тоже не отменило.
Если система (например, банковский биллинг) строится на ООП, то она должна и описываться в терминах ООП в документации.
ИМХО ФП — это прежде всего метод, позволяющий совладать с очень сложными алгоритмами (сложными алгоритмически а не в смысле количества внутренних интерфейсов и бюрократических процедур, которым алгоритм должен поклониться). Это могут быть алгоритмы для некого принятия решения, оптимизации. Условно говоря, это когда функция получает на входе простой запрос и доступ на чтение к доменной модели, выполняет алгоритм на несколько тысяч строк и возвращает простой ответ. В подобных случаях преимущества ФП бесспорны: четко видно что принимает и выдает каждая часть кода, нет необходимости изобретать кучу странных классов, нет проблем с много-поточностю, хранение промежуточных данных в имутабельных структурах итоге проще, чем в каких-то запутанных временных объектах. Если же проектировать нечто вроде биллинговой системы, то это все равно будет много взаимодействующих компонентов и общая схема системы будет одинаковой для проекта на ООП и на ФП.
> А ФП теряет своего слушателя уже на втором использовании слова «морфизм» и на первом использовании слова «функтор». Я слабо себе представляю как люди проектируют рабочие системы пользуясь диаграммами из теории категорий в техническом задании.

Не бывает такого. Не оперируют этими словами во время проектирования. Оперируют обычными терминами: подсистема, интерфейс, имплементация. Потом думают, какие технологии можно применить: FRP, STM, монады. Может, достаточно функций и алгебраических типов данных. Никто из известных мне хаскеллистов в продакшне не проектирует на теории категорий.
Подсистема, интерфейс, имплементация — это термины ООП. И если люди их используют, то они программируют на ООП, хоть и кодят в ФП. Тогда и не надо говорить о «программировании на ФП». Тогда и понятен провал — на раскоряку сидеть неудобно.
Вы глубоко неправы. Это не термины ООП. Это универсальные термины, не связанные с парадигмой или технологиями.

интерфейс ~= контракт ~= сигнатура ~= типы параметров функции
имплементация = реализация
подсистема = подсистема (хмм, лол)
как это относится к ООП???

>Простые констатации меня, ярого ООПшника не убедят. Я не вижу более высокой скорости разработки. Не вижу более лёгкой поддержки. Малое количество ФПшиков — вижу.

Ну, мы верим. Собственно, текст об этом — что надо лучше продавать. Надо подать так, чтобы вы увидели.

Я вот вижу слегка другое. Например, ФП в Java-сообществе довольно долго было «на задворках». Кто знает, что была и есть такая штука, как functional java, существующая очень давно? Да почти никто пожалуй и не знает. Зато с появлением Java 8, где некоторые части ФП стали частью языка, вот это вот все, скорость разработки, легкая поддержка — они видны всем, кто вообще хоть как-то интересуется. Яркий пример — то, как преобразились широко известные паттерны ООП с появлением функций в таком виде, что с ними стало реально удобно работать.

Они видны всем, кто работает и с такими вещами, как Spark. Хотя да, было бы очень неплохо не просто сказать «а я это вижу», но и померять.

Насчет ФП как способа выражения своих мыслей — ну это хорошее замечание, хотя вам уже пару раз ответили, что никто не проектирует системы в терминах аппликативных функторов. Кстати, я сильно сомневаюсь, что вы сможете также адекватно спроектировать систему в терминах ООП для любого произвольного применения.

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


sshikov, a можно пример или ссылку на пример?
Попробую, но не факт что быстро найду. Хотя… взгляните вот это, например.
Насчет ФП как способа выражения своих мыслей — ну это хорошее замечание, хотя вам уже пару раз ответили, что никто не проектирует системы в терминах аппликативных функторов. Кстати, я сильно сомневаюсь, что вы сможете также адекватно спроектировать систему в терминах ООП для любого произвольного применения.


Для любого произвольного и не надо, системы проектируются под конкретную клиентскую задачу. Система для любого произвольного применения — ОС. Только надо сначала программу написать :) а так любую задачу решает.

Не бывает абстрактных задач, все задачи конкретные.
Так я и хочу сказать, что ООП не панацея для любой задачи. Какие-то задачи на нее неплохо ложатся, а какие-то приходится как сову на глобус.
Библиотеки линейной алгебры, например. Иерархия чисел (целые, с плавающей точкой, комплексные и т.п.).
Из того, что мне лично попадалось недавно, это пожалуй интеграционные задачи разного рода. Их обычно описывают в терминах так называемых EIP (enterprise integration pattern), которые сами диаграммы, и на ООП они ложатся так себе. Не то чтобы их нельзя было в таких терминах описать — а просто пользы от такого описания не будет, и реализация обычно не в этих терминах все равно.

При этом описание другого бизнес-проекта почти на 100% состояло из одной здоровой ER-диграммы, и все отображалось в объекты и манипуляции с ними.
А я как раз про то что в большинстве задач ООП рулит, потому что большинство задач не про то как красиво вычислить числа фибоначи, или очень круто параллельно умножить каждый элемент массива на 2. Большинство задач про то как провести платеж пользователя, передать сообщение в чат, сохранить файл на диск, показать видео в окошке. И в них всех гораздо лучше подходит ООП.
Ну, я в штуках не считал, поэтому про большинство говорить не стану. У меня — где как, в последних проектах на спарке от ООП по большей части тоже рожки да ножки.

Платежи и формочки — да, это как раз случаи, когда бизнес задачи на ООП нормально ложатся. Ну и скажем так — по сравнению с тем, что было до ООП, это несомненно был шаг вперед в плане организации кода.
  1. Описать с помощью ООП как корова щиплет траву (там будет корова.щипать(трава), трава.бытьОщипанной(корова) или Природа.поедание(корова, трава)?).


  2. Есть лужа (совсем необязательно являющаяся сечением шара), в лужу бросили камень (вектор скорости совсем необязательно перпендикулярным поверхности). Задача: описать поведение волн с течением времени. Вот здесь бесполезность ООП лично для меня очевидна — задача поставлена, есть необходимость её решать, но ООП здесь совершенно никак не вклеивается — можно конечно создать классы "Лужа" и "Камень", и описать метод "взаимодействовать", но это даже на миллиметр не приблизит нас к моделированию действительности.



PS: А приблизит нас тоненькая брошюрка "Введение в динамику жидкости" товарища Бэтчелора и такая же тоненькая "Вычислительная математика" Тихонова+Самарского. В первой книжке мы найдём как выписать систему уравнений Навье-Стокса для нашей лужи, а во второй книжке мы найдём методы, как решать системы диффур численно. Покроем лужу достаточно мелкой сеткой, напишем алгоритм числнного решения (с прицелом на кластер) и вот тогда мы приблизимся таки к моделированию нашей действительности. И тут — о чудо — появятся объекты, да. Например, vector, matrix, обёртки над сокетами и тому подобные технические сущности. Причём набор этих сущностей будет существенно зависеть от выбранного способа решения. Однако куда делись лужа с камнем?

Лужа с камнем никуда не делись, камень изменил свои координаты и теперь лежит в луже. Просто Ваше внимание переключилось с лужи и камня на волну, которая возникла на поверхности лужи, для описания формы которой Вы читаете Бэтчелора, Тихонова+Самарского и составляете систему уравнений Навье-Стокса.
1, 2. Вы просто как, видимо, функциональщик, акцентируете внимание на действиях, «щипать» и «бросать». НУ в этом смысле да, если «не замечать» объекты, то как бы их и нет :) есть только «функции».
Вообще-то, программирование — это составление программ, т.е. алгоритмов (описания действий). ОПП, ФП, Структурное программирование и т.п. и т.д. — это все о том, как декомпозировать программу (алгоритм). На какие части и как. О том, как сделать кирпичики, чтобы из них собрать программу (алгоритм).

Описание требований и т.п. — это не программирование. И тут ООП не причем. Декомпозиция и описание ИС — это не совсем про программирование, т.е. написания программы.
Описать с помощью ООП как корова щиплет траву (там будет корова.щипать(трава), трава.бытьОщипанной(корова) или Природа.поедание(корова, трава)?).

Ну такой глупый пример и в обратную сторону сработает. На ФП как? Так?
новаяКорова = кушать(стараяКорова, трава)


Или, может так:
новаяКорова = кушать(трава, стараяКорова)


Что будет, если я передам траву тигру?
новыйТигр = кушать(трава, тигр)


Можно ли так?
новыйТигр = кушать(корова, тигр)


Сработает ли тогда так?
корова3 = кушать(корова1, корова2)
Очень корявое передергивание…
Вы пытаетесь глупыми, за ранее корявыми примерами сместить фокус обсуждения с абсолютно корректного вопроса проектирования в ООП в плоскость семантики конкретного языка.

P.S. Если писать на JS, то все ваши вопросы открыты и ответы зависят от компетенции разработчика. Если писать например на Haskell, то большинство ваших примеров просто не скомпилятся ввиду несоответсвия типов.
Я же сразу сказал — это глупый пример в ответ на глупый пример. Вам ваш пример не кажется глупым потому что вы — фанбой. Вся критика ООП кажется глубокой и остроумной, как та глупость с паттерны-против-функций

И вопрос не в семантике. Как бы вы не писали эти примеры — вопрос остается тот же.

Да в том-то и дело, что проблемы подобные коровам и траве в реальных проектах встречаются повсеместно, и разработчики далеко не всегда выбирают нужный класс удачно (это во многом зависит от ответственностей, которые навешивают на классы впоследствии). Кроме того, есть много ошибок, связанных с компромиссом "богатый интерфейс + удобство использования 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 можно посчитать просто как сумму частей!).

Почему в вашем коде тигр не может съесть корову?
НЛО прилетело и опубликовало эту надпись здесь

А должен?

всякие мат алгоритмы на haskell быстрее же писать?
Подозреваю что да. Я разве говорил что-то обратное?
Простые констатации меня, ярого ООПшника не убедят. Я не вижу более высокой скорости разработки. Не вижу более лёгкой поддержки


И не увидите, скорость и простота поддержки зависят в куда большей степени от разработчика, а не от того, на чём он пишет. Тут можно было бы сказать «если нет разницы, зачем платить больше», но у нас есть отличный пример того, как сам ОО подход принимался индустрией. Сначала большинство разработчиков тоже не понимало, зачем так всё усложнять. А потом рост сложности проектов ярко показал выгоды.
ФП существует очень давно, но теперь его внедрение толкает вперед индустрия больших данных и параллельных вычислений, чем больше людей становятся знакомы с ФП-концепциями, тем больше они начинают находить им применение в самых разных областях, Так что лет через 10 говорить будут не «ФП даёт более высокую скорость/лучше поддержку», а «проекты такого уровня сложности никто уже давно не делает на голом ООП».

Как мне кажется, с задачей "Объяснить монаду" неплохо справился Миран Липовича в своей книжке с голубым слоном. Но в Scala, не используя scalaz/cats это сделать не просто, скажем так.

Да, согласен

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


https://www.youtube.com/watch?v=dWyGM3MnN0A

Как раз ее и перечитывал перед написанием. Так что, возможно, получился своего рода трибьют.
С одной лишь разницей, что меня не устраивают его выводы. В отличие от Пола, у меня не появился и врядли появится свой стартап, чтобы преспокойно наблюдать за медленным мейнстримом и держать свое оружие в секрете.
Люди постоянно упускают из виду что современная коммерческая разработка уже давно не про абстракции, ФП, ООП, etc. Она про взаимодействие между людьми. По ссылке пример успеха Пола Грэма с Viaweb написанном на Lisp'е и вроде как ставшим успешным как раз благодаря Lisp'у. Но это же полная чушь, Viaweb был куплен Yahoo! за $45m благодаря организационному таланту и инвесторской проницательности Грэма, а не благодаря Lisp'у. Сколько успешных проектов написано не на языках ФП, сколько проектов обвешаных монадами кануло в безвестности? Люди > технологии. Если вы можете найти команду отличных специалистов ФП среди которых не будет примадон занимающихся самообразованием вместо решения проблем бизнеса — отлично, вам повезло. Но в большинстве случаев вам придется делать проекты с теми разработчиками, которые есть на рынке.
Статья не про то, как Грэм продавал проект Yahoo!, а про то, как этот проект делался. Центральная мысль статьи о том, что команда проекта играючи душила конкурентов благодаря возможности легко и быстро изменять код, что в свою очередь было заслугой Lisp'а. Можно быть сколь угодно хорошим предпринимателем, но если инструмент зарабатывания денег не позволяет быстро реагировать на требования рынка, успеха не достичь. Многие современные тенденции в отрасли, упомянутые dos65 — гибкие методологии, DevOps, микросервисная архитектура — предназначены как раз для этого, как можно более быстрой реакции на требования рынка. И мы ещё не затрагиваем вопрос того, что стоимость поддержки существенно выше стоимости разработки, а ФП может помочь эти затраты снизить.

Я в целом согласен, что люди значат больше, чем технологии. Но и тут у ФП преимущество, если верить отзывам компаний, нанимающих clojure-программистов. Они заверяют, что Clojure стоило выбрать уже за то, что тот открыл им рынок высококачественных соискателей и возможность формирования превосходных команд. Впрочем, я думаю, что это связано с относительно высоким порогом входа и пока ещё низким спросом. Уверен, лет через 10 вероятность напороться на примадону будет одинакова как при найме джависта, так и кложуриста.
>Центральная мысль статьи о том, что команда проекта играючи душила конкурентов благодаря возможности легко и быстро изменять код, что в свою очередь было заслугой Lisp'а.

Наверняка же знаете такой анекдот: а я на машинке умею быстро-быстро печатать! Такая х-ня получается :) Я тоже могу код легко и быстро изменять, это всегда можно было, только проблема как правило не в коде.

У бизнеса (который обычно представляют аналитики) уходят месяцы на обдумывание. У поддержки уходят месяцы на то, чтобы обнаружить проблему. Разработчик меняет код за 15 минут.

Вообще справедливости ради ФП не отменяет ООП, он скорее противоположен императивному программированию.

На днях как раз видел хорошее высказывание по этому поводу от умного человека
image
Спасибо за статью, надеюсь Вы не бросите попыток освоить глубины функционального программирования!

Нет, это не очередная попытка объяснить монады. Я не знаю, как это сделать и не могу представить, как бы я, например, из настоящего мог бы объяснить это себе из прошлого.


Могу предположить, что Вам неоднократно задавали похожий вопрос, интересно, что Вы отвечали?

Монады весьма забавная концепция, я до сих пор вряд ли смогу объяснить внутреннюю математику в рамках категорий, но с практической точки зрения всегда определял как абстракцию вычислительного процесса. Что такое вычисления понимают все, а абстракция просто говорит о том что мы описываем вычисления не вдваясь в детали контекста (происходит ли это асинхронно, есть результат или нет, может упасть с ошибкой или вернуть результат и т.д). Scala к сожалению скрывает суть за синтаксическими нагромождениями.

Касательно «А зачем это все?», я ответить Вам не смогу, но из моего опыта работы с функциональными языками и общения с ФП коммьюнити, я пришел к выводу, что для многих людей ФП является естественным отражением того как эти люди думаю, подходят к решению задач. Вопрос не в том хуже ООП или нет, это разные инструменты и, на мой взгляд, выбирать надо не с точки зрения скорости разработки, поддержки и т.д, а того с чем вам приятнее и удобнее работать, тогда, может быть, вопроса «А зачем это все?» стоять не будет.
Чудесно!

По мне так ответ на эту загадку простой — эти люди сойдут со сцены, и придут те, кто «понимает монады». У нас в группе как-то с этим не видно проблем, например.

Я насмотрелся в жизни и страха перед фортраном, и страха перед си++, и страха перед джавой, и страха перед ООП, и страха перед ФП; теперь вот все баяцца монад. Ну пусть боятся; эти люди ж не вечно на арене. Придут те, что не боятся. map и flatMap для них естественная вещь. Я этих людей вижу каждый день.

Ну и монада не конец света, конечно. Линзы (и вообще оптика), свободные монады (я в них не верю, там нужно сохранение фильтрованных копределов), расширения Кана… жизнь идет. А «любители ООП» (можно подумать, они родились с ООП в голове) уйдут на пенсию, будут ныть там.
Главная проблема «монады» в её названии. Что такое объект? Что-то, что можно взять, положить, посмотреть во внутрь. Что такое тред? Что-то, что вьётся, у чего есть продолжительность, начало и конец. Что такое pipe? На вход что-то, на выход оно же.

Простые, ясные, бытовые аналогии.

А теперь, какие бытовые свойства у монады? Например, быть непонятной.
> А теперь, какие бытовые свойства у монады? Например, быть непонятной.

Сохранение порядка эффектов независимо от способа вычисления (энергичного, параллельного, или какого-нибудь из ленивых — неважно)
Это вы уже придумали. Откуда слово «монада»? Почему «это» решили назвать «монада», а не «сепулятор»? Очевидно, что все свойства сепулятора так же выполняются.

Я повторю, что для центрального объекта для программирования, использованное слово — катастрофа семантического масштаба.

Сравните с трейтами. Внутри — предикаты на типах. А снаружи? «черты характера, типаж». Мы хотим от структуры иметь такие-то черты характера. Блистательная аналогия.

А монады — семантическая бездна. Кто, вообще, притащил её в математику, откуда и чем объяснял?
То есть вас интересует просто этимология термина monad? Лично я не в курсе, но я уверен, это можно разыскать, было бы желание.
Я бы предпочёл вести более содержательную беседу, чем спор о терминах.

Монада для разработчика на Haskell, например, имеет вполне конкретный смысл безо всяких аналогий (это тайпкласс вместе с требованиями на его инстансы).
Если вам легче, можете это назвать Chainable, Sepulator или LittleFuzzyThing, но тем самым вы уничтожите шанс быть понятым другими.

А аналогии вообще вредны почти всегда, ибо дают ложное ощущение понимания.

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


Вот, например, ваши… файлы? Почему это файл? Да ладно, файлы. У вас на экране окно браузера. (два термина, очень хороших). В вашем хаскеле у вас данные организованны в списки и массивы, а память выделяется из кучи. Возвращаемые значения и адреса возвратов складываются в стек, ваши монады называются Maybe и Either, а память вашего компьютера считается в байтах. Каждое из этих слов построено на аналогиях, крайне вредных.


Мы же знаем, что на самом деле ijk f l_n z^k, и те, кто не способен понять смысл этого без "аналогий" просто не хотят тратить время на более содержательную беседу, чем спор о терминах.

Монаду не притащили, а открыли путем наблюдений над самыми различными явлениями. Которые обобщаются примерно на такое — «функтор с pure и flatten».

Но, как я погляжу, тут ан масс невежды протестуют против математики. Да не хрен ли с ними, с невеждами. Математику они не отменят; отменят они только самих себя.
Вы можете сказать, что такое «монада» в отрыве от математики? Происхождение слова?

Вот, например, я понимаю бытовой смысл слова «предел». И слово «решётка» у меня тоже не вызывает вопросов. Даже континуум, каким бы крипи он не был, всё равно имеет бытовой смысл. А «монада»?
Слово произошло от Лейбница. Можно всегда погуглить.
Насчет же бытового смысла слов, это, конечно, идейка ценная искать материальные метафоры (и я ее поддерживаю), но не знаю, как вы при этом терпите приложения на смартфоне, функции четырех переменных в коде, и моральный закон внутри нас. Можете бытовые метафоры назвать?
Приложение — слово появилось за долго до компьютеров и подразумевало что-то дополнительное (к компьютеру). Что-то, что делает его «прикладным» (слово появилось до компьютеров и используется в быту).
Функция — вполне используется в быту. (Функция компьютера — считать)
Переменная — вполне вошло в быт, и смысл очевиден из названия (что-то, что меняется).
Мораль в бытовом языке используется похлеще, чем в философии.

Ещё вопросы?
Ещё вопросы?

Так что там с моральным законом-то? Какова бытовая метафора?
Закон диктующийся моралью. Слово мораль — бытовое. Закон тоже.
Слово мораль — бытовое.

Смысл слова «переменная» очевиден из названия, а вот очевиден ли из названия смысл слова «мораль»?
Объяснять базовые понятия — это боль. Например, слово «точка». Да, я могу потыкать в. и сказать, что вот это точка — но к четкой формулировке это нас не приближает.

Другое дело, что с точками все знакомятся в школе.
Отвык я уже вести ученые беседы с троллями, несущими херню.
Дано:
amarao, 200 статтей, 20000 комментариев, 280 кармы
vpatryshev, 0 статтей, 34 комментария, -2 кармы

Внимание, вопрос: Кто из этих двоих — тролль?
Ну вот вы явно троллите.

Статей, кармы и комментариев у вас ближе к amarao.
В каком месте я, вдруг, троллю?
НЛО прилетело и опубликовало эту надпись здесь
Вполне возможно, тогда зачем вообще поднимать вопрос на счет троллинга?
Не вижу почему бы благородному дону немного не потроллить. По крайней мере очень похоже.
О, действительно, не тролль — масса интересных статей у него. Спасибо.
Сдаётся мне, что второй это github.com/vpatryshev, которого я помню по далёким фидошным временам как специалиста по функциональшине.
Да, Форт-М6000, вроде бы тоже.
Не всё так однозначно.
Переменная — вполне вошло в быт, и смысл очевиден из названия (что-то, что меняется).

Не знаю, в чей именно быт вошло слово "переменная". Но описывать ее смысл словами "что-то, что меняется" некорректно. На мой взгляд, упущены такие факты:
1) Переменная всегда как то именуется. Без имени нет никакой определенности в изменении. По имени можно записать значение и прочитать значение.
2) При чтении значения из переменной, оно из переменной не пропадает.
3) При записи нового значения, старое исчезает бесследно.
Есть бытовая аналогия, которая выдерживает все эти пункты?


Функция — вполне используется в быту. (Функция компьютера — считать)
Переменная — вполне вошло в быт, и смысл очевиден из названия (что-то, что меняется).

Исходный вопрос вообще был о функции четырех переменных, как о цельном понятии. Что то мне подсказывает, что в этом термине у слова "функция" совсем не то значение, которое вы объяснили.

Это не свойство монады, это свойство, э, русских программистов, извините. Все непонятное вызывает страх. Ну, счастливого пути, конечно.
Вот не надо про пенсию. К возрасту это никак не относится. Я тоже каждый день вижу тех, кто не боится flatMap — и среди них есть люди самого разного возраста.

А кто сказал, что ФП что-то ускоряет? Я видел как знание предметной области, задачи, железа, ОС, языка, алгоритмов и библиотеки ускоряет разработку. Ещё я видел как разработку замедляет отсутствие нормальных IDE, средств отладки, мониторинга и профилирования. Ещё очень сильно разработку замедляет увлечение всякими «концепциями» типа ООП, ФП при отсутствии знаний перечисленных выше.

Для меня вот пока не особо понятно, какие материалы(книги/статьи/и т.д.) являются хорошими по ФП, чтобы почитать самому и порекомендовать потом другим. Хоть и многие вещи из ФП используются довольно часто мною.
попробуйте
Functional Programming, Simplified by Alvin Alexander
Спасибо, попробую
Аргументы про иммутабельность — удел слабаков, которые не осилили borrow/ownership model. Объект может быть либо общим, либо мутабельным в один момент времени. И всё, никаких больше проблем и undefined behaviour. А вот как уж язык может это энфорсить — это вопрос открытый.
Не туда воюете, IMHO, и смешиваете понятия. Например, странно видеть такую «ФП-приватизацию» иммутабельности. Есть Erlang, который со всех сторон иммутабельный, но который же и один из самых ООП из всех ООП языков, просто не в понятиях «разложим код по классам и методам». ADT есть во вполне себе императивных Rust и TypeScript, функции высшего порядка вообще были много где десятилетиями в явном (JS тот же) или не явном виде (реализация интерфейса с единственным методом apply).

Может, стоит вообще начать с того, чтобы как-то выйти за пределы Blub-области в целом? Что ООП это не Borsch borsch = new Borsch(), а ФП это не только Клейсли ваш любимый, а просто стримы из Java, которые 1) содержат в разы меньше кода 2) ленивые 3) вы уже их используете, бояться поздно. А с ADT было бы удобно обрабатывать ошибки, не выхватывая NPE в щи.

Абстрактные аргументы про «скорость разработки» и «меньше ошибок» без хорошей статистики ничего не стоят, а «легкая композиция» вообще из области вкусовщины.

В Эрланге есть функция с побочным эффектом (send, !, посылка сообщения процессу), и этот эффект настолько мощный, что на базе него реализуетмя и мутабельное состояние, и ввод-вывод, и исключения и много чего ещё. И из-за этого также образуются всё те же проблемы, как в оопе — гонки, дедлоки, лайвлоки и прочие. Благодаря иммутабельности объектов, проблем удаётся избежать на уровне процессов, но проблемы уезжают на уровень взаимодействия между процессами.

С этим нельзя не согласиться, но вроде как и не противоречит тому, что я написал.

Не сразу понял посыл вашего сообщения, да, не противоречит. Считайте, что я дополнил ваш ответ.

Насчет стримов… несомненно это тоже ФП. Хотя и частично. Могло бы быть и лучше, но и так неплохо прижилось.

Легкая композиция — да, попахивает вкусовщиной, так как не формализована.

Но с другой стороны, я уже года три как поймал себя на мысли, что вместо try/catch пишу Try.of(()->...). И возвращаю Try вместо String.

Почему? Да все потому же — потому что легкая композиция. Потому что даже если получатель этого Try все еще может сделать .getOrElse(""), и проигнорировать ошибку, по неопытности обычно, но если пару раз дать по рукам, и научить таки пользоваться flatMap, то все становится сильно проще. И это все видят, и тот кто пишет, и тот кто читает.
Автор, я прекрасно понимаю вашу любовь к ФП и ваши старания донести людям свои доводы. Пожалуй она сравнима с моей к Ruby — прекрасный язык, но вести профессиональную разработку не могу так как он мало востребован. Т.е. это наши субъективные мнения, а тут нужен объективистский подход.
Сейчас часто приходится слышать «Я использую ФП! только ФП! Тут можно написать функцию а не класс», но знаете чем это все заканчивается?! Дело в том что люди это утверждающие вообще не разбираются ни в принципах программирования, ни в архитектуре и даже в том же понимании ФП. И таких у нас 100 человек на проекте, и это все выливается в деструктуризированный ад.
И это к сожалению на практике бьет все ваши доводы «более высокая скорость разработки, более дешевая поддержка, меньшее количество разработчиков.».
Я прекрасно понимаю что на ФП тоже можно писать отличные продукты Си тому пример.
Но проблема как раз в том что происходит подмена понятий. ФП в вашем понимании это не тоже ФП в представлении другого.
Единственное что могу посоветовать это отсеивать людей с псевдопредставлениями о ФП и направлять их на достойные теоретические труды в этой области.

P.s. Буду признателен если порекомендуете одну книгу которая ответит на все вопросы по ФП в том числе и как писать на нем код.
Я прекрасно понимаю что на ФП тоже можно писать отличные продукты Си тому пример
Жаль вас расстраивать, но Си — это совершенно не ФП, а ПП. Это две кардинально разные парадигмы.

А по сути я с вами категорически согласен. ФП требует высокого уровня от программиста. Увы, у большинства современных ФП-программистов высокий уровень только самомнения.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий