Design patterns are spoonfeed material for brainless programmers incapable of independent thought, who will be resolved to producing code as mediocre as the design patterns they use to create it.
Аргументы у него всё те же, уже изложенные в этом треде:
Очень сильный аргумент при обсуждении ООП: «функциональное программирование лучше».
Эээ... а каких вы хотели? Когда люди обсуждают проблемы c X, которых нет в аналоге Y — я считаю полезным посоветовать Y. Вы находите это неправильным?..
И да, если ваша задача — описать некий конкретный снег (на произвольном языке), то выбор чукотского будет, очевидно, выигрышным.
бизнес — приложения пишут в основном на ООП.
в основном
пишут на ООП
Хорошо.
в JavaScript, который изначально не ООП приходится эмулировать классы.
Ладно.
Есть много книг по ООД, ДДД и прочим ООП — подходам к проектированию. Но я как-то не видел книги, где было бы разобрано как на ФП полностью спроектировать, например, интернет — магазин.
Какой суммой своих денег... вы готовы рискнуть, поставив на то что ваша «монадическая интуиция» будет соответствовать требованиям реального мира?
На что нужно ставить деньги, ещё раз?
Сформулируйте чётче. Каков completion criterion? При выполнении каких условий/событий/проверок я получу свои (умноженные) деньги обратно?
Повторюсь: во многих реальных задачах моделирование выполняется проще с использованием алгебраических типов данных и тайплассопедии. Этому есть фактические подтверждения.
А у вас каша в голове, вы даже риторический вопрос поставить не можете. Только подвесить — чтоб шатался в нужную сторону. // это мой ответ на ваш красочный аргумент к личности
Мне это говорит только о том, что Q.deferred не комплаит спецификацию promiseaplus, И не предоставляет монадический интерфейс. Только и всего.
В случае же, когда монадический интерфейс предоставляется (jQuery.deferred) рассуждать о нём применяя монадическую интуицию по-прежнему проще, чем без неё.
Операция bind в хаскеле принимает только два аргумента; в случае с `Future a` это будет сам `Future a`, и его продолжение (функция `a -> Future b`). Обработку ошибок нужно как бы модульно добавлять другими средствами (MaybeT, EitherT, например) — ну либо вообще не добавлять, если используемые действия возвращают результаты без ошибок.
Поэтому сразу так не совсем понятно, что ваш код выведет. Если всё-таки подсмотреть в спеке, что за два аргумента у .then, то ответ прост (чисто из монадной интуиции): зависимо от того, как отрезолвится первоначальный promise, появится один из двух алертов.
Если мы говорим про что-то вроде promisesaplus.com , то зачем вы использовали такие слова как монадический-что-то-там? Это просто посыл сообщения/вызов метода у объекта.
Да, это идеальный пример вы приводите. Зачем мне читать 3 страницы реквайрментов к интерфейсу, когда я могу просто понять, что здесь монада? А это и есть монада; просто почему-то большая часть спеки говорит о посылках сообщений™ и инвариантах внутреннего состояния. О том, что в случае Хаскеля запишется в типах и проверится автоматически компилятором.
Давайте ещё так: если мы говорим о скоплениях электронов в кристалле кремния, то зачем вы используете такие слова как вызов-метода-у-чего-то-там? Неужели вы заметили, что новые абстракции — это единственный работающий способ совладать с нарастающей сложностью ПО?..
Если посмотреть на качественный скачок от указателей-и-структур до методов-и-интерфейсов — сразу видно, насколько хорошо помогает удачная и простая абстракция. Тайпклассопедия даёт более ёмкие абстракции для качественно превосходящего построения интерфейсов. Это следующий шаг в проектировании ПО после ООП.
На 14-м слайде вы забываете, что моделируются типы далеко за пределами объектов. В современных языках любят поутверждать, что якобы «всё есть объект» и можно писать print("68656c6c6f".decode('hex')) — но это не так; есть полно задач (численные симуляции, например), объектные модели для которых выглядят отвратительно, натянуто и ненатурально (в лучшем случае всё ограничивается парочкой God Object-ов без перспектив дальнейшей детализации). Тайпклассопедия даёт возможности более широкого моделирования. Я знаю, как перевести Monoid на тот же С++, но сформулировать Alternative для ООП парадигмы уже как-то трудно.
Понимаете, да? Перевод GoF патернов в FP парадигму тривиален; в тайпклассопедии нет Strategy (потому что в FP Strategy это просто функция) — но перевод сегодняшних тайпклассов вроде Comonad обратно в парадигму ООП уже совсем не тривиален (несмотря на то, что концептуально это по-прежнему простые вещи). Более того, на C++, например, невозможно даже записать интерфейс Monad в общем случае; можно только повторять снова и снова под каждый конкретный случай (в точности это и происходит с std::future). Это так отчасти из-за недостатков системы типов (а именно, если я правильно понимаю: из-за отсутствия rank-n types).
В общем, вашу цитату я всё равно не понимаю (на правило вывода, кстати, она тоже не похожа: в правилах вывода имеются 1) аксиомы 2) предпосылки 3) следствия), и, в общем-то, ваше дело, какими абстракциями в своей работе пользоваться. Но на мой взгляд, вы сильно теряете, отказываясь от тайпклассопедии.
«Матерые ФПшники» (многие из тех с кем я пересекался) обясняют монаду как «монада — это монада», а потом начинают отшучиваться про рекурсию и тд.
Не думаю, что здесь подходящее место, чтобы начинать это объяснять — в сети есть уйма обучающих руководств по этой теме; можете начать хоть с той же haskellwiki, или с атлассиановской тайпклассопедии (для Scala).
Но есть поучительный момент, в том, что, например, то же красно-чёрное дерево — это Functor (отношение вида IS A — не наследование!), также Foldable и Monoid. Можно сделать и Monad, но это будет как-то не очень осмысленно.
Хороший пример монадического интерфейса — это Future, с операцией .then() (.ContinueWith() в .NET) в качестве монадической операции.
Вообще, по многим отчётам, тайпклассопедия в разы упрощает дизайн интерфейсов:
Recently I looked at some code I wrote 8 months ago and was shocked! I looked at one file written in «good OO-style», lots of inheritance and code reuse, and just thought «this is just a monoid and a bunch of crap because I didn’t realise this is a monoid» so I rewrote the entire thing to about a third of the code size and ended up with double the flexibility. Shortly after I saw another file and this time thought «these are all just endofunctors,» and lo and behold, rewrote it to about a third of the code size and the final product being both easier to use and more powerful.
Давайте скажем так: есть задачи (которые можно формально поставить), и есть их решения. Есть плохо понятые задачи (без полных формализаций), и настолько же плохо понятые решения.
Кстати, поясните чем Singleton так сильно отличается от State Monad и нафик ее (State Monad) придумали?
А чем огурец стакан чашка витаминов?..
Простите, мне непонятен этот вопрос. Давайте вместо отличий попробуем начать со сходства? По-моему, его там вовсе нет.
Но могу, конечно, ответить, зачем придумали монаду State. Это стройный алгебраический способ контролировать сайд-эффекты. Либо, если хотите, эдакий абстрактный синтаксический сахар для элегантного протягивания произвольного состояния через чисто-функциональный код — который по определению не обладает скрытыми (implicit) сайд-эффектами. Это явное управление состоянием без нудной потребности всё это выписывать вручную (и читать потом, опять же). Вот как будто у вас в (чисто-функциональном) коде появляются некие скрытые от взора переменные, но компилятор бьёт по рукам за попытки незаметно вкорячить туда нечто ужасное. К Singleton это не имеет даже отдалённого отношения.
Скажем так, один из прямых мотивирующих примеров для монады State (либо чего-то похожего) — это функцияrandom, которая в чисто функциональном подходе принимает дополнительным аргументом внутреннее состояние PRNG (например, Mersenne Twister), и возвращает псевдослучайные биты вместе с новым состоянием генератора. Каким боком здесь Singleton — ума не приложу.
ГоФ — это просто примеры того как можно писать (а можно и не писать), просто собрание знаний. А человек который игнорирует знания или слишком заносчив чтобы извлекать их (читай дурак), или слишком ленив (см выше), или не способен (см выше).
Вы так нечётко выражаетесь, что вам сложно возразить. Игнорировать знания MS Visual Basic 6.0 — это признак тупости/лени, или нет? Игнорировать знания закона Ома — это признак тупости/лени, или нет?
Квантовая механика — это просто пример того как можно объяснить (а можно и не объяснить) фотоэффект, или нет? Астрология — это просто собрание знаний о якобы эффектах небесных светил, или целая дисциплина с множеством теорий? Можно ли её игнорировать как бесполезную чепуху, или нет? По каким критериям делается решение из предыдущего вопроса?
Вы упускаете слишком много важных деталей, получая крайне хромые обощения.
Странный вопрос. Поосторожнее с argumentum ad numerum, он ошибочен.
В общем, не могу знать, убедит вас это или нет, но вот как бы список компаний, которые так или иначе смогли применить Хаскель, что называется, в продакшене™: www.haskell.org/...ell_in_industry
Это ровным счётом ничего не говорит о самом языке (потому что практическое применение идеи всегда вторично её пониманию), но, возможно, как-то поможет понять ответ на заданный вопрос.
Я позволю себе более популярно прорезюмировать этот... комок информации от Павла, и так сказать, уложить его в контекст всего треда.
Вот в самом деле, откройте блог Эдварда Зи Янга, весьма яркого апологета функционального программирования вообще (не путать с процедурным) и чисто-функционального языка Haskell в частности.
Что мы там видим? Все 23 каноничных GoF патерна в переводе на Хаскель. Не удивительно. Как выглядят собственно переводы?.. Читаем, это:
функции и лямбда-функции,
функции,
тайпклассы,
композиция функций,
ленивые списки,
функции,
монада,
... снова функции.
Все двадцать три чёртовых патерна переведены на кристально простой язык side-effectless функций и их композиций; половина попросту упразднена к функциям. Ну ещё там пара пустяков вроде алгебраических типов данных, параметрического полиморфизма и тайпклассов. Это всё простые как доска концепции — но нужно уметь выбросить из головы заветное ООП, чтобы их понять (иначе получается каша).
Вот в этом, в общем-то, и суть всего треда. То, над чем горячо спорят эксперты объектно-ориентированного дизайна годами, решается без всякого ООП простейшими функциями высшего порядка и карированием. Концептуальная сложность этих решений сравнима со сложностью, уж простите, извлечения подсохшего муконазального секрета из носу.
Вот именно поэтому о GoF нужно вытирать ноги. Всё понимание, что вы будете мучительно (годами) оттуда извлекать, можно получить даже не заметив за две недели изучения функционального программирования. Рекомендую.
ООП, развенчание стереотипов-наследовать нельзя обобщать
ООП, развенчание стереотипов-наследовать нельзя обобщать
Ещё такое же мнение от автора превосходного блога:
Аргументы у него всё те же, уже изложенные в этом треде:
- культивация квадратно-гнездового «внутрикоробочного» мышления;
- рассуждение в терминах известных решений, а не задачи;
- подгонка требований в руках под имеющийся молоток (который к тому же оказывается непереносимым между языками),
и т.п.ООП, развенчание стереотипов-наследовать нельзя обобщать
Кому лень совершенствоваться и впитывать новые идеи — достаточно.
Вы провели весьма неисчерпывающий поиск, мягко говоря.
ООП, развенчание стереотипов-наследовать нельзя обобщать
Эээ... а каких вы хотели?
Когда люди обсуждают проблемы c X, которых нет в аналоге Y — я считаю полезным посоветовать Y. Вы находите это неправильным?..
И да, если ваша задача — описать некий конкретный снег (на произвольном языке), то выбор чукотского будет, очевидно, выигрышным.
Хорошо. Ладно.Это ad populum, и это ошибочный аргумент.
ООП, развенчание стереотипов-наследовать нельзя обобщать
На что нужно ставить деньги, ещё раз?
Сформулируйте чётче. Каков completion criterion? При выполнении каких условий/событий/проверок я получу свои (умноженные) деньги обратно?
Повторюсь: во многих реальных задачах моделирование выполняется проще с использованием алгебраических типов данных и тайплассопедии. Этому есть фактические подтверждения.
А у вас каша в голове, вы даже риторический вопрос поставить не можете. Только подвесить — чтоб шатался в нужную сторону. // это мой ответ на ваш красочный аргумент к личности
ООП, развенчание стереотипов-наследовать нельзя обобщать
Мне это говорит только о том, что
Q.deferred
не комплаит спецификациюpromiseaplus
, И не предоставляет монадический интерфейс. Только и всего.В случае же, когда монадический интерфейс предоставляется (
jQuery.deferred
) рассуждать о нём применяя монадическую интуицию по-прежнему проще, чем без неё.ООП, развенчание стереотипов-наследовать нельзя обобщать
Операция
bind
в хаскеле принимает только два аргумента; в случае с`Future a`
это будет сам`Future a`
, и его продолжение (функция`a -> Future b`
). Обработку ошибок нужно как бы модульно добавлять другими средствами (MaybeT
,EitherT
, например) — ну либо вообще не добавлять, если используемые действия возвращают результаты без ошибок.Поэтому сразу так не совсем понятно, что ваш код выведет. Если всё-таки подсмотреть в спеке, что за два аргумента у
.then
, то ответ прост (чисто из монадной интуиции): зависимо от того, как отрезолвится первоначальныйpromise
, появится один из двух алертов.ООП, развенчание стереотипов-наследовать нельзя обобщать
Если это шутка — то не смешная. Откройте наконец документацию, что за детский сад вы строите.
Да, это идеальный пример вы приводите. Зачем мне читать 3 страницы реквайрментов к интерфейсу, когда я могу просто понять, что здесь монада? А это и есть монада; просто почему-то большая часть спеки говорит о посылках сообщений™ и инвариантах внутреннего состояния. О том, что в случае Хаскеля запишется в типах и проверится автоматически компилятором.
Давайте ещё так: если мы говорим о скоплениях электронов в кристалле кремния, то зачем вы используете такие слова как вызов-метода-у-чего-то-там? Неужели вы заметили, что новые абстракции — это единственный работающий способ совладать с нарастающей сложностью ПО?..
Если посмотреть на качественный скачок от указателей-и-структур до методов-и-интерфейсов — сразу видно, насколько хорошо помогает удачная и простая абстракция. Тайпклассопедия даёт более ёмкие абстракции для качественно превосходящего построения интерфейсов. Это следующий шаг в проектировании ПО после ООП.
На14-м слайде вы забываете, что моделируются типы далеко за пределами объектов. В современных языках любят поутверждать, что якобы «всё есть объект» и можно писать
print("68656c6c6f".decode('hex'))
— но это не так; есть полно задач (численные симуляции, например), объектные модели для которых выглядят отвратительно, натянуто и ненатурально (в лучшем случае всё ограничивается парочкой God Object-ов без перспектив дальнейшей детализации). Тайпклассопедия даёт возможности более широкого моделирования. Я знаю, как перевестиMonoid
на тот же С++, но сформулироватьAlternative
для ООП парадигмы уже как-то трудно.Понимаете, да? Перевод GoF патернов в FP парадигму тривиален; в тайпклассопедии нет
Strategy
(потому что в FPStrategy
это просто функция) — но перевод сегодняшних тайпклассов вродеComonad
обратно в парадигму ООП уже совсем не тривиален (несмотря на то, что концептуально это по-прежнему простые вещи). Более того, на C++, например, невозможно даже записать интерфейсMonad
в общем случае; можно только повторять снова и снова под каждый конкретный случай (в точности это и происходит сstd::future
). Это так отчасти из-за недостатков системы типов (а именно, если я правильно понимаю: из-за отсутствия rank-n types).В общем, вашу цитату я всё равно не понимаю (на правило вывода, кстати, она тоже не похожа: в правилах вывода имеются 1) аксиомы 2) предпосылки 3) следствия), и, в общем-то, ваше дело, какими абстракциями в своей работе пользоваться. Но на мой взгляд, вы сильно теряете, отказываясь от тайпклассопедии.
ООП, развенчание стереотипов-наследовать нельзя обобщать
Вы серьезно недооцениваете GHC. Его делали в Microsoft Research.
ООП, развенчание стереотипов-наследовать нельзя обобщать
...
ООП, развенчание стереотипов-наследовать нельзя обобщать
Не думаю, что здесь подходящее место, чтобы начинать это объяснять — в сети есть уйма обучающих руководств по этой теме; можете начать хоть с той же haskellwiki, или с атлассиановской тайпклассопедии (для Scala).
Но есть поучительный момент, в том, что, например, то же красно-чёрное дерево — это
Functor
(отношение вида IS A — не наследование!), такжеFoldable
иMonoid
. Можно сделать иMonad
, но это будет как-то не очень осмысленно.Хороший пример монадического интерфейса — это
Future
, с операцией.then()
(.ContinueWith()
в .NET) в качестве монадической операции.Вообще, по многим отчётам, тайпклассопедия в разы упрощает дизайн интерфейсов:
В отличие от этой вашей GoF.ООП, развенчание стереотипов-наследовать нельзя обобщать
Давайте скажем так: есть задачи (которые можно формально поставить), и есть их решения. Есть плохо понятые задачи (без полных формализаций), и настолько же плохо понятые решения.
ООП, развенчание стереотипов-наследовать нельзя обобщать
И как это отвечает хоть на один мой вопрос?..
И что вы вот это за цитату приводите всё время, позвольте в конце концов поинтересоваться? К чему она?
Гоу в настолки!
mfw
ООП, развенчание стереотипов-наследовать нельзя обобщать
*здесь ДОУ зачем-то создал дубль моего комментария, вместо того чтобы отредактировать предыдущий. и вот как удалить?.. плохо сделано.
ООП, развенчание стереотипов-наследовать нельзя обобщать
А чем огурец стакан чашка витаминов?..
Простите, мне непонятен этот вопрос. Давайте вместо отличий попробуем начать со сходства? По-моему, его там вовсе нет.
Но могу, конечно, ответить, зачем придумали монаду State. Это стройный алгебраический способ контролировать сайд-эффекты. Либо, если хотите, эдакий абстрактный синтаксический сахар для элегантного протягивания произвольного состояния через чисто-функциональный код — который по определению не обладает скрытыми (implicit) сайд-эффектами. Это явное управление состоянием без нудной потребности всё это выписывать вручную (и читать потом, опять же). Вот как будто у вас в (чисто-функциональном) коде появляются некие скрытые от взора переменные, но компилятор бьёт по рукам за попытки незаметно вкорячить туда нечто ужасное. К Singleton это не имеет даже отдалённого отношения.
Скажем так, один из прямых мотивирующих примеров для монады State (либо чего-то похожего) — это функция
random
, которая в чисто функциональном подходе принимает дополнительным аргументом внутреннее состояние PRNG (например, Mersenne Twister), и возвращает псевдослучайные биты вместе с новым состоянием генератора. Каким боком здесь Singleton — ума не приложу.Вы так нечётко выражаетесь, что вам сложно возразить. Игнорировать знания MS Visual Basic 6.0 — это признак тупости/лени, или нет? Игнорировать знания закона Ома — это признак тупости/лени, или нет?
Квантовая механика — это просто пример того как можно объяснить (а можно и не объяснить) фотоэффект, или нет? Астрология — это просто собрание знаний о якобы эффектах небесных светил, или целая дисциплина с множеством теорий? Можно ли её игнорировать как бесполезную чепуху, или нет? По каким критериям делается решение из предыдущего вопроса?
Вы упускаете слишком много важных деталей, получая крайне хромые обощения.
Остальное мне нечем прокомментировать.
ООП, развенчание стереотипов-наследовать нельзя обобщать
Странный вопрос. Поосторожнее с argumentum ad numerum, он ошибочен.
В общем, не могу знать, убедит вас это или нет, но вот как бы список компаний, которые так или иначе смогли применить Хаскель, что называется, в продакшене™: www.haskell.org/...ell_in_industry
Это ровным счётом ничего не говорит о самом языке (потому что практическое применение идеи всегда вторично её пониманию), но, возможно, как-то поможет понять ответ на заданный вопрос.
ООП, развенчание стереотипов-наследовать нельзя обобщать
Я позволю себе более популярно прорезюмировать этот... комок информации от Павла, и так сказать, уложить его в контекст всего треда.
Вот в самом деле, откройте блог Эдварда Зи Янга, весьма яркого апологета функционального программирования вообще (не путать с процедурным) и чисто-функционального языка Haskell в частности.
Что мы там видим? Все 23 каноничных GoF патерна в переводе на Хаскель. Не удивительно. Как выглядят собственно переводы?.. Читаем, это:
- функции и лямбда-функции,
- функции,
- тайпклассы,
- композиция функций,
- ленивые списки,
- функции,
- монада,
- ... снова функции.
Все двадцать три чёртовых патерна переведены на кристально простой язык side-effectless функций и их композиций; половина попросту упразднена к функциям. Ну ещё там пара пустяков вроде алгебраических типов данных, параметрического полиморфизма и тайпклассов. Это всё простые как доска концепции — но нужно уметь выбросить из головы заветное ООП, чтобы их понять (иначе получается каша).Вот в этом, в общем-то, и суть всего треда. То, над чем горячо спорят эксперты объектно-ориентированного дизайна годами, решается без всякого ООП простейшими функциями высшего порядка и карированием. Концептуальная сложность этих решений сравнима со сложностью, уж простите, извлечения подсохшего муконазального секрета из носу.
Вот именно поэтому о GoF нужно вытирать ноги. Всё понимание, что вы будете мучительно (годами) оттуда извлекать, можно получить даже не заметив за две недели изучения функционального программирования. Рекомендую.
Гоу в настолки!
как это не умеет?! делай обычную беседу на двоих, потом плюсик → Add people; УМВР
Гоу в настолки!
Могу познакомить с гейммастером Savage Worlds (похожего формата игра). D&D старо и не в моде, понимаете ли.