С таким подходом проблемы будут независимо от языка.
С каким — таким? «Посмотреть предложенный собеседником код и найти там проблемы»?
Проблемы с предложенным вами подходом потому, что он нелокален. Ну, вернее, это проблема не вашего подхода, а общей философии C++: например, если вы почитаете или послушаете гугловского Титуса Винтерса, топящего за что-то вроде «C++ design unit is an overload set» (а не функция или класс или модуль или…), и послушаете про его же кулстори про эволюцию гугловской кодовой базы, то увидите, что добрая часть проблем вылезает именно из-за этой нелокальности. Семантика, скрывающаяся за именем, оказывается размазана не по одному определению одной функции за этим именем, а по всему множеству всех функций с этим именем, потенциально в разных неймспейсах (привет ADL), и изменение этого множества приводит к забавным нелокальным спецэффектам (например, вопрос о роли requires вы почему-то пропустили — но я вас понимаю, сам бы его пропустил). Это — один из худших видов coupling'а.
Наверное, это не его забота, обеспечить приёмистость не точно соответствующих типов в предоставляемом API, — но только таких, которые разрешены проектировщиком API, а не любых, которые язык позволяет.
Наверное. Моей заботой (и вообще обязанностью) как программиста инфры было именно обеспечить максимально комфортную жизнь трейдерам, которые в статистике и прочих своих этих всех альфах-бетах разбираются куда лучше, чем в C++.
Есть предложенный механизм, и если хотеть добиться результата, этот механизм можно использовать для достижения этого самого результата.
Я с этим не спорю. Речь о другом: у предложенного механизма есть много негативных аспектов, поэтому говорить, что он эквивалентен решениям из раста (или из хаскеля — я так-то раст не люблю и хаскелист вообще), несколько нечестно.
Если не продумывать каждое решение, а пытаться наворачивать сверху, да побыстрее, а также быть вынужденным постоянно что-то менять, — да проблемы будут.
Как успехи с продумыванием кодовой базы на года вперёд?
Если у вас достаточно времени, то проще на том же хаскеле наваять для тех же трейдеров DSL с понятными сообщениями об ошибках, понятным поведением, понятным предметно-специфичным статическим анализом, и предсказуемой кодогенерацией. Да, проще, чем заставлять всех разбираться в экспоненциальной сложности C++.
Эта проблема не является специфичной для данного случая.
Ну, да. Но в этом случае она вылезает тоже.
Всё же, первая задача значительно проще, вы преувеличиваете.
Observationally equal. Я не знаю ни одного человека, решившего задачу останова, и не знаю ни одного человека, который бы знал C++. И, кстати, сверхвысокие HFT-шные зарплаты не позволяют их найти — все знатоки C++ в основном почему-то прячутся в комментариях на хабре или опеннете и тому подобных, вместо того, чтобы приходить на собеседования и получать свои заслуженные 500-700 в год.
Это, по всей видимости, не имеет отношения к реально происходившим событиям, потому что сделка была не одна большая, а — большое количество относительно мелких. И если бы ушло, то ордер был бы один.
Knight capital — это так, намёк на то, что при факапах в коде проверки и ограничители срабатывают не сразу, и даже их может оказаться недостаточно (они ж обанкротились и закрылись).
Так в коде выше на биржу уходит тоже большое число относительно мелких (если хочется, можете вместо sendOrder читать splitAndExecuteOrder или чё-т такое, сути это не меняет). Или вы думаете, что если вам надо купить/продать 100500 акций, то вы их покупаете одним пакетом? Это плохая идея по куче причин.
Ещё код по теме можно посмотреть в моём ответе
Ожидать, что люди будут в продакшене писать и поддерживать такой код — несерьёзно.
Потому что код меняется. Вчера const char* было, сегодня std::string_view (или наоборот). Вчера double price , сегодня fixed_point<4> price (в который неплохо бы конвертировать из литералов, кстати, но не будем вскрывать эту тему, перегрузки разбегаются как тараканы).
Вот я скопипастил ваш код (и заодно добавил requires из соседнего поинта) и сделал вид, что он эволюционирует со временем, «забыв» поменять тип первого аргумента в удалённой перегрузке:
Обратите внимание на -10. Задача со звёздочкой: скомпилится или нет? (ответ: да, скомпилится)
Теперь я убираю requires. Скомпилится или нет?
clang говорит «ambiguous» и ошибка, gcc компилирует (лан, моя вина — надо -pedantic добавлять), но говорит
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
13 | sendOrder("DAL", true, -10, 5.0);
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
Что за worst conversion? Откуда? Сможете сходу огласить весь список conversion'ов? Почему requires так влияет? Смогли бы предсказать такой результат, просто глядя на код? Сможете объяснить среднему программисту на C++, почему результат такой и причём тут requires? Сможете объяснить среднему трейдеру, который на C++ пишет постольку, поскольку вы ему даёте апишку для вашего инфра-кода, а у себя он там обмазывается q, матлабами и прочим?
Сможете быть уверенным, что сможете адекватно поддерживать кодовую базу на миллион-другой строк, где подобными финтами всё обмазано, и где простейшее изменение рискует превратиться в сутки-другие расхлёбывания выблева компилятора минимум, и где рекомпиляция одного TU занимает минуты даже в дебаг-билде, без оптимизаций? Мне приходилось поддерживать, не рекомендую.
И это — правда, та функция, адрес которой, весьма вероятно, необходимо будет брать?
Да, а что? std::bind_front(&sendOrder, "GOOG");
Сейчас там и так double последним аргументом. В таких местах float не используется.
Почему? Я хочу, чтобы у меня в кэшлайн помещалось 16 цен, а не 8 — почему вы мне запрещаете так делать?
Олсо, в таких местах и double не используется, а используется фиксированная точка, но неважно — это учебный пример.
В данной задаче это — необходимо?
Не, просто задача «освоить C++» примерно настолько же реализуема, как «решить проблему останова».
Вы, видимо, обознались.
Вовсе нет. Просто считать, что это число вот прям сразу пойдёт в пакетик на биржу — это несколько ошибочно. Там, например, может быть что-то по смыслу как
void sendOrder(...)
{
const int batchSize = computeSmallBatchSize(quantity);
for (int i = 0; i < quantity; i += batchSize) {
sendToExch(std::min(batchSize, quantity - i));
waitPriceToSettle();
}
}
И если вы хотите купить 10 акций, а случайно покупаете -10 = 4294967286, то до того, как у вас сработают всякие риск-чеки, дневные лимиты, и прочее, у вас уже уйдёт ордеров на сотню тыщ акций.
ML и параметрический полиморфизм. В C++ обкатывали разве что идею «как бы параметрический полиморфизм сделать максимально криво, но чтобы потом было весело делать головоломки и отсеивать людей на интервью». Хорошо разве что для job security.
Почему не было даже попыток применить данное решение?
Потому что вам теперь надо обновлять обе сигнатуры, и компилятор далеко не всегда напомнит вам это сделать.
Потому что теперь вы не можете взять адрес sendOrder(по крайней мере, в контекстах вроде аргумента для стандартных алгоритмов, где ожидаемый тип callable не фиксирован).
Потому что если вы захотите принимать doubleилиfloatпоследним аргументом, то вам уже придётся обмазываться концептами и писать что-то вроде requires (!(std::is_same_v<T3, double> || std::is_same_v<T3, float>)). Очень удобно и дружественно к людям, в чьи обязанности входит не только штудирование талмуда++. Кстати, тут крошка-джун пришёл к отцу, и спросила кроха: «папа, а что тут лучше, std::same_as или std::is_same_v? Какая вообще между ними разница? Какой-какой частичный порядок? Я полностью каждый день порядок навожу!»
следовало бы научиться пользоваться C++
И решить проблему останова на сдачу.
Человек, утверждающий подобное, даже не пытался изучить предмет.
Человек, отвечающий подробное, даже не понимает смысла учебных, иллюстрирующих примеров.
По этой логике в любом языке есть «элементы ООП», и выражение «пишу с использованием ООП» (с учётом неявного засовывания «элементов» в эту фразу) перестаёт иметь какую-либо описательную силу (разве что, понятно, что человек не пишет в машкодах, но это малое количество информации).
Что такое классическое ООП? Что значит его там нет?
Снова вопрос определений, но для меня лично его наличие в языке — это когда язык позволяет
легко инкапсулировать данные на уровне класса, а не модуля (в коде выше на go нигде не написано, что только функция Say может дёргать name)
легко описывать наследование (а не как в C, где можно обмазаться агрегированием и ЕМНИП явными кастами, конечно, но это больно и нетипобезопасно)
легко описывать полиморфизм подтипов (а не снова как в C, где всё опять на кастах и закате vtbl солнца руками)
Уточню свой исходный вопрос: можете привести пример наиболее популярного, на ваш взгляд, типизированного языка, для которого верно утверждение «классического ООП там нет» (с которым вы изначально спорили)?
Буквально нет никакой смысловой разницы.
Она есть, но её я с радостью обсужу чуть позже, как мы придём к согласию по вопросу выше.
Я их дальше привёл. Можно попробовать прочитать следующий абзац.
так что даже не могу понять, где они живут, эти инструменты, если оставаться в рамках DDD.
Тем не менее, не понял связи. Зачем здесь какие-то слова? В каком смысле «где живут»?
Ну, кроме размера инструмента важно ещё и умение им пользоваться. Вон, для автора статьи и ООП - так себе инструмент. А ещё надо уметь не хотеть пользоваться инструментом там, где он не годится. Например, диалектика, как и любая философия, сама по себе предсказательной и доказательной силы не имеет. Но как средство подсказать, где искать решение, а также - почему решение вряд ли является решением, она помочь способна. Мне, в частности.
Можно сделать s/диалектика/религия/g и получится примерно настолько же корректное высказывание.
Распарсенный XML (nodes), в ОЗУ нужно хранить в объектах
Зачем? Вот вам описание типа для XML-узлов на хаскеле (который вот совсем не ООП-язык):
data XmlNode
= TagNode { name :: String, attrs :: [Attribute], children :: [XmlNode] }
| TextNode { text :: String }
А в этой статье автор пишет, что ООП скам. Нужно всему верить?
Нет. В видео (к сожалению, расшифровки нет, так что на текстовую версию сослаться не могу) товарищ показывает, почему не-ООП-подходы оказываются эффективнее и, можно сказать, естественнее конкретно для разработки браузеров.
Впрочем, видеть вопрос «нужно всему верить?» от человека, до того пишущего «я не копал, но уверен» смешно.
Я лично не копал, из чего сделаны браузеры (да и просто парсер XML), когда HTML код, преобразуется в картинку на экране, которую вы сейчас видите, но уверен, что ООП - самый эффективный и даже единственный правильный инструмент для этого.
Например, функции (конвертирующие одни типы в другие). Или, например, события и реакции на них.
Не, серьёзно, DDD настолько естественно, что когда я прочёл пару книжек про DDD, то выяснил только то, что именно так и называется то, чем я давно занимался в ФП. Там, конечно, дают явные названия для этих инструментов, но они естественные, и скорее отражают организационную структуру, чем код. Ну там, shared kernel для ограниченных контекстов, соответствующих тесно связанным бизнес-процессам, или upstream/downstream, когда одна команда (бизнес-процесс)не может влиять на язык другой команды, но другая команда (бизнес-процесс) всё равно DDD, или anticorruption layer, когда другая команда — не DDD.
Но на практике обо всём этом можно не думать, и всё будет норм. Вам не нужно знать аксиомы Пеано, чтобы посчитать сдачу в магазине.
Диалектика противоречива в той мере, в которой противоричивы явления объективной действительности
Явления объективной действительности не противоречивы. Диалектика по описательной силе сравнима со средней религией: можно сделать вид, что описываешь что угодно, но на самом деле не описывается ничего.
Однако обсуждать диалектику здесь - это офтопик.
Только когда речь заходит о том, что диалектика — так себе инструмент, конечно :]
DDD же разбивает единую предметную область на куски - ограниченные контексты, и не дает встроенных инструментов, чтобы сшить эти куски на их границах.
Почему? Там есть куча инструментов для этого, и они настолько естественны, что о них даже не задумываешься.
Ну а диалектика - потому что она описывает эту частную конкретную проблему - которая, однако, в том или ином виде проявляется ещё много где - на уровне наиболее общих законов природы, общества и познания, и подсказывает полезные эвристики, как подобные проблемы можно решать (но решение всё равно надо находить для конкретного случая).
Проблема с диалектикой в том, что она логически противоречива, поэтому она применима ко всему (одинаково плохо).
Думаю, стоит разделять вопросы «почему?» и «зачем?» — у первого больше коннотаций причин, у последнего — целей (например, спрашивать «почему яблоки падают вниз?» норм, а «зачем яблоки падают вниз?» как-то даже звучит глупо, как по мне).
Способность легко забывать о рабочих проблемах за порогом офиса или за крышкой ноута, к сожалению, есть не у всех. Многие продолжают в фоне прокручивать проблемы, даже пытаясь забыть о них.
Так вот, вы отвечаете на вопрос «почему?». Я с этим вопросом не спорю и его даже не задаю — в конце концов, у меня тоже есть опыт, например, когда на работе была некоторая ерунда, ощущавшаяся как адская несправедливость, и я после работы её в голове прокручивал, и прокручивал, и прокручивал… Только потом я понял, что это непродуктивно, потому что стратегию поведения это вырабатывать не помогает, а только тратит моё личное время и эмоциональные ресурсы на какую-то бессмысленную ерунду. Вроде собирался вечером кардио поделать, на дорожке всякие там научпоп-новости почитать, а в итоге одна статья на одном месте открыта уже полчаса, а я всё прокручиваю, и прокручиваю, и прокручиваю…
Можно научиться этого не делать. Со способностями «легко забывать о рабочих проблемах» я тоже, тащем, не родился, но непродуктивные, неприятные проблемы (множество которых почему-то почти целиком совпадает со множеством проблем, понятных человеку вне отрасли) можно научиться выкидывать. А продуктивные, приятные проблемы («ну как же вот решить эту архитектурную задачу/ускорить этот кусок кода/етц») выкидывать даже, я бы сказал, и не нужно — мне их обдумывание вообще заснуть помогает, например. Но ими с другим человеком не поделишься, если он не то что вне отрасли, а вне конкретной предметной темы.
Не учиться выкидывать непродуктивные, неприятные проблемы из головы — выбор (почти всегда — осознанный), цели которого я не понимаю.
И для них психологическая поддержка — часть хорошего партнёрства. Даже если близкий не разбирается в теме и не может дать конструктивных советов — его моральная поддержка, даже на уровне «Вот козлы!», снижает стресс.
Я, наверное, слишком эмоционально тупой, чтобы «просто выговориться» для меня работало. Обсудить проблему и прийти к решению — да. Но просто обсуждать проблему без даже надежд на решение — это даже обсуждением язык назвать не поворачивается.
Ну и ещё исходный автор исходной статьи там что-то писал про ну-конечно-мы-за-равные-роли-в-отношениях — я, конечно, за равные роли не выступаю. Одна из моих неравных ролей — обеспечивать партнерше защиту от внешнего мира, и, в частности, изолировать её от максимального числа негативных аспектов своей жизни. У неё их своих хватает, я уверен.
Не, ну работа очень приличная часть жизни все же, как ее не обсуждать с женой
Так же, как не обсуждать с любым другим человеком. Зачем обсуждать негатив, переваривая его что в своей голове, что выплёскивая его на другого человека?
С каким — таким? «Посмотреть предложенный собеседником код и найти там проблемы»?
Проблемы с предложенным вами подходом потому, что он нелокален. Ну, вернее, это проблема не вашего подхода, а общей философии C++: например, если вы почитаете или послушаете гугловского Титуса Винтерса, топящего за что-то вроде «C++ design unit is an overload set» (а не функция или класс или модуль или…), и послушаете про его же кулстори про эволюцию гугловской кодовой базы, то увидите, что добрая часть проблем вылезает именно из-за этой нелокальности. Семантика, скрывающаяся за именем, оказывается размазана не по одному определению одной функции за этим именем, а по всему множеству всех функций с этим именем, потенциально в разных неймспейсах (привет ADL), и изменение этого множества приводит к забавным нелокальным спецэффектам (например, вопрос о роли
requiresвы почему-то пропустили — но я вас понимаю, сам бы его пропустил). Это — один из худших видов coupling'а.Наверное. Моей заботой (и вообще обязанностью) как программиста инфры было именно обеспечить максимально комфортную жизнь трейдерам, которые в статистике и прочих своих этих всех альфах-бетах разбираются куда лучше, чем в C++.
Я с этим не спорю. Речь о другом: у предложенного механизма есть много негативных аспектов, поэтому говорить, что он эквивалентен решениям из раста (или из хаскеля — я так-то раст не люблю и хаскелист вообще), несколько нечестно.
Как успехи с продумыванием кодовой базы на года вперёд?
Если у вас достаточно времени, то проще на том же хаскеле наваять для тех же трейдеров DSL с понятными сообщениями об ошибках, понятным поведением, понятным предметно-специфичным статическим анализом, и предсказуемой кодогенерацией. Да, проще, чем заставлять всех разбираться в экспоненциальной сложности C++.
Ну, да. Но в этом случае она вылезает тоже.
Observationally equal. Я не знаю ни одного человека, решившего задачу останова, и не знаю ни одного человека, который бы знал C++. И, кстати, сверхвысокие HFT-шные зарплаты не позволяют их найти — все знатоки C++ в основном почему-то прячутся в комментариях на хабре или опеннете и тому подобных, вместо того, чтобы приходить на собеседования и получать свои заслуженные 500-700 в год.
Knight capital — это так, намёк на то, что при факапах в коде проверки и ограничители срабатывают не сразу, и даже их может оказаться недостаточно (они ж обанкротились и закрылись).
Так в коде выше на биржу уходит тоже большое число относительно мелких (если хочется, можете вместо
sendOrderчитатьsplitAndExecuteOrderили чё-т такое, сути это не меняет). Или вы думаете, что если вам надо купить/продать 100500 акций, то вы их покупаете одним пакетом? Это плохая идея по куче причин.Ожидать, что люди будут в продакшене писать и поддерживать такой код — несерьёзно.
Написано в фразе прямо перед процитированной вами, но я повторюсь: в ML (ранние 70-ые).
Более того, даже тот же хаскель (с ещё более полиморфным полиморфизмом) появился в том же 90-м.
Полигон — это когда массовое применение прямо там же, да.
Не двигайте гоалпосты.
Потому что код меняется. Вчера
const char*было, сегодняstd::string_view(или наоборот). Вчераdouble price, сегодняfixed_point<4> price(в который неплохо бы конвертировать из литералов, кстати, но не будем вскрывать эту тему, перегрузки разбегаются как тараканы).Вот я скопипастил ваш код (и заодно добавил
requiresиз соседнего поинта) и сделал вид, что он эволюционирует со временем, «забыв» поменять тип первого аргумента в удалённой перегрузке:Обратите внимание на
-10. Задача со звёздочкой: скомпилится или нет? (ответ: да, скомпилится)Теперь я убираю
requires. Скомпилится или нет?clang говорит «ambiguous» и ошибка, gcc компилирует (лан, моя вина — надо
-pedanticдобавлять), но говоритЧто за worst conversion? Откуда? Сможете сходу огласить весь список conversion'ов? Почему
requiresтак влияет? Смогли бы предсказать такой результат, просто глядя на код? Сможете объяснить среднему программисту на C++, почему результат такой и причём тутrequires? Сможете объяснить среднему трейдеру, который на C++ пишет постольку, поскольку вы ему даёте апишку для вашего инфра-кода, а у себя он там обмазывается q, матлабами и прочим?Сможете быть уверенным, что сможете адекватно поддерживать кодовую базу на миллион-другой строк, где подобными финтами всё обмазано, и где простейшее изменение рискует превратиться в сутки-другие расхлёбывания выблева компилятора минимум, и где рекомпиляция одного TU занимает минуты даже в дебаг-билде, без оптимизаций? Мне приходилось поддерживать, не рекомендую.
Да, а что?
std::bind_front(&sendOrder, "GOOG");Почему? Я хочу, чтобы у меня в кэшлайн помещалось 16 цен, а не 8 — почему вы мне запрещаете так делать?
Олсо, в таких местах и
doubleне используется, а используется фиксированная точка, но неважно — это учебный пример.Не, просто задача «освоить C++» примерно настолько же реализуема, как «решить проблему останова».
Вовсе нет. Просто считать, что это число вот прям сразу пойдёт в пакетик на биржу — это несколько ошибочно. Там, например, может быть что-то по смыслу как
И если вы хотите купить 10 акций, а случайно покупаете -10 = 4294967286, то до того, как у вас сработают всякие риск-чеки, дневные лимиты, и прочее, у вас уже уйдёт ордеров на сотню тыщ акций.
CLU.
ML и параметрический полиморфизм. В C++ обкатывали разве что идею «как бы параметрический полиморфизм сделать максимально криво, но чтобы потом было весело делать головоломки и отсеивать людей на интервью». Хорошо разве что для job security.
Здесь согласен.
Потому что вам теперь надо обновлять обе сигнатуры, и компилятор далеко не всегда напомнит вам это сделать.
Потому что теперь вы не можете взять адрес
sendOrder(по крайней мере, в контекстах вроде аргумента для стандартных алгоритмов, где ожидаемый тип callable не фиксирован).Потому что если вы захотите принимать
doubleилиfloatпоследним аргументом, то вам уже придётся обмазываться концептами и писать что-то вродеrequires (!(std::is_same_v<T3, double> || std::is_same_v<T3, float>)). Очень удобно и дружественно к людям, в чьи обязанности входит не только штудирование талмуда++. Кстати, тут крошка-джун пришёл к отцу, и спросила кроха: «папа, а что тут лучше,std::same_asилиstd::is_same_v? Какая вообще между ними разница? Какой-какой частичный порядок? Я полностью каждый день порядок навожу!»И решить проблему останова на сдачу.
Человек, отвечающий подробное, даже не понимает смысла учебных, иллюстрирующих примеров.
Knight capital, кстати, передаёт привет.
Зависимые типы помогут (и помогают).
А какие из новых идей, опробованных в C++, оказались хорошими?
По этой логике в любом языке есть «элементы ООП», и выражение «пишу с использованием ООП» (с учётом неявного засовывания «элементов» в эту фразу) перестаёт иметь какую-либо описательную силу (разве что, понятно, что человек не пишет в машкодах, но это малое количество информации).
Снова вопрос определений, но для меня лично его наличие в языке — это когда язык позволяет
легко инкапсулировать данные на уровне класса, а не модуля (в коде выше на go нигде не написано, что только функция
Sayможет дёргатьname)легко описывать наследование (а не как в C, где можно обмазаться агрегированием и ЕМНИП явными кастами, конечно, но это больно и нетипобезопасно)
легко описывать полиморфизм подтипов (а не снова как в C, где всё опять на кастах и закате vtbl солнца руками)
Уточню свой исходный вопрос: можете привести пример наиболее популярного, на ваш взгляд, типизированного языка, для которого верно утверждение «классического ООП там нет» (с которым вы изначально спорили)?
Она есть, но её я с радостью обсужу чуть позже, как мы придём к согласию по вопросу выше.
Почему? Вот я беру код выше на go и портирую его на C, с точностью до синтаксиса:
Если гошный
User— класс, аSay— его метод, то и здесьUser— класс, аsay— его метод.Пропозал на uniform call syntax в C++ сделал бы это менее глупым вопросом, чем кажется, к слову.
Я их дальше привёл. Можно попробовать прочитать следующий абзац.
Тем не менее, не понял связи. Зачем здесь какие-то слова? В каком смысле «где живут»?
Можно сделать
s/диалектика/религия/gи получится примерно настолько же корректное высказывание.Зачем? Вот вам описание типа для XML-узлов на хаскеле (который вот совсем не ООП-язык):
Нет. В видео (к сожалению, расшифровки нет, так что на текстовую версию сослаться не могу) товарищ показывает, почему не-ООП-подходы оказываются эффективнее и, можно сказать, естественнее конкретно для разработки браузеров.
Впрочем, видеть вопрос «нужно всему верить?» от человека, до того пишущего «я не копал, но уверен» смешно.
Вот как раз про браузеры чувак даёт доклад с говорящим названием OOP Is Dead, Long Live Data-oriented Design.
Зачем вам ООП для XML-парсера?
Например, функции (конвертирующие одни типы в другие). Или, например, события и реакции на них.
Не, серьёзно, DDD настолько естественно, что когда я прочёл пару книжек про DDD, то выяснил только то, что именно так и называется то, чем я давно занимался в ФП. Там, конечно, дают явные названия для этих инструментов, но они естественные, и скорее отражают организационную структуру, чем код. Ну там, shared kernel для ограниченных контекстов, соответствующих тесно связанным бизнес-процессам, или upstream/downstream, когда одна команда (бизнес-процесс)не может влиять на язык другой команды, но другая команда (бизнес-процесс) всё равно DDD, или anticorruption layer, когда другая команда — не DDD.
Но на практике обо всём этом можно не думать, и всё будет норм. Вам не нужно знать аксиомы Пеано, чтобы посчитать сдачу в магазине.
Явления объективной действительности не противоречивы. Диалектика по описательной силе сравнима со средней религией: можно сделать вид, что описываешь что угодно, но на самом деле не описывается ничего.
Только когда речь заходит о том, что диалектика — так себе инструмент, конечно :]
А можно примеры типизированных языков, где в ваших терминах нет методов класса? А то выходит, что даже в C есть классы и у них есть методы.
Почему? Там есть куча инструментов для этого, и они настолько естественны, что о них даже не задумываешься.
Проблема с диалектикой в том, что она логически противоречива, поэтому она применима ко всему (одинаково плохо).
Думаю, стоит разделять вопросы «почему?» и «зачем?» — у первого больше коннотаций причин, у последнего — целей (например, спрашивать «почему яблоки падают вниз?» норм, а «зачем яблоки падают вниз?» как-то даже звучит глупо, как по мне).
Так вот, вы отвечаете на вопрос «почему?». Я с этим вопросом не спорю и его даже не задаю — в конце концов, у меня тоже есть опыт, например, когда на работе была некоторая ерунда, ощущавшаяся как адская несправедливость, и я после работы её в голове прокручивал, и прокручивал, и прокручивал… Только потом я понял, что это непродуктивно, потому что стратегию поведения это вырабатывать не помогает, а только тратит моё личное время и эмоциональные ресурсы на какую-то бессмысленную ерунду. Вроде собирался вечером кардио поделать, на дорожке всякие там научпоп-новости почитать, а в итоге одна статья на одном месте открыта уже полчаса, а я всё прокручиваю, и прокручиваю, и прокручиваю…
Можно научиться этого не делать. Со способностями «легко забывать о рабочих проблемах» я тоже, тащем, не родился, но непродуктивные, неприятные проблемы (множество которых почему-то почти целиком совпадает со множеством проблем, понятных человеку вне отрасли) можно научиться выкидывать. А продуктивные, приятные проблемы («ну как же вот решить эту архитектурную задачу/ускорить этот кусок кода/етц») выкидывать даже, я бы сказал, и не нужно — мне их обдумывание вообще заснуть помогает, например. Но ими с другим человеком не поделишься, если он не то что вне отрасли, а вне конкретной предметной темы.
Не учиться выкидывать непродуктивные, неприятные проблемы из головы — выбор (почти всегда — осознанный), цели которого я не понимаю.
Я, наверное, слишком эмоционально тупой, чтобы «просто выговориться» для меня работало. Обсудить проблему и прийти к решению — да. Но просто обсуждать проблему без даже надежд на решение — это даже обсуждением язык назвать не поворачивается.
Ну и ещё исходный автор исходной статьи там что-то писал про ну-конечно-мы-за-равные-роли-в-отношениях — я, конечно, за равные роли не выступаю. Одна из моих неравных ролей — обеспечивать партнерше защиту от внешнего мира, и, в частности, изолировать её от максимального числа негативных аспектов своей жизни. У неё их своих хватает, я уверен.
Для выражения которого ООП совершенно не нужен. DDD отлично делается на функциональных языках.
Так же, как не обсуждать с любым другим человеком. Зачем обсуждать негатив, переваривая его что в своей голове, что выплёскивая его на другого человека?
Нет, зачем? Это ж не TLA+ какой-нибудь.