Бьёрн Страуструп: Проблема с программированием

Автор оригинала: Bjarne Stroustrup, Jason Pontin
  • Перевод
image

Статья 2006 года.

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

В 1980-х и 90-х годах Бьёрн Страуструп разработал и внедрил язык программирования C++, который популяризировал объектно-ориентированное программирование и повлиял на многие другие языки программирования, включая Java.

C++ остается архетипическим «высокоуровневым» компьютерным языком (то есть языком, который сохраняет особенности естественного, человеческого языка), и он по-прежнему используется миллионами программистов. Многие из систем и приложений эры ПК и интернета были написаны на C++. Несмотря на это, язык остается спорным, во многом потому что его, как известно, трудно изучать и использовать, а также потому, что дизайн Страуструпа позволяет разработчикам допускать серьезные ошибки программирования в интересах сохранения их свободы.

Страуструп, на протяжении многих лет работающий в AT&T Bell Labs, теперь является профессором компьютерных наук на факультете инженерии в Техасском университете A&M, недалеко от Хьюстона.

Технологический обзор: почему большая часть программного обеспечения настолько плоха?

Бьёрн Страуструп: Некоторые программы на самом деле довольно хороши по любым стандартам. Подумайте о Mars Rovers, Google и проекте “Геном человека”. Это качественное программное обеспечение! Пятнадцать лет назад большинство людей, и в частности большинство экспертов, сказали бы, что каждый из этих примеров невозможен. Наша технологическая цивилизация зависит от программного обеспечения, поэтому, если бы программное обеспечение было бы в действительности таким же плохим, как и его наихудшая репутация, большинство из нас уже были бы мертвы.

С другой стороны, просмотр «типичных» фрагментов кода может заставить меня плакать. Структура ужасающая, и программисты явно не задумывались над правильностью, алгоритмами, структурами данных или ремонтопригодностью. Большинство людей на самом деле не читают код; они просто видят, что Internet Explorer «тормозит».

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

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

Технологический обзор: Как мы можем исправить беспорядок, в котором мы находимся?

Бьёрн Страуструп: Теоретически ответ прост: получше обучите наших разработчиков программного обеспечения, используйте более подходящие методы проектирования и используйте гибкий дизайн, мысля в долгосрочной перспективе. Вознаграждайте правильные, надежные и безопасные системы. Наказывайте за неряшливость.

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

Мы не можем просто остановить мир на десятилетие, пока мы перепрограммируем все, начиная от наших кофе-машин и заканчивая нашими финансовыми системами. С другой стороны, продолжать действовать наобум дорого, опасно и удручающе. Необходимы значительные улучшения, и они могут появиться только постепенно. Они должны прийти на широкий фронт; лишь одного изменения недостаточно.

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

Технологический обзор: Идея, лежащая в основе C++, заключалась в том, что программисты будут работать более активно в обмен на более эффективный код. Bell Labs захотели использовать язык, который несколько действительно умных людей будут использовать для написания кода, работающего на таких компьютерах, как Electronic Switching Systems (ESS), которые были не очень быстрыми. Сегодня очень много быстрых компьютеров и много разработчиков программного обеспечения. Означает ли это, что это сводит на нет всю суть C++?

Бьёрн Страуструп: C++ не был разработан специально для больших коммутационных аппаратов, он был разработан для огромного спектра приложений. Bell Labs была домом для невероятного спектра интересных проектов, охватывающих все масштабы и использующих практически все виды компьютеров и операционных систем. Но да, среднестатистический программист Bell Labs был значительно более способным в сравнении с мнением большинства людей о «среднестатистическом программисте», а надежность и производительность (в этом порядке) считались значительно более важными, чем в большинстве других мест.

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

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

Технологический обзор: В ретроспективе, при проектировании C++, не было ли ваше решение обменять эффективность программного обеспечения, его безопасность и надежность на производительность кода во время выполнения, фундаментальной ошибкой?


Бьёрн Страуструп: Ну, я не думаю, что я сделал такой обмен. Я хочу элегантный и эффективный код. Иногда я это понимаю. Эти дихотомии (между эффективностью и правильностью, эффективностью и временем программиста, эффективностью по сравнению с высоким уровнем и т. д.) являются фиктивными.

То, что я действительно делал, — это разработал C++, как прежде всего язык системного программирования: я хотел иметь возможность писать драйверы устройств, встроенные системы и другой код, который должен был использовать непосредственно. Затем я хотел, чтобы C++ был хорошим языком для разработки инструментов. Это требовало гибкости и производительности, а также способности выразить элегантные интерфейсы. Мое мнение заключалось в том, что для создания более высокого уровня, для создания полных приложений вам сначала нужно было покупать, строить или заимствовать библиотеки, предоставляющие соответствующие абстракции. Часто, когда у людей возникают проблемы с C++, реальная проблема заключается в том, что у них нет соответствующих библиотек или они не могут найти доступные библиотеки.

Другие языки пытались более непосредственно поддерживать приложения высокого уровня.

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

Технологический обзор: Как вы объясняете тот факт, что C++ широко критикуется и многими программистами, но в то же время очень широко используется? Почему этот язык настолько успешен?

Бьёрн Страуструп: Ответ прост: есть только два вида языков: те, на которые жалуются все, и те, которые никто не использует.

Есть более полезные системы, разработанные на языках, которые считаются ужасными, чем на языках, которые хвалили за то, что они красивы — и многое другое. Цель языка программирования — помочь создать хорошие системы, где «хорошее» можно определить разными способами. Мое краткое определение: что-то правильное, поддерживаемое и достаточно быстрое. Эстетика имеет значение, но в первую очередь язык должен быть полезен; он должен позволить программистам этого мира выражать реалистичные идеи лаконично и недорого.

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

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

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

Технологический обзор: В “Дизайне и эволюции C++” вы утверждаете, что Кьеркегор оказал влияние на вашу концепцию языка. Это шутка?

Бьёрн Страуструп: Возможно немного претенциозное заявление, но не шутка. Многие размышления о разработке программного обеспечения сосредоточены на группе, команде, компании. Это часто делается до такой степени, что человек полностью погружен в корпоративную «культуру» без выхода для уникальных талантов и навыков. Корпоративная практика может быть враждебной по отношению к людям с исключительными навыками и инициативой по техническим вопросам. Я считаю такое управление технарями жестоким и расточительным. Кьеркегор был сильным сторонником индивидуума против «толпы» и серьезно поднял вопрос важности эстетики и этического поведения. Я не мог указать на конкретную особенность языка и сказать: «Видите, есть влияние философа девятнадцатого века», но он является одним из корней моего нежелания устранять «уровень экспертного уровня», отменять «злоупотребление» и ограничивать возможности поддержки только тех приложений, которые, как я знаю, будут полезными. Тем не менее, я не особенно люблю религиозную философию Кьеркегора.

Технологический обзор: О чем вы жалеете больше всего?

Бьёрн Страуструп: Ни о чем не жалею! Ну, конечно, я мечтаю о том, что я мог бы сделать по-другому и лучше, но серьезно, кто я такой, чтобы переоткрыть, скажем, винтаж Бьёрна 1984 года? Возможно, он был менее опытным, чем я, но он был не менее умным, вероятно, умнее, и он лучше понимал слова 1984 года, чем я. C++ используется для создания многих систем, которые улучшают нашу жизнь, и это оказало значительное положительное влияние на более поздние языки и системы. Это то, чем можно гордиться.
Проектная школа программирования GoTo
83,44
Образовательный проект для юных программистов
Поддержать автора
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

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

    +3

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

      +9
      Очевидно, он это говорит не сейчас. Например, по его фразе о 15 годах и «Геноме человека» видно, что это очень старое интервью, ведь 15 лет назад проект «Геном человека» уже не только был 13 лет как начат, но и практически закончен. Это интервью 2006 года.

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

      Вот что было сказано на самом деле:
      who am I to second-guess, say, 1984 vintage Bjarne? He may have been less experienced than I, but he was no less smart, probably smarter, and he had a better understanding of the word of 1984 than I have.

        +1
        А почему бы не привести пример правильного перевода? Что не «переоткрыть винтаж Бьерна», а «покритиковать лампового Бьерна». Фразу «had a better understanding of the word of 1984» распарсить не удалось, возможно отсылка к одноименному роману. Часто вижу и в свой адрес «перевод ужасен» (справедливую, если честно) и никаких подробностей.
          +3
          Почти наверняка там опечатка, и он имел в виду ...of the world of 1984.
            +2

            Это не похоже на отсылку к роману. Выглядит как опечатка — world. Мол, старый Бьёрн явно лучше понимал мир 84-го года, чем он сейчас.

              0
              «Кто я такой, чтобы задним числом критиковать Бьёрна времён 84-го года? Пускай у него было меньше опыта, чем у нынешнего меня. Но он был ничуть не глупее, и, вероятно, даже умнее меня, и лучше меня понимал реалии 84-го года.»

              Здесь vintage не имеет значения «винтажный или ламповый». Vintage — это дословно процесс сбора урожая винограда и изготовления вина. 1984 vintage Bjarne означает что-то вроде «Бьерн 1984-го года розлива»
              +2
              Перевод просто ужасен.

              Уши гуглопереводчика торчат отовсюду.
              That works, but often that support comes at the cost of specialization.
              Это работает, но часто эта поддержка стоит за счет специализации.

              А должно быть «поддежка достигается ценой специализации».
              +3
              Но мы-то помним всю правду :)
              Вы пропустили тэг «ирония», или действительно считаете эту шутку за реальное «интервью» Струструпа? ;)
              AFAIK, вот реальное интервью.
                0
                В те времена на ЛОРе не было тега «ирония», все всегда были предельно серьёзны.
                  +1
                  Я не про те времена, а про первый комментарий в обсуждении: некоторые ведь могут и всерьез эту шутку принять.
              +1
              С 1998 года в языке C++ многое изменилось в лучшую сторону в нем появились range-based циклы, лямбда функции и даже строго-типизированный enum. К сожалению до сих пор нет монад и ленивых вычислений, что делает некоторые заявления из интервью Бьёрна актуальным и в наши дни. ))))))))
                0
                Монады (почти) запиливают в C++20 под видом корутин. Замените co_await на <- и co_return на pure.
                +1
                C ++ остается архетипическим «высокоуровневым» компьютерным языком (то есть языком, который сохраняет особенности естественного, человеческого языка), и он по-прежнему используется миллионами программистов.

                SQL гораздо ближе к человеческому языку, чем С++, хотя человек только при решении простых задач использует императивный подход:
                — Сходи в магазин, купи колбасы. Если будут яйца — возьми десяток.
                а для более сложных лучше подошло бы декларативное описание желаемых целей.
                — Давайте построим коммунизм, удвоим ВВП, войдем в пятерку экономически развитых стран.
                С++ в этом плане исключительно императивен.
                  –3
                  SQL гораздо ближе к человеческому языку, чем С++

                  Попробуйте Ruby, вот где красота.
                    +3
                    Честно говоря я побаиваюсь, потому что если
                    «Си» позволяет очень просто выстрелить себе в ногу. На «Си++» сделать это сложнее, но, когда вам это удается, ногу отрывает полностью.
                    Bjarne Stroustrup

                    то начинающий программист на Ruby может легко сделать себе харакири, учитывая специфику этого языка.
                      +2
                      «C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off». Yes, I said something like that (in 1986 or so). What people tend to miss, is that what I said there about C++ is to a varying extent true for all powerful languages. As you protect people from simple dangers, they get themselves into new and less obvious problems. Someone who avoids the simple problems may simply be heading for a not-so-simple one. One problem with very supporting and protective environments is that the hard problems may be discovered too late or be too hard to remedy once discovered. Also, a rare problem is harder to find than a frequent one because you don't suspect it.
                      Начинаем цитировать Библию? Это было сказано 32 года назад! Вас ничего не смущает?
                        0

                        Идём в Вики SQL first appearance 1974, первый стандарт 1986 как раз 32 года назад. Теперь можно спорить?

                          +1
                          О чём спорить-то? «Отстрелить себе ногу» можно и на JS, и на C# — долго ли «умеючи»! Проблема ведь не в тулзах, а в головах. В real life люди работают с очень опасными, сложными и капризными устройствами — и ничего, выжившие становятся высокооплачиваемыми профессионалами.
                      0
                      Ruby чарующе элегантен, но он в другой категории — скриптовых языков.
                      Вот если когда-нибудь по-настоящему взлетят Crystal и Elixir — вот будет красотища…
                      0
                      а для более сложных лучше подошло бы декларативное описание желаемых целей.
                      — Давайте построим коммунизм, удвоим ВВП, войдем в пятерку экономически развитых стран

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


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

                        +1
                        Как, например, LINQ в C#.
                          +1
                          Только императивный раствор отлично выражается на ФП теми же монадами и прочими способами управления эффектами.
                            0
                            Это какими, к примеру, монадами?
                              +1
                              Смотря какого сорта клей нужен (в этом, кстати, отдельная прелесть, потому что чем больше возможностей у вас ограничить себя в доступной вам в клею функциональности, тем лучше). По крайней мере, у меня это часто стеки с участием StateT, ResourceT и тому подобного.
                        +3
                        Мне кажется, что основная проблема C++ в том, что Бьярн — очень мягкий и хороший человек и старался никогда никому не говорить «нет»…
                          +3
                          Мне тоже кажется, что если бы он был бы по-жестче, как «Великодушный пожизненный диктатор» Гвидо, то дела бы пошли.
                          без шуток
                            0

                            Гвидо загнал сообщество в проблему 2vs3, поэтому тут тоже не все хорошо.


                            P.S. Ну или при его попустительстве загнали. Не знаю эту историю полностью.

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

                                По моим ощущениям это сильно ударило по позициям Python в целом. Пока PHP усиленно работал над производительностью и актуализацией, а Golang надо многопоточностью, Python просто ушел в болото на несколько лет.

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

                                    Ну, например, в этом году я впервые начал новый проект на Python 3. До этого вопросы обратной совместимости по библиотекам всегда останавливали.

                                      0
                                      какая библиотека мигрировала только в этом году?
                                        0

                                        Так сказать не получится: проект-то новый, поэтому просто посмотрели и поняли, что все есть. А до этого я работал над OpenStack, а там все исторически на 2.7 c редкими вкраплениями Ruby и Python 3.


                                        Проблема-то ещё и в том, что работает — не трожь. Т.е. резона переписывать, например, объвязку GPDB на 2.7 просто нет пока. И таких проектов море, а следовательно инсталяционная база у Python 3 меньше и качество обратной связи ниже. По крайне мере так было где-то до 3.4-3.5. Сейчас за полгода проекта на 3.6-3.7 ничего не словили критичного.

                                          0
                                          > работает — не трожь. Т.е. резона переписывать, например, объвязку GPDB на 2.7 просто нет пока

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

                                            Дьявол в деталях. Все же PHP 5.x и PHP 7.x это очень разные языки. Да что там говорить: даже между 5.1 и 5.6 изменили много (наконец грохнули globals, сменили ссылочную логику). Я участвовал в таком переходе как зритель. В целом не сложно, но сумарно с месяц человеко часов это съело: надо же не только изменить (что не много заняло), но протестировать, изменить поставку (а софт почти коробочный), написать документацию и т.д.


                                            На мой взгляд действительно хорошая совместимость только у C, потом C++, потом Java, а все остальное в целом проблемно. Беда в том, что Python 3 не предлагал существенных плюшек по сравнению с Python 2. Вот зачем переходить с PHP 5 на PHP 7 всем было понятно, а Python — нет.

                                              0
                                              Беда в том, что Python 3 не предлагал существенных плюшек по сравнению с Python 2.


                                              Так уж и не предлагает? А мне например со своей стороны не понятно зачем не только переходить с PHP 5 на PHP 7, а вообще зачем на нем писать код.

                                              Хотя статья о С++ и мы ушли в жуткий оффтоп.
                                                +1

                                                Потому что по скорости в вебе его обгоняет только Go lang (компилируемый:-) )
                                                Потому что одна из самых больших комьюнити
                                                Потому что невероятно огромный выбор хороших и не очень хороших пакетов\фреймворков
                                                Потому что огромное количество вакансий (среди веба, только у JS больше)
                                                Потому что 80% веба до сих пор PHP
                                                Потому что язык жив и активно развивается

                                                  +1
                                                  Потому что по скорости в вебе его обгоняет только Go lang (компилируемый:-) )

                                                  www.techempower.com/benchmarks
                                                  www.techempower.com/benchmarks/#section=data-r15&hw=ph&test=query
                                                  Сравнение производительности веб фреймворков на разных языках. Посмотирте позиции PHP, Java, Py, Ruby, Rust, Go.
                                                    +1
                                                    Я хаскель-наркоман и поэтому я с год назад сравнивал что-то на Go с чем-то на хаскеле, и у меня хаскель был, скажем так, побыстрее.

                                                    Ну а про Rust вам уже тоже написали.
                                                  0
                                                  Все же PHP 5.x и PHP 7.x это очень разные языки.

                                                  А аргументация будет какая-нибудь? Всё же PHP 5.x от 7.x отличаются так же, как питон 3.4 от 3.5, наличием тайпхинтинга и пачкой других мелочей, и ничего фатального, что перевело бы PHP 7.х в разряд «очень разный язык» нет.
                                                    0

                                                    Вся аргументация есть в документации на php.net.

                                                      +1
                                                      Отличный ответ. Получается, что ваше замечание голословно, т.к. документация точно так же говорит, что никаких отличий особых нет и документация по 5.х почти полностью повторяет 7.х.

                                                      Учитывая вышеизложенные тезисы, то вся логика последующего комментария, которая отталкивается от этого замечания лишь плод вашего воображения, либо неудачное стечение обстоятельств. На практике же переход с 5.х на 7.х, если в проекте участвовали компетентные специалисты, не использующие функционал, который устарел лет на *дцать, требует ровно два телодвижения — установка 7.х-fpm и рестарт сервера.
                                                          +1
                                                          Не так уж и много, чтобы говорить о разных языках. На деле я встречал только две несовместимых вещи: отсутствие драйвера mysql и eval в регулярных выражениях, остальное в обычном коде не встречается. И эти две проблемы имеют достаточно простое решение, и не требуют переписывания 99% кода.
                                                            +2
                                                            Невероятно, задепрекейтили конструкторы из 2000х годов и вместо Warning ошибки начали кидать Deprecated. Как же я могу об этом забыть, ну всё, теперь точно другой язык :D
                                                      0
                                                      Ну питон 3 активно развивается как язык, плюшек там много появляется, я питон только почуток смотрю, поэтому много перечислить не готов, однако например type hints вполне крутая штука для больших проектов.
                                  +1
                                  Мы выполняем много маленьких чудес посредством проб и ошибок, чрезмерного использования грубой силы и многих испытаний, но зачастую этого недостаточно.

                                  Оригинал:
                                  We perform many minor miracles through trial and error, excessive use of brute force, and lots and lots of testing, but–so often–it’s not enough.


                                  К сожалению, мой английский далеко не так силён, но мне кажется, что не стоило переводить «brute force» — так здесь имелся в виду метод полного перебора (то есть не чрезмерное использование грубой силы, а использование неэффективных решений «в лоб»).
                                  Кроме того, «and lots and lots of testing» хочется перевести как «и проведения огромного количества тестов».
                                  Поправьте меня, пожалуйста, если я ошибаюсь
                                    0

                                    Тут именно "метод грубой силы", потому что речь идёт о надёжности программ и сложности их проектирования. Но судя по всему, у автора это получилось случайно, потому что "lots of testing — многих испытаний" — былинный отказ.

                                      0
                                      А что есть полный перебор (или же, как Вы сказали, «неэффективные решения в лоб»), как не применение грубой силы?
                                        +1
                                        Несомненно, перевод соответствует действительности. Но на практике я встречал варианты «полный перебор» и варваризм — брутфорс. «Грубая сила» даже не припомню.
                                        Я изначально понимал, что всё это сильно субъективно, поэтому мне было интересно мнение сообщества (кроме того mbait сказал, что мой вариант перевода неверен). Считайте, что это отсылка к спору по поводу использования интерсептор(интерцептор)/перехватчик, синглтон/одиночка, прокси/заместитель. Честно говоря, мне сильно претят варваризмы, но первые варианты даже в контексте мною воспринимаются четче, чем вторые.
                                          0
                                          Дело в том что в данном случае Страуструп говорит о «brute force» не как о полном переборе(это значение у этой фразы не основное), а именно как о грубой силе, то есть брать мощностью железа, а не крутостью алгоритма или эффективностью реализации, а уж алгоритм ли там полного перебора или, например, использование веб-приложений вместо нативных — не важно.
                                            0
                                            https://ru.wikipedia.org/wiki/Атака_«грубой_силой»

                                            Там все три варианта приведены как равноправные, причём «грубая сила» — как основной.
                                        0

                                        <режим ворчуна> в статье довольно много неточностей перевода (широкого круга приложений вместо широкого круга применений) и разного рода неточностей (багги), хорошо бы подтянуть знание языка перед переводом тематических текстов</режим ворчуна>

                                          +3

                                          Ну не знаю как по мне проблема в инструменте. Люди они такие есть были и будут всегда. Всегда будет горстка толковых и куча аматоров. А инструмент должен если не предотвращать то не поощрять эти ошибки. С++ как бензопила без защитного чехла и предохранителя на цепочке.

                                            0

                                            Я к тому что с++ писался так буд-то вокруг одни гении и специалисты. Возможно когда-то это было так но явно не сейчас

                                              +1
                                              Но надо отметить, что современные стандарты C++ (начиная с 11-го) и Core Guidelines ситуацию довольно хорошо исправляют — по крайней мере, если придерживаться их рекомендаций и не использовать устаревшие подходы, риск случайно отпилить себе руки при запуске бензопилы стал во много раз меньше, да и пользоваться ей теперь ощутимо удобнее.
                                                +2
                                                так в этом и проблема, что человек должен знать и помнить, что можно, а что нельзя, на си тоже можно писать крутой код если всё знать и ничего не забывать, но человек так не умеет
                                                  0
                                                  Мне недавно на Fortran пришлось дописать код в один проект, я с удивлением обнаружил, что в те далекие времена «знать и помнить, что можно, а что нельзя,» нужно было на порядки больше чем сейчас!
                                                  А те кто знали, писали по настоящему крутой и быстрый код.
                                                  А сечас что?! Reaсt, Redux и на продакшен.
                                                    0
                                                    таланты бывают, но на них отрасль не построишь, тем более речь не про крутой и быстрый, а про надёжный, Дональд Кнут и тот попал на бабки за свои баги.
                                                    +2
                                                    Список «что можно, а что лучше не надо» довольно простой, на самом деле. Можно RAII и современные стандарты, а лучше не надо — сырые указатели, и все то, что объявлено deprecated. Те же Core Guidelines при этом очень хорошо объясняют, как и почему, что даже запоминать не надо, нужно просто один раз прочитать и понять.

                                                    И тут еще накладывается проблема с обучением, об этом сам Страуструп и другие на конференциях уже не раз говорили:



                                                      0
                                                      ну вот что-то не получается учить, гугл вроде не самых худших разработчиков нанимает, но приходится изобретать всякие огороженные Go чтобы они себе ноги не отстреливали.
                                                        0
                                                        Go покрывает все-таки весьма небольшую сферу использования C и C++.
                                                          +2
                                                          Гугл имеет возможность нанимать и околотоповых разработчиков, и свежих студентов, которым надо на чём-то микросервисы хреначить.
                                                        0
                                                        C++ Core Guidelines, в соответствии с концепцией, включает в себя статический анализатор как неотъемлемую часть.
                                                          0
                                                          Да статические анализаторы изобрели давно, но чуда что-то не случилось.
                                                            0
                                                            Это скорее потому, что ими мало кто пользуется. Кому-то дорого (а бесплатные все-таки сильно проигрывают коммерческим решениям), кто-то в них не верит, а кто-то вообще о них слышал только отдаленно.
                                                              0
                                                              Конкретно в случае Core C++ Guidelines существующие анализаторы умеют проверять достаточно много, чтобы ваше утверждение «так в этом и проблема, что человек должен знать и помнить, что можно, а что нельзя, на си тоже можно писать крутой код если всё знать и ничего не забывать, но человек так не умеет» было неверным. Большая часть вполне проверяется.
                                                      +1
                                                      Да, надо признаться себе, что человек это самое ненадёжное звено и не рассчитывать на его идеальную работу при проектировании инструментов вроде языка программирования.
                                                        +1
                                                        Ну, не совсем так. Защитный чехол и предохранитель можно поставить, после того как отпилишь себе 3-4 ноги, конечно. Зато на собственном опыте осознаешь, для чего они нужны и когда необходимо их снимать, для того чтобы реализовать низкоуровневые вещи.
                                                        Ну а как иначе? Если выдумывать какие-то безопасные инструменты, то вы рано или поздно упрётесь в необходимость подвигать биты туда-сюда.
                                                          0
                                                          Системного программирования всё меньше и там интересным вариантом, не отягощённым обратной совместимостью, выглядит Rust
                                                            0
                                                            Для того чтобы своять свою, допустим, хэш таблицу, вам придется повертеть в руках raw поинтеры.
                                                            Rust, конечно не имеет наследия в виде доисторического Си, но для меня этого недостаточно, тем более с++ со временем всё лучше и лучше, вон в версии от 17 года подсыпали сахарку ещё.
                                                            Само появление rust'a это следствие периода застоя в комитете с++, я сам когда знакомился с плюсами, был удивлён что вот это и есть то на чём написано всё в мире.
                                                              0
                                                              у C++ вроде до сих пор проблемы с зависимостями?
                                                        +1

                                                        Не С ++, а С++!

                                                          0

                                                          ИМХО. С++ как один из инициаторов ООП 'эры' это беда.
                                                          Ещё студентом ощущал что c ооп что-то не так — на нем не удается красиво написать код увязав бизнес логику и ООП парадигму.
                                                          Сейчас по прошествии лет работы с разными языками это понимание только укрепилось.
                                                          Для котиков и окошек ООП отлично подходит, для бизнес логики где нет четкого наследования и нет необходимости в объектах, т.к. в основном код это данные и функции работы над данными(но не вместе) — не подходит.

                                                            0
                                                            А можете прояснить свою мысль более развернуто? И предложить парадигму, более подходящую для вашей бизнес-логики?

                                                            для бизнес логики где нет четкого наследования

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

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

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

                                                                  Т.е. вы предлагаете писать лишний код, чтобы решить проблемы которые при тестировании создает ООП, подход? Я это так понимают.


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

                                                                    +4
                                                                    Ровно наоборот. ООП не создает проблем при тестировании, а при правильном применении позволяет красивее и удобнее создавать тестовые окружения и тестовые сценарии.
                                                                    +1
                                                                    Если есть класс, ответственность которого — только хранить данные, то логично его избавить от всего, что к этому не относится, получив POD. А класс (или скорее классы, но не важно), который отвечает за действия, с одной стороны, имеет большой риск оказаться -er классом, а с другой, может без особых проблем быть заменен на набор функций.
                                                                    Вот и получается, что такой подход отличается от процедурного программирования по форме, но не отличается по сути: у нас те же данные, функции, а классы здесь особенно-то и не нужны. Поэтому я и говорю, что он, на мой взгляд, противоречит духу ООП.
                                                                    PS: Я не великий эксперт, вполне могу ошибаться. Да и не факт, что верно понял ваше предложение.
                                                                      +1
                                                                      только хранить данные, то логично его избавить от всего, что к этому не относится, получив POD.

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

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

                                                                      Если в языке есть механизм неймспейсов, чтобы не захламлять глобальную область — да, может быть заменен, если для работы класса действий нам не нужно хранить какое-то состояние для его инстансов (а иногда бывает нужно). Плюс с набором функций часто сложнее (я не говорю что невозможно, хотя зависит от конкретного языка) применить IoC/DI подход для удобного тестирования.
                                                                        +1
                                                                        До тех пор, пока нам не нужно их получать в разных видах, валидировать, и т.д.
                                                                        Как раз здесь я вас неправильно понял. Когда вы писали о «классах, представляющих данные», я думал, вы имеете в виду POD.
                                                                        Разве это плохо?
                                                                        Вроде это более или менее известный антипаттерн. www.yegor256.com/2015/03/09/objects-end-with-er.html
                                                                        Если в языке есть механизм неймспейсов, чтобы не захламлять глобальную область
                                                                        Полностью согласен, что если в языке нет неймспейсов, то можно использовать классы для их замены. Но у нас же вроде C++.

                                                                        Насчет Di согласен.
                                                                    +3
                                                                    «Данные и методы их обработки» — это определение понятия «класс» в ООП. Определение класса противоречит духу ООП?
                                                                      0
                                                                      Всегда думал, что «данные и методы их обработки» — это определение абстрактных типов данных. А ООП — это инкапсуляция, наследование, полиморфизм. Я ошибаюсь?
                                                                        0
                                                                        ООП — это (согласно рус. Вики):
                                                                        методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования
                                                                        Инкапсуляция, наследование, полиморфизм — это принципы ООП, которые, ИМХО, не есть сама суть ООП. А так называемый «дух», ИМХО, присущ не самому ООП, а программисту, который его использует. И если для кого то «дух» ООП — это использование наследования везде, где только можно, я советую обратиться к Саттеру и Александреску — они доходчиво объясняют, когда стоит использовать наследование, а когда рак на горе таки не свистит.
                                                                          0
                                                                          Отсылка к википедии — сильный аргумент, но все-таки не истина в последней инстанции. Что-то Вы меня задели, хочется ответить. Хотя я и не силен в призывании духов, в том числе и «духа ООП», но позволю изложить свой «голос с белтА» (или, если угодно, из программистских окопов).
                                                                          Суть ООП предельно проста: представление программы, как совокупности «линейно независимых» сущностей, скрывающих свое внутреннее состояние и доступных для взаимодействующих исключительно в соответствии со строго определенными протоколами. Такие сущности и «экспортируемые» ими протоколы в ООП и называются объектами. Как это делается средствами языка — вопрос десятый. В C++ — это класс и совокупность его публичных методов, в JS — это (как пример) сигнатура функции, возвращенной из другой функции и «закложурившей» в качестве «полей класса» экземпляры локальных переменных, в Rust — это (опять же, пример) структура + совокупность ее собственной реализации и реализуемых для нее трейтов, для C это может быть WinProc со switch-ом на десяток экранов. Варианты можно добавлять. Главное — есть инкапсулированное состояние и определение допустимых способов взаимодействия. По сложившейся традиции, если нет иерархии наследования и виртуальных методов, то такой подход называется «абстрактные типы данных», а если добавляется наследование и позднее связывание — то, почему-то, ООП.
                                                                          Ну, а что касается Александреску и Сеттера, то они замечательные эксперты, но мне ближе Шон Пэрент, особенно его «Inheritance is the root cause of all evil».
                                                                          Как-то так, что-то тема меня забрала, мог бы еще долго распространятся и аргументировать, но затыкаюсь ибо и так слишком длинно.
                                                                            +2
                                                                            Прошу прощения, если обидел лично Вас, мои замечания на счет «духа» ООП относятся к предыдущим комментаторам, которые обвиняли С++ в том, что их личная бизнес логика не совместима с их личным пониманием ООП.
                                                                            В моем понимании ООП — это то, что написано на Вики, только без последней фразы про иерархию наследования. Просто объединяем данные и методы их обработки в классы — вот и ООП. Если у меня четко одно поведение — не будет полиморфизма, ничего страшного. Если у меня простая структура, содержащая данные, к которым много где нужен прямой доступ — долой инкапсуляцию. А наследование всегда пытаюсь использовать по минимуму, ибо, несмотря на его удобство в правильных ситуациях, в остальных оно всегда вызывает проблемы. Принципы принципами, но пусть все же ООП работает на меня, а не наоборот. Это лишь мое понимание, которое, очевидно, не совсем совпадает с мнением большинства, но пока что как то так.
                                                                            Единственное же, что я хотел сказать оскорбившим Вас комментарием — это то, что не стоит обвинять ООП в своих проблемах, а С++ — в проблемах ООП, ибо ООП — не единственная парадигма поддерживаемая в С++, а решение проблем — это не задача ООП.
                                                                              0
                                                                              Нет проблем, какие претензии, да меня особо не обидишь:) Мне не нравятся очень распространенные в последнее время «возвышенное» отношение к ООП и расширенная его трактовка. Где-то в 90-х прошлого века это можно было понять, не не в наше время.
                                                                              Еще раз повторю основную свою мысль: ООП это это метод проектирования и реализации, позволяющий лучше справиться с управлением состоянием программы путем разделения этого состояния на меньшие части и ограничения на способы взаимодействия этих частей. Нет нетривиального и необходимого состояния — ООП не особо нужно. Например, когда программа есть функция, перемалывающая одни данные в другие — много «OOP inside» скорее вредит.
                                                                              Есть более узкое понимание ООП: инкапсуляция, наследование, полиморфизм. Такое понимание «взлетело», потому что очень упростило программирование оконного интерфейса, вот его и стали всюду пихать, где надо и не надо. А классы тут просто деталь реализации. Сам Страуструп, кстати, про классы писал (цитирую по памяти): "… классы — это модули, но такие, что можно одновременно создавать много экземпляров ...".
                                                                        0
                                                                        Так я именно это и хочу сказать. «Данные и методы их обработки» — это класс. А когда данные отдельно, методы отдельно — это уже фигня какая-то, а не ООП.
                                                                          0
                                                                          Ах да, прошу прощения, неправильно прочитал. Но мне все же не кажется, что это противоречит какому-то духу. Если данные какой то сущности должна особым образом обрабатывать другая сущность, это не повод все мешать в один класс. Другое дело, если это происходит постоянно — тогда стоит задуматься над архитектурой проекта. Если все становится слишком уж сложным — никто не мешает пересесть на процедурщину. Но само ООП ни в чем не виновато.
                                                                            0
                                                                            Мне кажется, Вы путаете синтаксический сахар (ну, и некоторые возможности оптимизации) с логической сутью. Например:
                                                                            class Cpp {
                                                                              int a;
                                                                              int b;
                                                                            public:
                                                                             void  f() { ... }
                                                                            };
                                                                            

                                                                            эквивалентен:
                                                                            struct PureC {
                                                                              int a;
                                                                              int b;
                                                                            };
                                                                            void f(struct PureC * this) {...}
                                                                            

                                                                            Когда-то, во времена CFront, это так и было, я еще помню) Есть концептуальные моменты, например, конструкторы и деструкторы (как средства поддержания инвариантов и в меньшей степени управления жизненным циклом), но основная разница в удобстве программирования, а не в сути. А «дух ООП» пускай носится над бездной, в программировании ему мало места.
                                                                              0
                                                                              Да, дело здесь не в сахаре. Я полностью согласен, что оба варианта кода выше — это ООП. В свое время писал проект на C89 с полноценным ООП, с наследованием, полиморфизмом, всеми делами, это был очень интересный опыт.
                                                                              Я подумал, что, возможно, ситуация у комментатора выше похожа на ту, что была в одном из моих проектов, где не получалось нормально скрыть поля объектов (для любого чиха приходилось использовать много полей разных объектов), а функции работали с несколькими равноправными объектами и не очень-то собирались в логически связанные группы. И в этом случае, вместо того, чтобы писать
                                                                              class C1 {
                                                                              public:
                                                                                int a, b;
                                                                              };
                                                                              class C2 {
                                                                              public:
                                                                                int a, b;
                                                                              };
                                                                              ...
                                                                              class Methods {
                                                                                public:
                                                                                static C1 f1(C1, C2, C3);
                                                                                static C2 f2(C5, C6, C7);
                                                                              ...
                                                                              };
                                                                              лучше написать что-то вроде
                                                                              struct C1 {
                                                                                int a, b;
                                                                              };
                                                                              struct C2 {
                                                                                int a, b;
                                                                              };
                                                                              ...
                                                                              C1 f1(C1, C2, C3);
                                                                              C2 f2(C5, C6, C7);
                                                                              ...
                                                                              Потому что эти два варианта — оба следуют процедурной парадигме, а не объектно-ориентированной (и именно в этом смысле в этом коде нет «духа ООП»). Первый от второго отличается лишь сахаром.
                                                                              PS: сейчас я уже как-то не очень уверен, что изначально автор имел в виду именно это, но сначала я понял его именно так.
                                                                        0
                                                                        А можете прояснить свою мысль более развернуто? И предложить парадигму, более подходящую для вашей бизнес-логики?

                                                                        Я не хотел тут развиваться холивары по этому альтернативы специально не писал. А сделал акцент на недостатках ООП, которые на мой взгляд ставят эту парадигму под сомнения.


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

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


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

                                                                        Тогда мне так же, непонятно зачем нужен ООП. Если вы игнорируете идею объекта — как вещи в себе.
                                                                        Какой нибудь JSON или HTTP запрос в своей сути является сочетанием 2-х коллекций ассоциативного массива и списка. Для манипуляции этими двумя типами (ассоциативный массив и список) есть отличные функции в любой стандартной библиотеке, для чего нужна обертка в виде класса?


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

                                                                        Думаю что в вашем случае представление о FP извращено представителями вида Haskell, языки поддерживающие основные концепции FP не обязательно должны иметь сложную систему типов. Erlang, Clojure простые, но реализуют самые важные, С ПРАКТИЧЕСКОЙ, точки зрения концепции из FP.

                                                                          +2
                                                                          Но тогда встает вопрос, если вы игнорирует ключевые части некоторой парадигмы — зачем она вам?

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

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

                                                                          есть отличные функции в любой стандартной библиотеке, для чего нужна обертка в виде класса?

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

                                                                            Обычно такие вопросы возникают у тех кто не смирился с мыслью, что объект в ООП не равен объекту реального мира. Это есть абстракция. А все абстракции кастрированы по определению — они реальность показывают далеко не со всех сторон. Об этом прямо говорит Single Responsability Principle — объект отвечает за что то одно и от этого зависит какой он — инкапсулирует что либо или наследуется или просто делает что то. За что должен отвечать класс/объект? — а вот это уже вопрос проектирования. А проектирование архитектуры программного кода как и любое проектирование есть не только инженерия, но и в не малой степени искусство. Поэтому нельзя просто понимать или не понимать ООП, принять его или не принять — это есть подход. Возможны другие подходы, но только те что позволяют проектировать. Иначе с их помощью не построить сложную систему. ФП в целом проектировать позволяет, но при этом свойства ФП и ООП различаются и выходит что и свойства спроектированных систем различны. Т е там где буксует ФП — отлично растет ООП и наоборот.
                                                                              –2
                                                                              Обычно такие вопросы возникают у тех кто не смирился с мыслью, что объект в ООП не равен объекту реального мира.

                                                                              Причем тут реальный мир, я писал что-то о реальном мире? А вот во всех книгах про ООП обычно и моделируются объекты из реального мира — животные и иерархия в компании и подобное.
                                                                              В реальности 99% кода это не реальный мир — кэш, HTTP, ответ от БД, обход коллекции, и т.д. На них как раз ооп и не ложится в отличии от вымышленных примеров.


                                                                              ФП в целом проектировать позволяет

                                                                              Что именно из деталей ФП мешает проектированию?)


                                                                              Т е там где буксует ФП — отлично растет ООП и наоборот.

                                                                              Можно привести примеры и теоретические выкладки где ФП буксует а ООП нет и наоборот. Без них вы как бы просто пустословите, ИМХО.


                                                                              P.S.
                                                                              Хотелось бы в проектировании/программировании обойтись без искусства иначе спорить можно до бесконечности.)
                                                                              Что бы самому не быть голословным, приведу примеры того как предметная область не ложится на ООП из-за чего вылазит геморой.
                                                                              ORM исключительно продукт ООП, попытка натянуть эту парадигму на реляционную. Из-за чего для достаточно простой задачи извлечь данные из БД нужно городить кучу классов и хитрых связей между ними. Как итог вам нужно знать SQL + ORM, две системы вместо одной. Я уже не говорю о том что ORM библиотеки между собой могут существенно отличаться.
                                                                              Во пример отличного применения ООП:)
                                                                              https://github.com/spring-projects/spring-framework/tree/master/spring-web/src/main/java/org/springframework/http
                                                                              90% кода просто перегоняют данные из одного типа(класса) в другой.
                                                                              И все это чтобы представить такую простую штуку как HTTP запрос/ответ:


                                                                              GET /wiki/страница HTTP/1.1
                                                                              Host: ru.wikipedia.org
                                                                              User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5
                                                                              Accept: text/html
                                                                              Connection: close
                                                                              (пустая строка)

                                                                              Которую в любом ЯП можно представить как ассоциативный массив.


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

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

                                                                                Я бы не обобщал это на прямо все книги. Не вы не я не читали всех книг по ооп.
                                                                                Можно привести примеры и теоретические выкладки где ФП буксует а ООП нет и наоборот. Без них вы как бы просто пустословите, ИМХО.

                                                                                Давайте не будем бросаться колкостями если вы реально хотите диалога а не драки, хорошо? Как вам пример с оконными интерфейсами?
                                                                                В реальности 99% кода это не реальный мир — кэш, HTTP, ответ от БД, обход коллекции, и т.д. На них как раз ооп и не ложится в отличии от вымышленных примеров.

                                                                                Впервые слышу что на кэш или http ооп «не ложиться»
                                                                                Которую в любом ЯП можно представить как ассоциативный массив

                                                                                Вот как раз этого ООП старается избежать. Это называется «выхолащивание» абстракций. Т е в любой момент можно добавить/удалить из этого массива поле что приведет к неработоспособности кода, но с первого взгляда эта проблема будет скрыта и не то что компилятор не определит, но и программисту придется отслеживать все места в коде где идут операции с этими ассоциативными списками. Тогда как в ооп это либо вообще не скомпилируется, либо можно будет легко найти где идут операции с этим полем. Если уж хотите корректное сравнение с ФП тогда в пример нужно приводить записи(record) ну или алгебраические типы. Но записи мало чем отличаются от объектов с оторванными методами и в принципе их легко имитировать на ООП. Алгебраические типы конечно уникальны для ФП, но и они имеют свою нишу. Если уж на то пошло, то самое сильное отличие ФП от ООП — это использование ридонли-структур. Именно из этого вытекает большинство плюсов ФП и одновременно его же минусов.
                                                                              +3
                                                                              Думаю что в вашем случае представление о FP извращено представителями вида Haskell, языки поддерживающие основные концепции FP не обязательно должны иметь сложную систему типов.

                                                                              Приехали, Haskell у нас теперь извращает FP.

                                                                              FP — это в первую очередь про типы, про алгебру типов, про типобезопасность и корректность. Да, система типов в хаскеле — unsound, и вообще Hask is not a category, но если вы эту unsoundness видите и можете обсудить, равно как и понимаете, почему именно Hask is not a category и что это ломает, то мозги у вас уже достаточно вывернуты, всё в порядке.

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

                                                                              Ну и если что-то противопоставлять сложным и извращённым системам типов, то я бы говорил о каких-нибудь идрисах, там нет всего этого месива из GADT-TypeFamilies-FunDeps-RankNTypes-DataKinds-TypeInType, там просто сразу нормальные завтипы. Но не Erlang или Clojure.

                                                                              Erlang, Clojure простые, но реализуют самые важные, С ПРАКТИЧЕСКОЙ, точки зрения концепции из FP.

                                                                              Какие?
                                                                            +2
                                                                            Мне кажется, что разговоры о нужности/полезности/оптимальности (ненужное зачеркнуть) ООП оправданы только по отношениям к языкам, в которых все есть ссылка на класс, а любое действие — вызов метода, обычно виртуальный. У C++ могут быть проблемы с «истинным функциональным программировании», но и только. А так — есть место ООП и есть место, где лучше без ООП.
                                                                            Правда, и туда пробрались глобальный функции… )
                                                                              0
                                                                              У C++ могут быть проблемы с «истинным функциональным программировании», но и только.

                                                                              Не, с истинным функциональным программированием как раз всё прекрасно. Берёте, значится, темплейты…
                                                                              +2
                                                                              Для котиков и окошек ООП отлично подходит, для бизнес логики где нет четкого наследования и нет необходимости в объектах

                                                                              А почему нет необходимости в объектах? Объекты обладают свойствами: состояние, идентичность, поведение. Я думаю бизнес-объекты этим тоже обладают.


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


                                                                              Что такое "четкое наследование" и почему в бизнес логике его нет?

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

                                                                                  Из Мейера помнится, что при многопоточности в C++ f(g(x),y(z)); — это не то же самое, что auto a = g(x); auto b = y(z); f(a,b);. А так язык неплохой, и Кьеркегор, как оказалось, в деле...

                                                                                    +2
                                                                                    Вроде то же самое, что и
                                                                                    if (some_random() % 2 == 0)
                                                                                    {
                                                                                      auto a = g(x);
                                                                                      auto b = y(x);
                                                                                      f(a, b);
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                      auto b = y(x);
                                                                                      auto a = g(x);
                                                                                      f(a, b);
                                                                                    }
                                                                                    

                                                                                    , но по новому стандарту, вроде всегда должен выполняться if, или только будет должен…
                                                                                      +1
                                                                                      Начиная с C++17 всегда только if: [intro.execution.16]
                                                                                      Every value computation and side effect associated with a full-expression is sequenced before every value
                                                                                      computation and side effect associated with the next full-expression to be evaluated
                                                                                        +1

                                                                                        По-моему, здесь говорится о законченных выражениях ("full expression"), аргументы функции являются подвыражениями (subexpressions), поэтому к ним это не относится. То есть ваша цитата фактически гарантирует, что statement1(); statement2(); выполнится в порядке 1-2.


                                                                                        Насколько мне известно, до C++17 в стандарте ничего не было про порядок в аргументах функции, поэтому это было UB, а теперь официально закреплено, что порядок произвольный. Я не знаю, где выдержку прямо из стандарта взять, но на cppreference вот так написано:


                                                                                        15) In a function call, value computations and side effects of the initialization of every parameter are indeterminately sequenced with respect to value computations and side effects of any other parameter.
                                                                                          +1
                                                                                          Все верно, я говорил про вторую часть первого комментария: auto a = g(x); auto b = y(z); f(a,b);А параметры функции, насколько я понимаю, описываются [intro.execution.17]:
                                                                                          Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. — end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a memory location (4.4) is unsequenced relative to either another side effect on the same memory location or a value computation using the value of any object in the same memory location, and they are not potentially concurrent (4.7), the behavior is undefined. [ Note: The next section imposes similar, but more complex restrictions on potentially concurrent computations. — end note ]
                                                                                          Получается, они должны быть unsequenced. Странно, что cppreference говорит о другом. Возможно, я где-то запутался.
                                                                                            +1
                                                                                            Нет, все нормально с cppreference, это я читать не умею. [expr.call.5]:
                                                                                            The postfix-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.
                                                                                      +1

                                                                                      Ну тут дело вроде даже не в многопоточности, а в том, что в C++ не гарантируется порядок вычисления аргументов функции и даже то, что они будут вычислены последовательно. Это, например, приводит к опасным и трудно-находимым багам. Например,
                                                                                      f(unique_ptr<int>(new int(100)), g()) может привести к утечке памяти, если g() выбрасывает исключение.

                                                                                        +1
                                                                                        вот вы привели пример из книги Майерса на тему «зачем нужен make_unique», но в угоду аргументу забыли про make_unique. Вас совесть после этого не мучает?
                                                                                          0
                                                                                          Где забыл? Пример как раз должен проиллюстрировать, зачем оно нужно.
                                                                                            0

                                                                                            Вот мне приходится писать код с условием, что он будет компилироваться на g++-4.7, в нем даже C++11 не весь, а make_unique лишь в 14м стандарте появился. Может я не один такой с устаревшими компиляторами, там эта проблема может быть актуальной.

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

                                                                                        А ведь если тренды пойдут так, как сейчас — эти слова, которые надо выбить в граните, могут, увы, стать "Говорил я вам — не прислушались". Достаточно взглянуть, скажем, на Atom (который редактор)…
                                                                                          0
                                                                                          C++ сейчас учу и он начинает мне нравиться. Но: во-первых, сочинял его человек, не учившийся математике или ненавидящий её. Глядя на выражение вида A(b), математик никогда не угадает, что это инициализация. Кроме того, с дизайном очень плохо
                                                                                          public static virtual *** &&
                                                                                          Не должны половину программы занимать служебные слова, не должны быть знаки * и & там, где они предполагаются по умолчанию.
                                                                                            +1
                                                                                            Ну, не нравится математику A(b) — может и A{b} написать. А что касается * и &. то всей Одессе они нравятся, только математик недоволен:) Не трогайте священное наследие C, которое, по словам Страуструпа же, одновременно обожают и ненавидят;)
                                                                                            А вот где математик нашел 'public static virtual'…
                                                                                              +3
                                                                                              public static virtual *** &&

                                                                                              стесняюсь спросить, а вы точно C++ учите? :)
                                                                                                +1
                                                                                                а где знаки *, & && и пр. предполагаются по умолчанию?

                                                                                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                              Самое читаемое