Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

ООП, развенчание стереотипов-наследовать нельзя обобщать

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Доброго дня, уважаемые гуру программирования.

Освежал недавно своё понимание базовых принципов ООП столкнулся с резкой критикой наследования как базового принципа . серьёзные люди очень рекомендуют минимизировать наследование в своём коде. при этом большинство книг всячески расхваливают наследование и создают длинные цепочки наследования для иллюстрации этого принципа. Подозреваю, что наследование также любят пишущие в анонсах «Разработчик-практик с опытом работы в IT сфере более 1,5 лет.»

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

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn

Схожі топіки

Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

На наследование нужно ввести мораторий и временный запрет на 2 года что бы отбить все порывы его неправильного использования. Ох и натерпелся я в одном проекте от польских студентов этого наследования. Как только в двух конкретных классах было немного общего кода, сразу появлялся их общий абстрактных класс. Это был мрак.

лет 10-20 назад все упирались в наследование. сейчас так не модно. сейчас модно куча страшных слов типа клоуд, биг дата, нет Сиквелю, и тд. как раньше люди жили без этого? в софтверной индустрии есть такой феномен — каждые 5-10 лет кто-то или инициативная группа придумывает нечто что обещает «революцию», обьявляя все что было до этого устаревшим или нерациональным. иногда это действительно так, а иногда не очень , и в революциях этих больше маркетинга и цели продвигать именно свои продукты. где сейчас джава апплеты, COM, CORBA, EJB? а когда-то это было тоже модно и революционно.

наследование? место для него есть, но чрезмерное использование наследования я считаю злом, особенно когда из 5 унаследованных методов 4 кидают исключение «фича нот имплементед» потому что разработчик унаследованного класса не знает что они должны делать в контексте данного класса (оказывается что ничего), а поскольку родитель абстрактный, то переопределять обязательно. и такое сплошь и рядом! facepalm: я не говорю уже про копи-паст программирование как самую распространенную форму «повторного использования кода» lol:
и это не джуниоры пишут, это такое пишут тим лиды с многолетним опытом и в возрасте за 40 facepalm:

Есть такой метод определения сеньорности программиста: заходит он в комнату, а ты ему под ноги кидаешь книгу GoF и смотришь. Если вытрет ноги — значит, сеньор; если просто переступит — ну, нормальный девелопер. А вот если возьмёт и начнёт читать — значит, джун, и место ему в опенспейсе исключительно возле параши.

заходит он в комнату, а ты ему под ноги кидаешь книгу GoF и смотришь. Если вытрет ноги — значит, сеньор; если просто переступит — ну, нормальный девелопер. А вот если возьмёт и начнёт читать — значит, джун
Это такой способ определить «23-летнего синьора» (джуна, который думает что он синьор, который пишет без багов).
Хорошие книги (те которые рекомендуют через десятки лет после их публикации) надо перечитывать раз в 2-5 лет и каждый раз найдете что-то новое для себя.
К слову, вы сколько раз читали ГоФ? Сколько из этих раз в оригинале? (Моя ставка что ответ будет 0 из 0)

А сколько вы ставили? Куда за деньгами подходить?

А сколько вы ставили? Куда за деньгами подходить?
Если бы надо было приходить, то ответ был бы 2 числа, а так 0 из 0, пока, выигрывает :)

Ну давайте так — я читал GoF (на обоих языках как в смысле перевода, так и в смысле C++/Smalltalk), читал продолжение Влиссидеса, читал его статьи; читал маэстро Коплиена с его чудовищной книгой и FAST по наводке оттуда же (можно считать основанием DDD, если вы любите аббревиатуры). Я читал все книги Герба Шмидта и ряд его статей (бессмысленно потерянное время), продирался сквозь публикации семинаров по теме (тысячи их). Я читал маэстро Норвига, и я читал многие другие замечательные статьи. Про Коплиена точно могу сказать, что читал не менее пяти раз (т.к. только с пятого раза понял), но и GoF, очевидно, более нуля.

Теперь я могу получить свои деньги?

P.S. забыл упомянуть Карделли. Жаль, что адепты ООП так редко его читают.

Теперь я могу получить свои деньги?
Всю сумму на которую спорили :)
я читал
Теперь бы еще убрать «я» и научится выделять важные моменты в словах собеседников.

И какой же важный момент был в словах моих собеседников?

Важный момент был здесь один. Джун где-то услышал аббревиатуру GoF и решил блеснуть знаниями. Но был безжалостно раздавлен и отправлен читать заново K&R

Кстати, Pavlo, вы получили причитающийся вам выигрыш? А то языки чесать на кофепоинтах все сильны, а как доходит до дела — «я не я и кобыла не моя»...

Нет, конечно. Остаётся довольствоваться сомнительным удовлетворением гипертрофированного надглоточного ганглия.

Вынужден согласиться. Удовлетворение сомнительное..

Судя по Вашему высказыванию выше это очень сомнительно, как по мне...

Есть такой метод определения сеньорности программиста: заходит он в комнату, а ты ему под ноги кидаешь книгу GoF и смотришь. Если вытрет ноги — значит, сеньор; если просто переступит — ну, нормальный девелопер. А вот если возьмёт и начнёт читать — значит, джун, и место ему в опенспейсе исключительно возле параши.
Мне вот гораздо интересней, из какого из выше перечисленных ресурсов вы почерпнули описанную Вами технику? Ну или как Вы смогли сами прийти к таким умозаключением после прочтения перечисленного материала?

О, ваши сомнения делают мне больно. За что вы так со мной? Что плохого я вам сделал?

Если вы изыщете у себя свободного времени для хотя бы беглого ознакомления с указанными источниками, вам станет совершенно очевидно, что укзанной выше техники в них нет и быть не может. Её познают исключительно на медитациях с хоровым распеванием мантры AAD GURAY NAMEH и жеванием листьев erythróxylum cóca. Свальный грех и старое доброе ультранасилие — по желанию.

Ладно, Паша, я все таки надеюсь, что и этот коммент, и тот, что выше был неудачным троллингом, иначе просто ума не приложу, как Вы смогли найти себя в IT... ну или как Вас нашли...

P.S.: распевание мантры и жевание листиков звучит забавно конечно, улыбнуло :)

Забавно??? А вам что, на вашем проекте, удается обходиться без листьев erythróxylum cóca?... Гм... Дайте угадаю... Одно из двух, либо вы троль либо работаете не в IT сфере.

К сожалению я не вписываюсь в Ваше представление об IT сфере, поэтому к какой категории Вы отнесете меня, меня честно говоря не интересует.

Скорее не «к сожалению», а «к счастью»

Это смотря с чьей стороны на коммент посмотреть ;)

Надежда — наш компас земной, Ира! А для того, чтобы найти себя в IT, надо сначала там себя потерять.

Посылаю вам лучей постигания дзена.

Я позволю себе более популярно прорезюмировать этот... комок информации от Павла, и так сказать, уложить его в контекст всего треда.

Вот в самом деле, откройте блог Эдварда Зи Янга, весьма яркого апологета функционального программирования вообще (не путать с процедурным) и чисто-функционального языка Haskell в частности.

Что мы там видим? Все 23 каноничных GoF патерна в переводе на Хаскель. Не удивительно. Как выглядят собственно переводы?.. Читаем, это:

  • функции и лямбда-функции,
  • функции,
  • тайпклассы,
  • композиция функций,
  • ленивые списки,
  • функции,
  • монада,
  • ... снова функции.
Все двадцать три чёртовых патерна переведены на кристально простой язык side-effectless функций и их композиций; половина попросту упразднена к функциям. Ну ещё там пара пустяков вроде алгебраических типов данных, параметрического полиморфизма и тайпклассов. Это всё простые как доска концепции — но нужно уметь выбросить из головы заветное ООП, чтобы их понять (иначе получается каша).

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

Вот именно поэтому о GoF нужно вытирать ноги. Всё понимание, что вы будете мучительно (годами) оттуда извлекать, можно получить даже не заметив за две недели изучения функционального программирования. Рекомендую.

Я, как бы уже не первый год слышу о красоте функционального программирования , в часности о языке Хаскель (насколько я понял он истинный true, а всякие F# - это уже переводняк).
Я ничего против ф-ционального программирования не имею, но у меня вот простой вопрос, сколько из существующих + реально работающих OS, текстовых/графических редакторов, серверов баз данных... написано на языка Хаскель или другом «True-functional language» ?

Странный вопрос. Поосторожнее с argumentum ad numerum, он ошибочен.

В общем, не могу знать, убедит вас это или нет, но вот как бы список компаний, которые так или иначе смогли применить Хаскель, что называется, в продакшене™: www.haskell.org/...ell_in_industry

Это ровным счётом ничего не говорит о самом языке (потому что практическое применение идеи всегда вторично её пониманию), но, возможно, как-то поможет понять ответ на заданный вопрос.

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

Единственное , что заинтересовало —
«Intel
Intel has developed a Haskell compiler as part of their research on multicore parallelism at scale.»
Вот если интел сделает Хаскель компилер, это будет серъезный толчек для развития языка.

Вот если интел сделает Хаскель компилер, это будет серъезный толчек для развития языка.

Вы серьезно недооцениваете GHC. Его делали в Microsoft Research.

Intel не делает компилятор, Intel делает backend для GHC. И лично мне не очень понятно, каким образом их кодогенератор даст толчёк уже поехавшему языку.

Класична помилка плюсиста: “на $FAVOURITE_LANGUAGE має бути написане все”.

А скільки

реально работающих OS, текстовых/графических редакторов,
написано на Джава?
А скільки
серверов баз данных
написано на PHP?
А скільки веб-серверів написано на плюсах?
А скільки реальних ядер написано не на Сі, а на плюсах?

Я не кажу що i на чому повинно бути написано, я лише прошу привести приклади. А ви лише ставите зворотне питання.
P.S. OpenOffice написаний на Java, вас це влаштуе?

Ну не знаю, протиставляти мови, які просто в різних вагових категоріях щодо підтримки менеджменту та бізнесу — це нечесно; я ж хотів показати, що навіть при багатомільйярдній підтримці корпорацій та чудовій репутації навіть на С++ так і не написано серйозних ядер ОС чи веб-серверів (nginx та apache обидва на чистому Сі).

Якщо ж відволіктись від підтримки корпорацій, то на Хаскелі написані pugs (інтерпретатор Perl6), pandoc (комбайн перетворення форматів даних), darcs (система контролю версій) + купа всяких невеликих утиліт типу xmlgen. Якщо ж про гіківське, то є XMonad (непоганий window manager для XWindow, користуюсь і задоволений), є текстовий редактор Yi (непоганий клон vi, але не користуюсь), багато хто пише мілкі веб-сервери на Yesod/Happstack/Snap (користуюсь Happstack). На Ocaml, родичі Хаскеля, написані Frama-C (фреймворк статичного аналізу сішного коду), 0install, gitfs, це основа для експорту коду із автоматизованих theorem proovers (Coq, Isabelle/HOL, Agda), якими часто користуються при формальній верифікації (seL4 — формально верифіковане ядро ОС, compcert — формально верифікований компілятор Сі, по суті, написаний на Coq, з коду якого генерується код на Ocaml).

Щодо ОС, то можу назвати проекти unikernels (тобто спеціалізованих однозадачних ядер, як правило, призначених для віртуалізації, як правило, на xen): MirageOS (OCaml on Xen), HaLVM (Haskell on Xen), і т. д.

Хаскель/функціональщина також часто використовується в фінансових колах (Barkleys; якась компанія, в якій працював SPJ і в якій кодобаза була на мільйони рядків на Хаскелі; Jane Street користується в основному OCaml).

Окремий пункт — Erlang, який давно завоював прекрасну репутацію в продуктах, яким потрібна чудова надійність і відмовостійкість (сервер відео ErlyVideo, всякі телекомунікаційні свічі).

Тобто питання в ніші і знайомстві із такими продуктами. Мейнстрим легко створює враження, що існує тільки він.

P.S. OpenOffice початково був написаний на плюсах, і лише далі став все більше покладатись на Java, а сучасний LibreOffice у цю солянку ще й притягує Python, так що «написаний на Java» це не зовсім точно.

OpenOffice написаний на Java
Че?
Я его лично на FreeBSD портировал в свое время.
Там 25млн. строк чистого C++ поверх STL и ассемблерных ускорителей.
Ява там сугубо для интерфейсов к кое-чему и вообще необязательна ни разу по сути. Кстати 10 лет тому назад ее под FBSD и не было.
А ОО я собрал и к релизу 1.0 он работал.
Что мы там видим? Все 23 каноничных GoF патерна в переводе на Хаскель.
Вы думаете если вы ходите, то вы не сидите? ©
можно получить даже не заметив за две недели изучения функционального программирования
Можно получить, а можно и не получить
без всякого ООП простейшими функциями высшего порядка и карированием.
А вот тут веселье:
на практике, изучатели за 2 недели частенько путаеют каррирование и чакстичное применение (или не могут обяснить разницу).
«Матерые ФПшники» (многие из тех с кем я пересекался) обясняют монаду как «монада — это монада», а потом начинают отшучиваться про рекурсию и тд.
Все двадцать три чёртовых патерна переведены на кристально простой язык side-effectless функций и их композиций; половина попросту упразднена к функциям.
23-1 (Singleton. Unnecessary; ) Нужно или не нужно — это решается в конкретной ситуации, много из ГоФ паттернов «не нужно» в зависимости от вашего стиля программирования, а нет от ООП или ФП.
Кстати, поясните чем Singleton так сильно отличается от State Monad и нафик ее (State Monad) придумали?
.
ГоФ — это просто примеры того как можно писать (а можно и не писать), просто собрание знаний. А человек который игнорирует знания или слишком заносчив чтобы извлекать их (читай дурак), или слишком ленив (см выше), или не способен (см выше).
Кстати, поясните чем Singleton так сильно отличается от State Monad и нафик ее (State Monad) придумали?

А чем огурец стакан чашка витаминов?..

Простите, мне непонятен этот вопрос. Давайте вместо отличий попробуем начать со сходства? По-моему, его там вовсе нет.

Но могу, конечно, ответить, зачем придумали монаду State. Это стройный алгебраический способ контролировать сайд-эффекты. Либо, если хотите, эдакий абстрактный синтаксический сахар для элегантного протягивания произвольного состояния через чисто-функциональный код — который по определению не обладает скрытыми (implicit) сайд-эффектами. Это явное управление состоянием без нудной потребности всё это выписывать вручную (и читать потом, опять же). Вот как будто у вас в (чисто-функциональном) коде появляются некие скрытые от взора переменные, но компилятор бьёт по рукам за попытки незаметно вкорячить туда нечто ужасное. К Singleton это не имеет даже отдалённого отношения.

Скажем так, один из прямых мотивирующих примеров для монады State (либо чего-то похожего) — это функция random, которая в чисто функциональном подходе принимает дополнительным аргументом внутреннее состояние PRNG (например, Mersenne Twister), и возвращает псевдослучайные биты вместе с новым состоянием генератора. Каким боком здесь Singleton — ума не приложу.

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

Вы так нечётко выражаетесь, что вам сложно возразить. Игнорировать знания MS Visual Basic 6.0 — это признак тупости/лени, или нет? Игнорировать знания закона Ома — это признак тупости/лени, или нет?

Квантовая механика — это просто пример того как можно объяснить (а можно и не объяснить) фотоэффект, или нет? Астрология — это просто собрание знаний о якобы эффектах небесных светил, или целая дисциплина с множеством теорий? Можно ли её игнорировать как бесполезную чепуху, или нет? По каким критериям делается решение из предыдущего вопроса?

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

Остальное мне нечем прокомментировать.

*здесь ДОУ зачем-то создал дубль моего комментария, вместо того чтобы отредактировать предыдущий. и вот как удалить?.. плохо сделано.

Игнорировать знания MS Visual Basic 6.0 — это признак тупости/лени, или нет? Игнорировать знания закона Ома — это признак тупости/лени, или нет?
Есть такие штуки «данные», «информация» и «знания». Знания — это информация + правила вывода.
Либо, если хотите, эдакий абстрактный синтаксический сахар для элегантного протягивания произвольного состояния через чисто-функциональный код
От я и говорю: Вы думаете если вы ходите, то вы не сидите? ©

И как это отвечает хоть на один мой вопрос?..

И что вы вот это за цитату приводите всё время, позвольте в конце концов поинтересоваться? К чему она?

И что вы вот это за цитату приводите всё время, позвольте в конце концов поинтересоваться? К чему она?
У любого подхода есть свои ограничения и (типовые) способы их решения, зачастую эти решения пересекаются, но некоторые проблемы по факту заменены на другие.
К примеру, таже стратегия есть (именно есть, а не упразднена) и в ООП и в ФП, она описанна в книге о которую вы предлагали вытерать ноги, чтобы продемонстрировать свою синьорность (зрелость как специалиста)
И как это отвечает хоть на один мой вопрос?..
Это дает вам правила вывода. И отвечает оно на ваши вопросы, где-то так же как и ГоФ (самое смешное что сейчас это не стеб)

Так намного понятнее. Спасибо

Что вы имеете в виду под паттерном Strategy который есть в ФП? Не встречал. Пожалуйста приведите пример или дайте ссылку.

Что вы имеете в виду под паттерном Strategy который есть в ФП? Не встречал. Пожалуйста приведите пример или дайте ссылку.
Начнем со ссылки:
www.ibm.com/...-ft10/#listing6

Давайте скажем так: есть задачи (которые можно формально поставить), и есть их решения. Есть плохо понятые задачи (без полных формализаций), и настолько же плохо понятые решения.

Богдан, будьте так добры, напрягитесь и объясните, что вы всетаки имеете в виду. Предыдущий комментатор не поленился и написал вам развернутый ответ. В вашей экономии слов мне видятся менторский тон и некоторое неуважение к собеседнику.

Информация и правила вывода — это логика, а не знания.

Информация и правила вывода — это логика, а не знания.
Ну допустим вы не правы, но это не моя проблема.

Допустим, он прав — что теперь?

«Матерые ФПшники» (многие из тех с кем я пересекался) обясняют монаду как «монада — это монада», а потом начинают отшучиваться про рекурсию и тд.

Не думаю, что здесь подходящее место, чтобы начинать это объяснять — в сети есть уйма обучающих руководств по этой теме; можете начать хоть с той же 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.
В отличие от этой вашей GoF.
Не думаю, что здесь подходящее место, чтобы начинать это объяснять — в сети есть уйма обучающих руководств по этой теме
Это еще одно очень распространенное объяснение что такое монада :)
Хороший пример монадического интерфейса — это Future, с операцией .then() (.ContinueWith() в .NET) в качестве монадической операции.
Если мы говорим про что-то вроде promisesaplus.com , то зачем вы использовали такие слова как монадический-что-то-там? Это просто посыл сообщения/вызов метода у объекта.
.
Вообще, по многим отчётам,
Не столько отчетам, сколько -заганжованым- this-was-my-journey.
«good OO-style», lots of inheritance and code reuse
В отличие от этой вашей GoF.
Именно ГоФ я последний раз читал лет 6-7 назад, но насколько я помню, то там говорится что наследование — это не очень хорошо.
.
с атлассиановской тайпклассопедии (для Scala).
Особенно мне понравился 14-й слайд typeclassopedia.bitbucket.org/#slide-14 Он демонстрирует такую «простоту» до которой той самой ГоФ еще копать и копать.
.
P.S. надеюсь это сообщение прояснило к чему была цитата
Что мы там видим? Все 23 каноничных GoF патерна в переводе на Хаскель.
Вы думаете если вы ходите, то вы не сидите? ©
Это еще одно очень распространенное объяснение что такое монада :)

Если это шутка — то не смешная. Откройте наконец документацию, что за детский сад вы строите.

Если мы говорим про что-то вроде 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) следствия), и, в общем-то, ваше дело, какими абстракциями в своей работе пользоваться. Но на мой взгляд, вы сильно теряете, отказываясь от тайпклассопедии.

Да, это идеальный пример вы приводите. Зачем мне читать 3 страницы реквайрментов к интерфейсу, когда я могу просто понять, что здесь монада?
Вот вы знаете что это монада, спеку вы не читали. Скажыте что выведет этот код:
promise
.then(function(){return 1;}, function(){return 2;})
.then(function(){alert('win');}, function(){alert('fail');});
Подсказка: в зависимости от библиотеки/спецификации будет или win, или fail. Или компилятор хаскелла не позводит запрограммировать одно из поведений?
.
(потому что в FP Strategy это просто функция)
От в том то и проблема, что не просто функция. Стратегия — это __что-то типа__ «частичнопримененной функции».

Операция bind в хаскеле принимает только два аргумента; в случае с `Future a` это будет сам `Future a`, и его продолжение (функция `a -> Future b`). Обработку ошибок нужно как бы модульно добавлять другими средствами (MaybeT, EitherT, например) — ну либо вообще не добавлять, если используемые действия возвращают результаты без ошибок.

Поэтому сразу так не совсем понятно, что ваш код выведет. Если всё-таки подсмотреть в спеке, что за два аргумента у .then, то ответ прост (чисто из монадной интуиции): зависимо от того, как отрезолвится первоначальный promise, появится один из двух алертов.

Поэтому сразу так не совсем понятно, что ваш код выведет. Если всё-таки подсмотреть в спеке, что за два аргумента у .then, то ответ прост (чисто из монадной интуиции): зависимо от того, как отрезолвится первоначальный promise, появится один из двух алертов.
jsfiddle.net/f1a8kgfp — fail
jsfiddle.net/LozL7a9f — win
В одном случае — это «монадическая интуиция», а в другом «монадическая фантазия».
Никакие монады вас не спасут от необходимости читать спеку.

Мне это говорит только о том, что Q.deferred не комплаит спецификацию promiseaplus, И не предоставляет монадический интерфейс. Только и всего.

В случае же, когда монадический интерфейс предоставляется (jQuery.deferred) рассуждать о нём применяя монадическую интуицию по-прежнему проще, чем без неё.

Мне это говорит только о том, что Q.deferred не комплаит спецификацию promiseaplus
В случае же, когда монадический интерфейс предоставляется (jQuery.deferred)
Ну как раз Q, в отличии от jQuery, поддерживает Promises/A+, так что пока монадическая интуиция вас подвела, хотя она может быть и проще.
А теперь риторический вопрос:
Какой суммой своих денег, а не денег «заказчика», вы готовы рискнуть, поставив на то что ваша «монадическая интуиция» будет соответствовать требованиям реального мира?
Какой суммой своих денег... вы готовы рискнуть, поставив на то что ваша «монадическая интуиция» будет соответствовать требованиям реального мира?

На что нужно ставить деньги, ещё раз?

Сформулируйте чётче. Каков completion criterion? При выполнении каких условий/событий/проверок я получу свои (умноженные) деньги обратно?

Повторюсь: во многих реальных задачах моделирование выполняется проще с использованием алгебраических типов данных и тайплассопедии. Этому есть фактические подтверждения.

А у вас каша в голове, вы даже риторический вопрос поставить не можете. Только подвесить — чтоб шатался в нужную сторону. // это мой ответ на ваш красочный аргумент к личности

В отличие от этой вашей GoF.
почитал и остальное тут. ых, не один тусовался на форумах функциональщиков, — а оно все и поныне там :)

Муть «Haskell» и иже с ним начиется с фундамента — теорката:

Хоар Ч. Э. Р. пишет: «Теория категория совершенно является наиболее обобщённой и абстрактной областью чистой математики [...]. Следствием высокой степени обобщённости и абстрактности является то, что теория практически не помогает в решении более конкретизированных проблем в рамках направлений, к которым применима теория. Это инструмент для теоретиков-идеалистов, а не для практиков [...]».
Отсюда следует, что и для информатики теория категорий скорее подойдёт для исследования теоретических аспектов, а не для разработки программных средств.
из «Мягкое введение в теорию категорий»
(вычислительный подход)
М. М. Фоккинг

вся красотень ФП хороша для постов, презентаций и холиваров.
и некоторых проектов, ессно, и некоторых команд упоротых функциональщиков.

Главные проблемы:
— Мышление человека итеративно
— Процесс разработки ПО обычно итеративен
— Основные задачи решаемые с помощью ПО — плохо формализованы (Математические инструменты не справляются со своими задачами. Стивен Вольфрам делает весьма важное наблюдение. Сама по себе идея описания поведения на языке математических уравнений оправдывает себя лишь в случае элементарного, даже примитивного поведения. И почти неизбежно она оказывается несостоятельной, как только модель поведения несколько усложняется. Ведь существует множество заурядных явлений, о которых теоретическим наукам, похоже, сказать практически нечего. Трудность математического представления явлений возрастает экспоненциально по мере повышения их уровня сложности.
Источник: Джамшид Гарадаеги «Системное мышление. Как управлять хаосом и сложными процессами»)

Это стройный алгебраический способ контролировать сайд-эффекты
да. и что с того, если проблемы программных проектов — не в этом :)

и так по многим другим преимуществам ФП:
предлагаются решения проблем, которые конечно есть, но обычно — НЕ являются приоритетными в большинстве случаев.

ну возьмем самый ужас — веб на php. Ну покажется в браузере пользователя нечто не то, из-за ошибки в коде, которая вызвана некими свойствами ЯП.
И? каковы убытки пользователя? каково время на поиск и исправление этой ошибки?
И какова будет стоимость проекта скажем на Haskell, особенно с учетом что «ТЗ» нет, «хочу вот нечто вот такое, покажите мне что-нибудь, а я выберу», стоимость внесения изменений и т.д.
А пресловутая «бизнес-логика» — она ведь кругом :)

холивары вокруг ФП сродни холиварам:
а на ЯП Х вывести «Hello world» проще!

А вот интересно ваше отношения к гибридным языкам вроде того же F#, есть ли у них преспективы.

F# это насколько помню модернизированный OCaml
он не гибридный. перспективы у него поэтому как и у OCaml.
вернее как и у всего ФП:
вечная маргинальная жизнь, применение в специфических проектах, в образовании, использование ортодоксами ФП, обкатка идей, конструкций, которые, в случае практической изящности будут перениматься другими ЯП.

Скала вполне в продакшене.
Мартин вообще первый, кто сумел для идиотов объяснить что же такое монада, и зачем она нужна.

Скала вполне в продакшене.
приведите удобную вам статистику о ее распространении в мире JVM

Достаточно зайти в раздел работа и вбить соотвецтвующие ключевые слова.
9 результатов против 98 для «java». В моем понимании это и есть «доля распространения». Немного конечно, но всяко луче чем 0 для обсуждаемого тут вами хаскеля.

Достаточно

Кому лень совершенствоваться и впитывать новые идеи — достаточно.

0 для обсуждаемого тут вами хаскеля.

Вы провели весьма неисчерпывающий поиск, мягко говоря.

Кому лень совершенствоваться и впитывать новые идеи — достаточно.

При чем тут «лень совершенствоваться» к ситуации на рынке ?
Вы провели весьма неисчерпывающий поиск, мягко говоря.

Проведите свой — предоставте нам ссылок на вакансии хаскелистов в Украине.
предоставте нам ссылок на вакансии хаскелистов в Украине.

С какой стати я должен вам палить годноту? Вам нужно — вы и ищите, я в вашем трудоустройстве не мотивирован совершенно никак.

Но да, вакансии в Украине есть. Как минимум одна была ;-)
Да и за пределами достаточно.
Знаете, как говорится: кто ищет — тот всегда найдёт.

Вы точно Хаскель программист а не Руби ? Это я так чисто для себя спрашиваю...

В моем понимании это и есть «доля распространения».
вакансии — это чьи-то желания, взять кого-то определенного. эти желания могут быть вызваны разными причинами. Hype cycle — никто не отменял.
эти желания могут быть вызваны разными причинами.

Помойму основная причина, это «мы используем этот язык», не ?
Hype cycle — никто не отменял.

Хайп для скалы был несколько лет назад, и помойму уже прошел.
Помойму основная причина, это «мы используем этот язык», не ?
не. точно — мы хотИМ(будущее время) использовать этот язык.
а об используЕМ(настоящее) — неизвестно.
успехи примемения — известны. о любом ЯП :)
насколько будУТ массовы — другой вопрос.
Хайп для скалы был несколько лет назад, и помойму уже прошел.
у нее однозначно перспективы лучше чем у Haskell, в плане массовости применения. мир JVM плюс мультипарадигменность — Одерски сделал выбор правильней некуда.
(ребята из Вроцлава — крупно обшиблись выбрав .NET для Nemerle. Хотя, говорят в итоге их в Microsoft взяли)

... жаль не сохранил ссылку, на какой-то крупный британский сайт вакансий. там статистика была за годы. я смотрел по Java, PHP, Python, Ruby

запомнилось — резкое уменьшение вакансий на границе 2008-2009 по Java. потом, в течение годика-двух — выход на докризисный урвень и далее «плато».
Ruby начало уменьшения где-то в 2011ом, 2012ом. и продолжающееся.
PHP стабильно растет. Python — кривая роста в общем такая же.

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

Но, ИМХО, в мире JVM есть «темная лошадка» под названием Groovy. Вакансий мало, потому что, слышал, ставят вакансию — Java, а в первый день работы — предлагают перейти на Groovy.

я к тому — что нужно учитывать «дефекты» этого показателя.

не. точно — мы хотИМ(будущее время) использовать этот язык.
а об используЕМ(настоящее) — неизвестно.
успехи примемения — известны.
Тут я согласен, но имхо, если после стольких лет разработки языка, все еще «хотим» то перспективы есть. Хаскель даже никто и не хочет (окромя пачки упоротых фанатов)
Но, ИМХО, в мире JVM есть «темная лошадка» под названием Groovy. Вакансий мало, потому что, слышал, ставят вакансию — Java, а в первый день работы — предлагают перейти на Groovy.

Я о таком не наслышан. Но я считаю, что толковому джависту изучить груви до состояния «можно чтото делать» — два дня. Со скалой так не выйдет, тем не мение, компании вполне набирают джавистов на дообучение.
толковому джависту изучить груви до состояния «можно чтото делать» — два дня
именно потому и нет смысла ставить в вакансию — «Groovy»
Со скалой так не выйдет
..., да, «junior Scala» — как-то не представляю :)
компании вполне набирают джавистов на дообучение.
не удивлюсь, если через пару лет в вакансиях Java будет стоять:
... Java 8 ...

а насчет дообучения на Scala... сомневаюсь очень. про ФП ее часть, что имеет смысл — «дообучать». ну вот все знают- джава джунов не берут. ну казалось бы — возьмите, дообучите. ФП с нуля ничем не быстрее в освоении.

мне так кажется что Scala — это как лейбл, сертификат — «супер-бупер программист!».
ведь не написано ж в вакансиях: Scala опыт — от 3ех лет :)

то бишь у большинства будет — первый реальный проект. так за что берут? за «Я асилил!».
нечто вроде статустности по размерам и окрасу «хвоста павлина».

а насчет дообучения на Scala... сомневаюсь очень. про ФП ее часть, что имеет смысл — «дообучать». ну вот все знают- джава джунов не берут. ну казалось бы — возьмите, дообучите. ФП с нуля ничем не быстрее в освоении.

В наших краях общепринято, что джун==бестолковый. В большинстве случаев оно так и есть. На западе с этим чуть по легче, например у нас амеры к себе в америках взяли амер студента-математика, без особого коммерческого опыта, писать какуюто там математику сходу на скале. И все вроде как довольны.
мне так кажется что Scala — это как лейбл, сертификат — «супер-бупер программист!».
ведь не написано ж в вакансиях: Scala опыт — от 3ех лет :)
то бишь у большинства будет — первый реальный проект. так за что берут? за «Я асилил!».
нечто вроде статустности по размерам и окрасу «хвоста павлина».

Я к этому отношусь больше как к поиску «своих». Тот кто пришел в ИТ только заради денег — не будет для себя интересоваться непопулярной технологией.

взяли амер студента-математика,
ну дык они ж там с функциональщины начинают :) им она в скале потому родная :)
приведите удобную вам статистику о ее распространении в мире JVM
и что это покажет? насколько вы всё равно не готовы её изучать?

забавная постановка вопроса...

вам привести список того что ВЫ не готовы изучать?

и что это покажет?
ничего конечно. упоротым верующим ничего кроме их догматов не показывает.

Я попрошу не путать апологетов/идеологов/популяризаторов с верующими.
В лучшем случае — пастор или священник, но совсем никак не верующий.

вам привести список того что ВЫ не готовы изучать?

Да, приведите — очень интересно узнать что-нибудь новое о себе.

Разъясню: adoption rate ровным счётом ничего не говорит в пользу/вред непосредственно технологии. Сколько экскаваторов KU-800 используется в мире? Два. Что это говорит об этой модели? Ничего.

... Потому что использовать популярность/известность/используемость в качества аргумента — это грубая ошибка. Популярность не возникает сама по себе — её рождают люди, которые видят по-настощему сильные стороны и соглашаются на риски/неудобства early adoption. А используя ad populum, вы сами себя заключаете в замкнутый круг, где популярность — следствие действий кого-то другого. Вы умышленно ставите себя, метафорически, в конец пищевой цепочки IT-технологий, с сильным опозданием подъедая остатки. Пока вы только смотрите статистику — кто-то эту статистику уже делает.

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

В общем, всего хорошего.

очень интересно узнать что-нибудь новое о себе.
вы уже так умнее всех на свете :)
Сколько экскаваторов KU-800 используется в мире? Два. Что это говорит об этой модели? Ничего.
это может говорить об их сильной специализации. а не «ничего».
отсюда — и невостребованность.
а также может говорить об их дороговизне. поэтому — не востребовано по такой цене
Популярность не возникает сама по себе — её рождают люди
а масло маслянное, да, откровение — популярный (лат. popularis, от populus — народ).
популярность — следствие действий кого-то другого
Scala — НЕ следствие действий кого-то другого? даровано Богом?
Вы умышленно ставите себя, метафорически, в конец пищевой цепочки
откуда вы знаете? телепат? или ad hominem?
Вы худлит тоже оцениваете по массовости?
а вы по тому что все плюются и говорят — графоман?
или
он великий писатель! но пока ни один издатель не оценил, и не нашлось ни одного мецената чтобы издать его нетленные труды...

признание — необходимое условие. не достаточное, но — не обходимое.
маргинальность, то есть — НЕпризнание, не является ни необходимым, ни тем более достаточным признаком гениальности, истинности.

Муть «Haskell» и иже с ним начиется с фундамента — теорката

На самом деле в Haskell теорката не больше, чем в Java — формальной семантики ООП от Карделли. Какие теоретико-категориальные понятия вам приходится вспоминать, когда вы пишете функционально? Функтор и монаду? Интерфейс с одним методом и интерфейс с двумя? Это, конечно же, очень усложняет разработку.

Если вы так хотите придраться к фундаменту, то начинайте с System F.

Теоркат не в Haskell. А в голове программирующего должен быть. Или появится свой, подобный. Кто говорит что он не нужен — либо неофит, либо обманщик
Как и GoF

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

Повторю свой вопрос — какие теоретико-категориальные понятия вам приходится вспоминать (изобретать), когда вы пишете функционально?

И давайте не менять свою точку зрения подобно флюгеру:

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

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

Повторю свой вопрос — какие теоретико-категориальные понятия вам приходится вспоминать (изобретать), когда вы пишете функционально?
чтобы прорабатывать упражнения из учебника — никакие.
чтобы читать и писать код претендующий на профессиональность — да почти все.
И давайте не менять свою точку зрения подобно флюгеру:
ФП не тождественно Haskell. Haskell не тождествен ФП.

Проектирование, моделирование не тождественно писательству.
Быть писателем — это не только грамотно писать на языке.

Haskell не является теоретико-категориальным языком.
Haskell является членом множества ФП. чистый он, грязный, или вообще гибридный — это другой вопрос.
Какая система типов, какова ее реализация — третий.
Нет необходимости в знании даже основ теории из брошюрки Пирса
Ложь. Любой мало мальски профессиональный хаскелист вам об этом скажет.
А как один пытавшийся им стать сказал о нем:
«Язык требующий прочтения несколько научных монографий каждый год — не годится для продакшна»

но, нет смысла дискутировать — любой кто серьезно брался — столкнется с этой проблемой.
или с маленьким типичным — «а что такое монада?». как в этой теме подметил Bogdan Shyiak

И как хорошо, что в мире есть неофиты, кодеры и теоретики,
есть четвертая категория — программисты. т.е. инженеры, практики.

Программист НЕ кодер — нонсенс. Это как писатель который не пишет.
Но, например, в ТОП комментаторов на доу — есть хоть один — писатель?

так вот чтобы не просто кодировать на Haskell, а быть профессиональным программистом пишущим на Haskell и нужен и теоркат, и изменение мышления в парадигме ФП.

Так же как
«GoF мышление» для ООП
Теория множеств для SQL

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

По другому — успешный программист отличается от начинающего или неуспешного наличием интуитивного мышления, «над кодом».
Может как-нибудь напишу подробнее статейку.

Для подумать же
Почему существует такая вещь как learning curve, и почему она разная для ЯП, фреймворков, технологий, ...

В третий раз спрошу — какие конкретно теоретико-категориальные понятия вам приходится вспоминать (изобретать), когда вы пишете функционально?

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

У вас талант отвечать не по существу и невпопад. Какое отношение ФП имеет к теории категорий? А чистота? А система типов? Напишите ещё рандомных слов, которые вам кажутся умными, это несомненно очень поможет диалогу.

Ложь. Любой мало мальски профессиональный хаскелист вам об этом скажет.

Ну тогда может он подскажет вам и ответ на первый вопрос моего комментария, а?

нет смысла дискутировать

Вы не дискутируете. Вместо аргументации вы постоянно срываетесь на категоричные утверждения, ad populum и апелляцию к ложному авторитету. В теме вы не разбираетесь — иначе мы бы уже говорили про пределы, дуальность, конструкции в категориях, свободные объекты и лемму Йонеды. Впрочем, в Haskell вы явно тоже ни в зуб ногой — иначе мы говорили бы про GHC, его расширения, прагмы, Cmm и STG; про транзакционную память и стратегии параллельного выполнения.

Теория множеств для SQL

Не теория множеств, а реляционная алгебра. Сомневаюсь, что так уж много DBA вообще слышали о лемме Цорна и смогут сформулировать аксиоматику ZFC.

В третий раз спрошу
да хоть в стопицотый. я не пишу на Haskell
У вас талант отвечать не по существу и невпопад.
я вам ничего не должен. не нравится — не отвечайте.
Не теория множеств, а реляционная алгебра
нет. именно теориИ множеств.
Впрочем, в Haskell вы явно тоже ни в зуб ногой
ну вы явно не профи в Haskell, потому что говорите то, за что профессиональные хаскелисты высмеивают быстро и беспощадно.
не один год периодически тусуюсь на их форумах.
мы говорили бы про GHC
аха, а еще о том как по разному программы работают на ноутах от Dell и HP
Сомневаюсь, что так уж много DBA вообще слышали о лемме Цорна
сомневаюсь что большинство изучали даже аристотелеву логику.
что не говорит о том что все мыслят не логично.
а уж как массово заявляют о нелогичности...
и молчат когда:
где, в каком объеме и какие логики изучали?
Ну тогда может он подскажет вам и ответ на первый вопрос моего комментария, а?
я отвечаю на то что мне интересно. и так как мне хочется или считается важным.

если вы хотите ответы на то что вам нужно, и в таком виде как вам нужно — платите деньги.

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

А лучше скажу так — продолжайте периодически тусоваться на форумах, заучивать термины, перечитывать GoF и требовать деньги за ответы. Глядишь, на дутом авторитете и выплывете.

я бы вам дал совет:
«Писать на стенах туалета, увы друзья не мудрено»

Продолжайте гнать пургу об ФП среди непрофильных программистов. это модно, круто и стильно.
кто не знает- будет рукоплескать.

в которых вы ровным счётом ничего не понимаете
ну да, ну да, вы допонимались что ’’tapl’ не нужен :D
ну да, ну да, вы допонимались что ’’tapl’ не нужен :D

Когда я говорил о брошюрке Пирса, я имел в виду брошюрку Пирса. И да, TAPL (+ ATTAPL) для программирования на Haskell тоже необязателен (хотя прочесть их я всем горячо рекомендую).

а я говорил о причинах неустранимой, фундаментальной маргинальности ФП, и Haskell в частности.

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

одно точно известно
восторги об ФП — «оно решит Проблемы!» и «Та оно просто!» — не сооветствуют наблюдаемой действительности.

Можете взять свои три обола.

Вы наблюдаете какую-то не ту действительность. Либо не так.

Главные проблемы:
— Мышление человека итеративно
— Процесс разработки ПО обычно итеративен

Я здесь отвечу потрясающе удачной и точной цитатой от Simon Peyton Jones:

In short, Haskell is the world’s finest imperative programming language.

И это не шутка.

Simon Peyton Jones
И это не шутка?

— Сынок, этот концерт получился слишком сложным в исполнении...
— Что ты, папа! даже ребенок его сыграет! Я же играю!
Моцарт, в детстве.

кто не в курсе
Glasgow Haskell Compiler — lead developers are Simon Peyton Jones and Simon Marlow.

кто не в курсе
на Prolog’е тоже можно писать императивно

соответствие Карри-Говарда — таки работает для тьюринг полных языков!

P.S.
вобщем по обилию агргументов «масло маслянное» я все же думаю что вы пока просто упорото верующий. а не адепт, популяризатор, проповедник.

на Prolog’е тоже можно писать императивно

Можно пример? Тот же XPCE вполне себе декларативный.

соответствие Карри-Говарда — таки работает для тьюринг полных языков!

Какое отношение Тьюринг-полнота имеет к CHI?

Можно пример?
то есть? вам учебник?

или нужно пояснять что , (AND) можно «трактовать» как ;(завершение оператора) в Сиподобных языках, и соответственно — и мыслить — императивно.

Какое отношение Тьюринг-полнота имеет к CHI?
Для DSL языков — вряд ли оно работает.
Потому что можно специально создать два DSL, для которых оно не будет соблюдаться.
вам учебник?

Мне пример императивного кода. Описания последовательности действий.

можно «трактовать» как

Мне это не очевидно, потому я и прошу пример.

Для DSL языков — вряд ли оно работает.

Какое отношение DSL имеют к Тьюринг-полноте и CHI?

Потому что можно специально создать два DSL, для которых оно не будет соблюдаться.

И что значит не будет соблюдаться применительно к CHI? Логика будет инконсистентна? Так для этого не нужен DSL, можно взять general purpose language.

Мне пример императивного кода. Описания последовательности действий.
откройте учебник и прочитайте главу о файловых операциях.
Мне это не очевидно, потому я и прошу пример.
ну так откройте учебник по Prolog, и просто прочтите.
В одном известном, даже впрямую об этом написано.
Забыл имя, но помнится из университета в Любляне...
Какое отношение DSL имеют к Тьюринг-полноте и CHI?
DSL это НЕ тьюринг полные языки. Обычно. Вы не знали?

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

И что значит не будет соблюдаться применительно к CHI? Логика будет инконсистентна?
вы бы почитали что такое «соответствие Карри-Говарда»....
в вики хотя бы.
откройте учебник
ну так откройте учебник

Ладно, проехали.

DSL это НЕ тьюринг полные языки. Обычно. Вы не знали?

DSL это, внезапно, какие угодно языки. Их характеристики определяются доменом. Вот пример вполне себе Тьюринг-полного eDSL. Тысячи их.

вы бы почитали что такое «соответствие Карри-Говарда»....

Можете процитировать ответ оттуда, если вам так нравится именно статья с википедии.

Спасибо за пример, теперь понятно.

DSL это НЕ тьюринг полные языки.
Это ложь.
... Обычно. Вы не знали?
Что значит «обычно»? Для кого «обычно»?
я же сразу дал оговорку. чтобы знающие не поймали на ложном обобщении.
И это ваш стиль аргументации? Ну, окей.

... Если (попробую угадать) про DSL вы вспомнили, пытаясь объяснить императивное подмножество Хаскеля — то вы сильно ошиблись.
Оно там не потому что для ввода-вывода придумали некий DSL (как в том же Прологе).
Оно там потому что фундаментальные императивные приёмы были успешно обобщены и удобно (практично) уложены в фреймворк композиций sideeffectless функций.

Именно поэтому — если хотите! — на Хаскеле можно писать императивно. В ряде случаев получается удобнее смешивать чисто-функциональные части с императивными.

Именно поэтому Haskell is the world’s finest imperative programming language.

Можно пример?
то есть? вам учебник?

Приведите пример. Я тоже без понятия, как вы построили связь между CHI и Тьюринг-полнотой.

И отвечать (невежливым) вопросом на вопрос — дурной тон. Мы, кажется, в приличном месте общаемся; ни сделать бочку, ни дёрнуть анус (как это принято в некоторых более других сообществах) вам ещё никто не порекомендовал. Так что извольте пример.

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

Иначе у меня не получается понять, о чём вы.

в трех постах уже упомянул, и раскрыл.
вы не читаете мои посты?

Процитируйте, если можете.
тогда смысл вам писать очередной?
Иначе у меня не получается понять, о чём вы.
на ваше понимание и не рассчитывал. вы ж упоротый :)

кому интересна тема — пусть почитает, подумает.

Перечитал ещё раз; до сих пор неясно, где вы нашли «масло масляное».

Вас уже единожды словили на пустословии и категоричности в том, в чём вы не разбираетесь (в теории категорий); может, всё-таки, хоть в этот раз потрудитесь обосновать свои слова?

по обилию агргументов «масло маслянное» я все же думаю...
Моцарт, в детстве.
Моцарт моцартом, но конкретно с этим утверждением SPJ я на 100% согласен. Читайте сами.
Моцарт моцартом, но конкретно с этим утверждением SPJ
ну когда у вас будет регалий как у SPJ, тогда и будете примазываться к его мнению.
а пока — лоб не расшибите, используя Haskell для императивного стиля. Метр же сказал? вы уверены что поняли — ЧТО оно сказал?

Это как в анекдоте
Взбирается альпинист на Эверест, и видит — стоят два каких-то бородатых мужика в простынях!
Протер глаза, подошел, точно, не галюцинация!
Он им
-Э-э-э, мужики, вы как сюда попали?
Один из мужиков разправил руки и легко полетел.
Сделал круг, и стал рядом.
— Вот так. И ты можешь!
Альпинист расправил руки и — полетел
— А-а-а.... — камнем вниз.
Стихло эхо, и другой говорит:
— Ну ты Павлуша и сволочь. Хоть и апостол...

ну когда у вас будет регалий как у SPJ, тогда и будете примазываться к его мнению.
Вы опять апеллируете к авторитету. Ваш собственный авторитет при этом стремительно падает.

И почему это мне нельзя «примазываться» к мнению, которое я понимаю и разделяю?
На собственное мнение уже нужна лицензия?

А непосредственно по коду у вас нет комментариев, одни анекдоты?

а пока — лоб не расшибите, используя Haskell для императивного стиля.

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

обясняют монаду как «монада — это монада»

Любой ребёнок в наше время знает, что монада в категории — это моноид в категории её эндофункторов.

Вот именно поэтому о GoF нужно вытирать ноги. Всё понимание, что вы будете мучительно (годами) оттуда извлекать, можно получить даже не заметив за две недели изучения функционального программирования.
Очень сильный аргумент при обсуждении ООП: «функциональное программирование лучше».
Это все равно что сказать: вот по русски надо долго описывать снег: насколько он рыхлый, насколько подтаявший, насколько яркий и т.д. А у чукчей это можно сказать одним словом — у них 100 слов для обозначения разного снега!.
То же и с ФП: многие проблемы в нем решаются замечательно, других вообще не возникает ввиду отсутствия состояния. Но вот только бизнес — приложения пишут в основном на ООП. Более того: даже в JavaScript, который изначально не ООП приходится эмулировать классы.
Есть много книг по ООД, ДДД и прочим ООП — подходам к проектированию. Но я как-то не видел книги, где было бы разобрано как на ФП полностью спроектировать, например, интернет — магазин.
Очень сильный аргумент при обсуждении ООП: «функциональное программирование лучше».

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

И да, если ваша задача — описать некий конкретный снег (на произвольном языке), то выбор чукотского будет, очевидно, выигрышным.

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

Это ad populum, и это ошибочный аргумент.

выбор чукотского будет, очевидно, выигрышным.

Вовсе не обязательно. Сначала нужно определиться какие метрики для нас важны, а уж потом мерить что выигрывает. В теории может и есть средства, обеспечивающие оптимумы по всем метрикам одновременно, но на практике обычно есть плюсы и минусы. Например, минус чукотского — снег вы может и опишите точно и лаконично, вот только поймёт вас от силы 10 тысяч человек. Примерно то же с ООП и ФП — число людей, легко понимающих императивный ООП код (по крайней мере в парадигме классового наследования) значительно больше числа людей легко понимающих декларативный ФП код.

Простите, но у вас противоречие. Декларативный код по определению просто понять.

И да, на Haskell весьма просто писать декларативно. Одно из главных его применений, тащемта, — это как раз реализовывать разнообразные DSL для сложных областей применения.

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

И да, на Haskell весьма просто писать декларативно.
а масло маслянное, да...

функциональное программирование вообще-то и является декларативным по концепциям. ru.wikipedia.org/...рограммирование

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

а главная цель DSL — дать язык для людей с менее крутой подготовкой.
с теми же целями ведутся работы и в области Controlled natural languages (CNLs)

Аргумент был простой: чукотский язык для снега наверняка лучше, как и функциональный для своих задач.
Но значит ли это что имеет смысл учить чукотский, если знаешь русский? Или учить функциональный язык если уже умеешь применять ООП? Думаю только в очень редких случаях.
По моему опыту в бизнес-приложениях задач, которые дешевле было бы решить на ФП, примерно не более 20%. При этом если все-таки написать эти 20% на ФП то затраты на поддержку двух разных языков зачастую сводят на нет всю выгоду.
Поэтому аргумент что проблемы ООП решаются переходом на ФП — это из разряда «мышки — станьте ежиками».
P.S. Буду благодарен за ссылку на книгу про проектирование и разработку бизнес-приложения полностью на функциональном языке — хотелось бы сравнить насколько это сложнее.

С книгами напряжёнка, а вот видео можно и посмотреть.

Это видео подтвердило мое мнение про Хаскель, как язык предназначенный для сугубо «низкоуровневых» задач: драйверы, датчики температуры, сложные вычисления, обработка сигналов и т.д.
Не представляю что бы на нем можно было быстро и удобно разработать бизнес-приложение с юзер-интерфейсом, бизнес-правилами, базой и т.д.
Еще интересный вопрос: а есть ли для ФП какие-нибудь диаграммы вроде UML? Как там вообще проектируется архитектура?

Диаграммы для ФП есть — они обычно чертятся маркером на доске.

Вот сервис, сделанный на Haskell. Что касается проектирования, то можно использовать тот же UML — он содержит стандарты визуализации не только для ООП, вообще говоря. Другое дело, что благодаря тому, что язык форсирует изоляцию сайд-эффектов, многие вопросы проектирования, сложные в императивной разработке, становятся ествественными и не требуют специфических механизмов для проектирования.

За разбрасывание такими книгами нужно бить томиком Макконелла по голове и вообще выгонять из годного опенспейса.
Сравнение бюджетов когда проект пишут такие «швыряльщики» и когда пишут люди, которые читают данную литературу описано здесь.

О, томик Макконелла можно использовать в тех же целях, отличный пример!

Ни наличие книги ни

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

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

И ему было бы очень печально читать то, что вы пишете.

Быдлокодер детектед.

Я же и говорю — исключительно возле параши!

Это вы описываете вашу корпоративную политику или локальные договоренности на уровне тимы?

Это тайный масонский ритуал всех солидных IT-компаний мира.

Туннельное видение детектед.

Ничего страшного, главное чтобы не туннельный синдром

Ещё такое же мнение от автора превосходного блога:

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.

Аргументы у него всё те же, уже изложенные в этом треде:

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

какая разница на каких языках написаны общающиеся по TCP/IP?

Более того, какая разница на каких языках написаны программы, выполняющиеся в единой виртуальной среде.

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

А значит — вам нужны переносимые между языками скилы.

народ менее ограничен в выборе.
в сутках 24 часа
народ ограничен даже фреймворками в пределах одного языка
выбор будет всё более и более разнообразным.
не будет. будет больше — фреймворков.
в дальнейшем вы будете сталкиваться (если работаете в этой области) с кодом на всё более и более разнообразных языках.
будет больше — кодогенерации, фреймворком, с используемого языка
вам нужны переносимые между языками скилы.
языки изучаются на порядки быстрее чем их использование, и среды в которой они используются.
В том-то и дело, что во многих областях (веб, к примеру)
а что такое область «веб»? веб — это общее название набора технологий, которые программист, как инженер — использует. какой язык не дай — ему миниум придется брать или создавать «молоток» для работы с ними. если не хочет «хардкодить» и «копипастить»
разница часто несущественна.
и как, скажем Sencha Ext JS похож на AngulaJS? это ж — javascript? ну так какие проблемы — ты его знаешь, вперед сегодня на тебе сенчу, пиши!
о, тут заказ, на AngulaJS, давай за денек добавь функционалу!
что значит — я его в первый раз вижу? ты ж Программист на javascript?
подавляющее число программистов не в состоянии...

Давайте-ка вы будете говорить за себя (и своих подчиненных, если имеются), ладно?

Ну либо подкрепляйте вот эти свои «подавляющее число» фактами. А то выходит некрасиво как-то.

Давайте-ка вы будете говорить за себя (и своих подчиненных, если имеются), ладно?
так это всем известно :)
начиная от представителей заказчика и заканчивая руководителями проектов, разного уровня.
Ну либо подкрепляйте вот эти свои «подавляющее число» фактами.
«Дайте мне ТЗ!!!» — обычное дело.
а сам программист написать — не в состоянии?
А то выходит некрасиво как-то.
не вижу ничего некрасивого.

программист вынужден выполнять две несвязанные работы
1 создавать инженерную конструкцию
2 описывать модель решаемой задачи

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

и, проверено отраслью — раз вопрос в ИЛИ, то лучше специализировать на п1. дав ему — «чудо-фреймворк» и «best practices»

... копипастного хардкодинга. и в сопровождении — неизвестно еще где будет больше боли.

Хорошо. Ступайте копипастить.
Успехов.

«не давайте советов что мне делать, и я не скажу куда вам идти»

Для краткости — всему своё место и время. Если вы атоматизтруете СТО то не нужно от класса автомобиль наследовать классы дизельный и бензиновый — потому что завтра скажут что они на дизель поставили газовый движок :)
Или от класса работник не надо наследовать класс менеджер — завтра менеджера переведут в уборщицы т по меняются лишь бонусы, обязанности и права. Когда не нужно наследовать? Описанное выше выливается в то что если объект в своём жизненном цикле может поменять тип — у вас проблемы — нужно продолжать моделирование. Если говорить про библиотеки — имя им легион и разные они и по API и по моделям — нужно смотреть — может где наследование, где-то адаптер а где-то фасад :)

раньше девелоперы ругались что в Джаве нет множественного наследования (особенно переходящие из С++). я тоже так думал как бывший сипипишник. сейчас я думаю по другому — очень хорошо что его там нет — меньше трудноподдерживаемого гвнокода успели понаписать.
и вообще наследование интерфейсов — наше все! красота использования единого АПИ для семейства классов, и в то же время отсутствие побочных эффектов типа измененного поведения

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

Та да, пора завязывать ;-)

Касательно критики наследования, я тоже встречал в литературе рекомендации к использованию композиции вместо наследования( en.wikipedia.org/...ver_inheritance ). Но, абсолютное большинство проектов, использующих фрейморки или библиотеки изначально предполагают наследование от библиотечных классов. Поэтому я бы сформулировал поставленный вопрос так: как часто вы пишете собственные классы и используете при этом наследование?

Что я только что посмотрел и как это развидеть?

Вы используете наследование от библиотечных и своих классов в коде
к сказанному ранее другими
это два совсем разных случая.

1 от библиотечных — вынуждают наследоваться авторы. или API. Частый случай — предлагают интерфейсы или абстрактные классы которые нужно реализовать, и передать библиотеке

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

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

но точно — если без проектирования наклевывается семейка с более чем 3мя «поколениями» — то нужно остановиться, и — засесть за проектирование, или перейти на композицию.

кратко, интутитивно
наследование требует waterfall
композиция для — agile

Зависит от того, что пишешь. Но в целом — конечно использую наследование. Если у меня есть 85 парсеров файлов, половина из которых парсит Excel, а треть html — логично наследовать их от класса Parser, в котором есть методы для чтения соответствующих форматов. Parser при этом — это мой класс, не библиотечный. А когда в проекте с использованием Kohana мне нужен класс для хранения/выборки данных в/из БД — он будет наследоваться от Model_Database, так как последний имеет ссылку на объект Database. Но в то же время я избегаю слишком длинных цепочек, когда класс С наследует класс B, который наследует класс A.
ООП для программиста, а не программист для ООП.

логично наследовать их от класса Parser, в котором есть методы для чтения соответствующих форматов
Чего-чего? то есть, в Parser — loadXML и loadCSV, а отдельно — XMLParser и CSVParser с единственным методом parse?
в случае парсера наследование редко расширяет логику — чаще просто реализуется заданный интерфейс. разве нет?

Кроме этого в Parser парочка protected-свойств и публичных методов. Интерфейс же мне не подходит, так как в PHP ни интерфейс, ни абстрактный класс не могут реализовывать методы (а мне очень нужно например реализовать loadHTML, так как разбор хтмл-таблички — грязная работа, которую не стоит копировать во множество файлов). Наследование же технически отлично подходит. В базовом классе реализованы методы, которые нужны всем парсерам, а уже каждый парсер реализует метод parse..

ни интерфейс, ни абстрактный класс не могут реализовывать методы (а мне очень нужно например реализовать loadHTML
в общем случае, loadHTML будет выглядеть неуместно в CSVParser. а чем trait’ы не устраивают?
В базовом классе реализованы методы, которые нужны всем парсерам, а уже каждый парсер реализует метод parse..
какие это? load/save — это лучше бы сделать через декомпозицию. типа, reader/writer.

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

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

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

Наследование штука хорошая, когда пользуется без фанатизма и исключительно по делу.
Создавая цепочку из 7-10 циклов наследования, изменения на любом из промежуточных звеньев могут приводить к не шуточному баттхёрту, особенно если это что-то вроде фреймворка, используемого в множестве проектов.

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

Наследование само по себе — удобный и полезный инструмент. Но есть негатив — адепты ООП суют его во все места — куда надо и куда не надо.

И немного конструктива. Иерархия должна использоваться в исключительно редких случаях.
GameObject extends Identifiable — это хорошо.
Warrior extends Character — очень плохо.
GameObject implements Renderable — это тоже очень, очень плохо.

а можете пояснить в каких исключительных случаях это оправданно?

GameObject extends Identifiable
Combat implements Tickable
Thread implements Runnable
ArrayList extends List

Всякое, в общем, системное. И главное — иерархии должны получаться 2-3 уровня, не больше.
Другая крайность — в бизнес логике иерархию нужно избегать. Никаких Client extends Person.

Никаких Client extends Person.

Непонятно почему — это же классика, в каждом учебнике это как пример приводят.
Хочется увидеть аргументацию.

Потому я его и привёл, что в книжках он часто упоминается :) Проблема в том, что иерархия в проекте — она как гранит. В ней структура высекается, а потом очень тяжело поддаётся изменению. И вот для чего-то фундаментального (структуры данных, самый-самый кор системы, и т.п.) — её можно использовать. А для чего-то, что имеет шансы на изменение — себе во вред.

Конкретика.
Запилили Client extends Person.
А на завтра к нам приходит ПМ, и говорит — а давайте, у нас будут групповые покупки.
А потом прибежали маркетологи — а давайте у нас клиентами будут заводы и всякие юр. лица.
А потом говорит директор — нужно разрешить выплату клиентам, причём одни будут рефералами для других.

И для КАЖДОГО уникального набора требований — будут РАЗНЫЕ иерархии. В реальном (а не книжном) мире, возможность учитывать новые пункты ТЗ и изменения в нём — очень важна. А сильный упор на ООП и «раннюю красоту кода» (отсыл к «ранней оптимизации») — превратит вас в упёртого, отрицающего необходимость смены ТЗ, клянущего всех-этих-ничего-непонимающих гуманитариев, неспособных один раз, внятно и навсегда, составить требования.

Ну, всё-таки хотелось бы чтобы ТЗ составлялось заранее и программист не думал о том, что выходит за пределы его компетентности и обязанностей (в данном случае групповые клиенты, юридически-физические лица — это уже область знаний маркетологов, юристов, но никак не программиста). И по-хорошему те все лица должны приходить как раз в процессе написания и утверждения ТЗ.

Как было бы лучше, бывает ли, и можно ли верить обещаниям не менять ТЗ — это другой вопрос.
Просто я предпочитаю, на вопрос «а давайте добавим в ТЗ вот такую мелочь» — мочь ответить — «ок, давайте подробности», а не «это не вписывается...», «в ТЗ такого не было...», «у нас не предусмотрена возможность...», и т.п.
И вот для своей личной свободы и нервов (и полезности, как специалиста) — я и использую рекумендуемый мной совет.

Да ну так можно дойти и до использования отдельных функций вместо классов, что тоже не добавляет удобства. Кроме того, в вебе например большиснтво приложений — это связка PHP+MySQL. Новая фича вполне легко может привести к необходимости изменить структуру БД. Отказ от наследования не спасёт.
А задачка

Запилили Client extends Person.
А на завтра к нам приходит ПМ, и говорит — а давайте, у нас будут групповые покупки.
А потом прибежали маркетологи — а давайте у нас клиентами будут заводы и всякие юр. лица.
А потом говорит директор — нужно разрешить выплату клиентам, причём одни будут рефералами для других.
Вполне решаема без затрагивания Person, изменением класса Client.

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

Нельзя так дойти (если не идти специально) — нужно не только минимизировать связанность (например, путём отказа от наследования), но и максимизировать связность.

А как раз агрегация зачастую делает изменения в структуре БД простыми: вместо изменения основных таблиц просто добавляем новые с отношениями 1:1, легко изменяемые на 1:много при необходимости.

И получаем join по 10 таблицам вместо 3х

С нормальной ORM, которая не выгребает всё что может, а только то что нужно, на большинстве задач не получаем.

Применить к данным фильтры по всем полям, затем сгруппировать записи, просуммировав значения некоторых полей, вывести постранично. ORM мне поможет?

Например, есть 10000 сделок на FOREX. В каждой указаны как минимум дата (и время) входа и выхода, цена, валютная пара, объём и результат. Нужно: выбрать сделки с определенной валютной парой, отсортировать скажем по дате закрытия и для каждой сделки посчитать накопительный результат (результат этой сделки + результат предыдущих. Вывести это всё постранично (так как если вывести всё на одной странице — браузер подавится). Можно такие задачи решать с помощью ORM?

А как? Особенно накопительный результат интересует.

Сферический ORM предоставляет механизмы для вывода данных постранично. Иначе бы никто ими не пользовался.

Я что-то слышал про ОРМ и что он умеет постранично — подозревал. Накопительный результат как считать будем?

Да как угодно. Вариантов много. Либо средствами СУБД, либо средствами ORM, либо средствами ЯП. ORM это не совсем то, что вы думаете( по крайней мере, как я понимаю, что вы думаете о ORM).

Можно. Не далее как на этой неделе решал в чём-то подобную задачу на Doctrine: по каждому клиенту нужно было вытащить общий срок действия все договоров, среднее время между договорами, общую сумму в разрезе разных видов транзакций и другую статистику.

Просто не надо забывать, что ORM это не просто тупой маппинг «таблица — класс, строка — объект, столбец — поле», а маппинг объектов на любые сущности БД такие как хранимки или материализованные представления.

Это уже интересно. То, что я видел в качестве примеров ORM раньше — это был именно тупой маппинг, что мне не подходит.

Важно различать ORM как принцип проектирования, слой архитектуры который обеспечит связь объектов и РСУБД, и универсальные ORM-библиотеки (подавляющее большинство из которых реализует паттерн ActiveRecord, годный, имхо, только для простых CRUD приложений).

По сути ORM это любой код, который формирует запрос к БД и из его результатов наполняет объекты (и, наоборот, сохраняет состояние объектов в БД). Если вы писали код, который делает запросы и сохраняет результат не в куче переменных или массиве, а раскидывает его по полям одного или нескольких объектов или их коллекций, то вы писали ORM сами того не подозревая :)

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

Пускай жестко захардкоженый, пускай без красивых абстракций,

Красивые абстракци поверх нетипизированного sql кода одно из основных достоинств передовых ОРМ.
Чем дальше тем чаще оверхед становиться контролируемый и минимизируемый средствами самого языка программирования. Без вмешательства в виде SQL

А вы не путаете ORM с DBAL или вообще слоем хранения в архитектуре? ORM не предполагает в общем случае инкапсуляцию и/или генерацию SQL запросов. Функции/методы маппинга могут принимать их в качестве параметра или явной зависимости. Причём обычно такой подход показывает наибольшую эффективность, поскольку позволяет воспользоваться всеми преимуществами не просто конкретной РСУБД, а даже конкретной её версии.

А что кто-то кроме Орм обычно принимает как зависимость компонент, который генерирует sql на основании классов и языковой инфраструктуры?

Генерация SQL не является ответственностью ORM. ORM имеет два «входа»: данные и метаданные приложения и метаданные БД и реализует связь между ними по заданной схеме. ORM должна знать как получить данные из БД, но «знать» SQL ей для этого не обязательно, достаточно «знать» методы DBAL типа getAll, filter, sort и т. п.

Ок, без ОРМ эти компоненты отдельно сейчас практически не развиваются. И все передовые наработки по ним происходят в контексте развития ОРМ. Так?

Тут вопрос скорее философский: считать ли, например, LINQ to Entities полноценной ORM или только транспортом для неё.

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

Если вы о том, что многие не отделяют собственно ORM от других средств, абстрагирующих работу с БД, то согласен. Но почувствуйте разницу между «понятие ОРМ более комплексное» и «многие неправильно используют понятие ОРМ».

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

100%
с точки зрения предприятия и люди не люди, а всего лишь «ресурс» приносящий прибыль (если он делает что-то полезное) и затраты (на зарплату и соц.выплаты)

а тебе говорят — «у нас аджайл — какое ТЗ?» или «у нас фича-дривен девелопмент»

Потому что области ответственности у Person и Client скорее всего разные. У Person скорее всего есть общечеловеческие поля типа ФИО, дата рождения, адреса, телефоны и т. п. для организации процессов типа «позвонить», «написать письмо», а у Client поля типа список договоров, состояние их исполнения, счета, оплаты и т. д. для организации процессов типа «заключить договор», «выставить счёт», «зачислить оплату» и прочим, мало зависящим от личных данных, использующих их как справочник, но не основу для процессов.

в 1С помнится есть единая категория — «контрагенты». это могут быть физлица, предприятия, и еще и предприятия внутри предприятий, или физлица внутри предприятий. т.е. потенциально — древовидная иерархическая модель
в случает ЧП рисуется так: Контрагент — СПД Гейтс Б.Г. -> Контактное лицо — Гейтс Билли Генриевич. налицо агрегация

Именно. Класс типа «контрагенты», «клиенты» и т. п. должен агрегировать класс типа «физлица», «персоны» и т. д. даже если на сегодняшний день в каком-нибудь розничном магазине это одни и те же объективные сущности реального мира (люди) — для бизнес-процессов это разные сущности с разными областями ответственности — договор можно заключить с контрагентом, а позвонить — человеку .

На рахунок агрегації, є такий мінус — важко реалізувати зворотній зв’язок від компонента до «парента». Наприклад, Tickable всередині міняє деякі параметри парента (в даному випадку Combat) — тоді потрібний загальний інтерфейс (Combat: public TickableOwner) і зворотній референс в компоненті. Ще гірше, якщо один компонент впливає на стан інших компонентів.

В наслідуваному класі вся внутрішня кухня в одному місці.

Мой посыл не в том, что нет удачных примеров использования наследования (Tickable — это как раз один из них), а в том, что их гораздо меньше, чем принято писать в книжках.

Scala позволяет избежать многих проблем с наследованием при помощи traits, type classes, abstract types, stackable traits, structural types, implicit conversions, views — если и не уникальные, то довольно редкие фичи для языков программирования. Практикую все из них, прямому наследованию предпочитаю компонование свойств в виде подмешивания из других trait’ов (mixins) или создание ускоспециализированных type classes.

д̶о̶в̶о̶л̶ь̶н̶о̶ ̶р̶е̶д̶к̶и̶е̶ функциональные фичи
FTFY

Отнюдь. Ни одна из этих фич не является функциональной. Все они вполне могли бы присутствовать в чисто императивном языке со строгой типизацией, таком как Java или C#.

Годная статья по type classes была здесь: danielwestheide.com/...pe-classes.html ; сейчас почему-то только через кэш: webcache.googleusercontent.com/...lient=firefox-a

Я за свою практику заметил, что чрезмерное использование наследования — это «детская болезнь» начинающих программистов, которые пытаются применить свои знания принципов ООП на практике, даже если это не требуется; пытаются изначально продумать архитектуру на базе иерархии классов, т.е. они рассматривают подход наследования «по умолчанию», и только если у них с этим не получается, они переходят к использованию композиции. Правильный подход же противоположный — по умолчанию используется композиция, а наследование — только если к этому есть четкие показания, т.е. взаимоотношение «IS A» между типами, что является довольно редким случаем на практике, по крайней мере значительно более редкий, чем это кажется начинающим.

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

Если присмотреться, есть однозначная зависимость между количеством и силой связей между компонентами, и качеством кода. На самом деле связность между элементами является определяющим и объективным критерием качества кода (объективным потому, что его можно измерить, например с помощью JDepend в java). Поэтому, уменьшение и «ослабление» зависимостей — это прямой путь к улучшению качества кода, и именно поэтому композиция лучше наследования.

Очень рекомендую интервью с Гаммой на Артиме по этому вопросу: www.artima.com/...rinciples4.html (ссылка на 4 страницу, посвященную как раз вопросу — наследование vs композиция, но интервью нужно читать полностью. Кто не в курсе, Гамма — один из «Банды четырех», GoF, написавший классическую книгу о паттернах).

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

Также, очень рекомендую к прочтению небольшую статью Роберта Мартина (Uncle Bob) www.objectmentor.com/...nd_Patterns.pdf где в том числе освещается вопрос измерения метрик зависимостей (лежащих в основе JDepend например).

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

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

Какая-то каша.
Во первых зависит от языка и фреймворка.
Начнем с простого. Например, в .NET наследование везде — любой тип унаследован от System.Object. А вот JavaScript хотя и объектно-ориентированный язык, но наследования там нет. Потому и появились всякие CoffeeScript.
В том же .NET обобщение — вообще ортогонально к наследованию. Обобщение реализовано через наследование.
Длинные цепочки — да, зло, но не абсолютное.
Я бы говорил, скорее, о композиции против наследования. Композиция очень мощный инструмент. Хотя заменить наследование полностью опять же не может.

А вот JavaScript хотя и объектно-ориентированный язык, но наследования там нет
В чистом JS наследование есть, просто оно прототипное. Некоторые используют примеси называя это наследованием.

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

А CoffeScript больше из-за того что в JS много конструкций дублирующихся один в один, поэтому синтаксический сахар не помешает.

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

А вот создание небольших классов с узконаправленным функционалом, и конструирование из них основного класса посредством примесей — видится хорошей идеей.

Наследуй если это помогает твоему пониманию кода. Затраты компа на наследование — минимальны, поскольку львиную часть работы выполняет компилятор ОДИН РАЗ.

Основной принцип программирования: Не делай за компьютер его работу!

И ещё — чем лучше ты понимаешь код, и чем меньше пишешь — тем меньше в нём ошибок. В десятки раз меньше. А каковы затраты юзера от ошибки в коде?

Железобетоное доказательство:
Допустим, за всё время работы кода этот участок был вызван 100 000 000 раз. А теперь напиши программу в которой вызовешь пустой метод класса с 8-м порядком наследования 100 000 000 раз. В том же коде засеки время за которое он справился. Меньше секунды, да?
Внимание, вопрос: А сколько лишнего времени потратил ты на написание и отладку кода без наследования?

Мораль: ДОУ рулит :)

Я так понимаю, речь о Java.
В .NET механизм перехода по таблице виртуальных методов по скорости почти не уступает вызову просто метода (единицы лишних команд процессора) и, насколько я помню, не зависит от глубины наследования.

У наследования есть и минусы. Допустим есть очень разветвленное дерево наследуемых объектов. Как сильно повлияет на остальной код наличие бага в корневом узле? Сколько будет потрачено усилий на тестирование поведения всех потомков исправленного класса? Хорошо, если код покрыт тестами.

Это не минус, а плюс. Чем чаще используется код, тем быстрее находятся его баги. А вот если каждый сам себе писец — то угадай, покрыты ли тестами самые второстепенные задачи типа вспомогательных утилит администрирования. А потом всплывает, что какой-то клоун подал SQL-серверу команду UPDATE без условия.

Совсем недавно обнаружилось дивное. Так что довод про частоту использования утилит (и кода) не всегда работает.
tjournal.ru/paper/bash-bug
Про каждый сам себе писец не понял, какое это имеет отношение к вопросу выбора между наследованием и композицией. Композицию наоборот проще тестировать.
Опять же соблюдение LSP — та еще задача.

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

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

Для начала нужно различать наследование поведения и наследование интерфейса.
В наследовании интерфейсов не вижу ничего плохого. Тут иерархия определяется исключительно предметной областью: как надо так и наследуем.
А вот наследование реализации это более противоречивая штука. Дело в том, что во многих ООП языках наследовать реализацию можно только от одного предка. Это значит что такое наследование — очень жесткая связь! Гораздо жестче, чем агрегация (здесь можно подменить реализацию легко). Унаследовать потом от другого — нужен сложный рефакторинг. А иногда вообще библиотеки требуют наследования от своих классов и если класс уже в своей иерархии, то приходится исхитряться.
Еще одна проблема: от унаследованного нельзя отказаться. Наследуем все или ничего. Можно, конечно, «заткнуть» неподходящие методы, но это «отказ от наследства» и нарушение «принципа замещения Лисков».
Это, конечно же, не значит что наследование реализации — зло, которого нужно всячески избегать. Просто наследовать таким образом имеет смысл только методы гарантированно нужные этому классу и всем потомкам. Или методы жестко завязанные на внутреннее состояние объекта когда вынести их наружу сложно. Банальный пример — это метод ToString, который полезен для любого класса и не имеет смысла его выносить.
Во всех остальных случаях действуем по принципу разделения интерфейсов и реализации. Интерфейсы наследуем и агрегируем как хотим, реализация (классы) скрыта и доступна только фабрикам или депенденци-контейнеру. В итоге каждый класс слабо связан и реализацию разных методов всегда легко подменить.

очень дельное замечание, поддерживаю.

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

Наследование один из самых противоречивых и холиварных основ ООП. Многое зависит от языка, если возможны DDD как в С++ или мета-хаки как в Javascript/Groovy/Scala путем добавления методов в объект на runtime-е, то лучше дважды подумать. В Java например в этом плане безопасней за счет единственного суперкласса и однозначного соответствия объекта классу, но все равно можно попасть впросак.

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

В моей практике наиболее удачные реализации выглядели так: Интерфейс(5 методов) -> Абстрактный класс (3-4 реализованых метода) -> Конкретные классы (1-2 метода). И хорошо работало ТОЛЬКО когда идет наследование и переопределение поведения, а не состояния.

В целом если наследование можно заменить шаблоном стратегия лучше так и делать, just to be on the safe side. А еще лучше подойти к лиду и посоветоваться. Чем опытнее разработчик, тем больше он слушает и анализирует мнение других членов команды.

Подскажите, пожалуйста, часто ли в реальных проектах Вы используете наследование от библиотечных и своих классов в коде.
Нет, только реализую библиотечные интерфейсы и мой объект юзается библиотечными классами.
Или же, по другой рекомендации вызываете из собственного класса метод другого объекта.
Да, если метод статический, если нестатический, создается/инжектится Spring-ом объект, а из него уже вызывается метод.
Практикуете ли генерализацию собственных классов или же начинаете кодировать классы от самых базовых?
Только когда возникает необходимость. Заранее такое делать не очень хорошо. Мне больше нравится подключать поведение в класс через интерфейсы, чем возиться с Generic-ами. В целом скорее нет.

Підписатись на коментарі