Комментарии 118
Перевод просто ужасен. Например, это:
но серьезно, кто я такой, чтобы переоткрыть, скажем, винтаж Бьёрна 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.
Это не похоже на отсылку к роману. Выглядит как опечатка — world. Мол, старый Бьёрн явно лучше понимал мир 84-го года, чем он сейчас.
Здесь vintage не имеет значения «винтажный или ламповый». Vintage — это дословно процесс сбора урожая винограда и изготовления вина. 1984 vintage Bjarne означает что-то вроде «Бьерн 1984-го года розлива»
Перевод просто ужасен.
Уши гуглопереводчика торчат отовсюду.
That works, but often that support comes at the cost of specialization.
Это работает, но часто эта поддержка стоит за счет специализации.
А должно быть «поддежка достигается ценой специализации».
Но мы-то помним всю правду :)Вы пропустили тэг «ирония», или действительно считаете эту шутку за реальное «интервью» Струструпа? ;)
AFAIK, вот реальное интервью.
SQL гораздо ближе к человеческому языку, чем С++
Попробуйте Ruby, вот где красота.
«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 года назад! Вас ничего не смущает?
Идём в Вики SQL first appearance 1974, первый стандарт 1986 как раз 32 года назад. Теперь можно спорить?
Вот если когда-нибудь по-настоящему взлетят Crystal и Elixir — вот будет красотища…
а для более сложных лучше подошло бы декларативное описание желаемых целей.
— Давайте построим коммунизм, удвоим ВВП, войдем в пятерку экономически развитых стран
И сколько из этих целей завершилось успешно? Вы уверены, что это хороший пример успешности декларативного программирования?
А вообще скорее наоборот — фп лучше подходит для простых задач обработки данных, маленьких кирпичиков, которые соединяются императивным раствором
Гвидо загнал сообщество в проблему 2vs3, поэтому тут тоже не все хорошо.
P.S. Ну или при его попустительстве загнали. Не знаю эту историю полностью.
А то, что кто-то ещё на нём пишет это не проблема питона, просто мало у кого поставлен процесс обновлений, вон перл выходил без поломок обратной совместимости, но куча контор не обновлялась практически никогда, с джавой примерно те же проблемы и т.д.
По моим ощущениям это сильно ударило по позициям Python в целом. Пока PHP усиленно работал над производительностью и актуализацией, а Golang надо многопоточностью, Python просто ушел в болото на несколько лет.
Ну, например, в этом году я впервые начал новый проект на Python 3. До этого вопросы обратной совместимости по библиотекам всегда останавливали.
Так сказать не получится: проект-то новый, поэтому просто посмотрели и поняли, что все есть. А до этого я работал над OpenStack, а там все исторически на 2.7 c редкими вкраплениями Ruby и Python 3.
Проблема-то ещё и в том, что работает — не трожь. Т.е. резона переписывать, например, объвязку GPDB на 2.7 просто нет пока. И таких проектов море, а следовательно инсталяционная база у Python 3 меньше и качество обратной связи ниже. По крайне мере так было где-то до 3.4-3.5. Сейчас за полгода проекта на 3.6-3.7 ничего не словили критичного.
так я и говорю что многие компании не имеют процесса миграции на новые версии т.е. проблема не в том, что не было каких-то библиотек для третьего питона, просто нет желания мигрировать, также куча проектов на доисторических версиях джавы, пхп, перла и т.д. сидят, хотя там обратную совместимость не ломали.
хотя там обратную совместимость не ломали.
Дьявол в деталях. Все же PHP 5.x и PHP 7.x это очень разные языки. Да что там говорить: даже между 5.1 и 5.6 изменили много (наконец грохнули globals, сменили ссылочную логику). Я участвовал в таком переходе как зритель. В целом не сложно, но сумарно с месяц человеко часов это съело: надо же не только изменить (что не много заняло), но протестировать, изменить поставку (а софт почти коробочный), написать документацию и т.д.
На мой взгляд действительно хорошая совместимость только у C, потом C++, потом Java, а все остальное в целом проблемно. Беда в том, что Python 3 не предлагал существенных плюшек по сравнению с Python 2. Вот зачем переходить с PHP 5 на PHP 7 всем было понятно, а Python — нет.
Потому что по скорости в вебе его обгоняет только Go lang (компилируемый:-) )
Потому что одна из самых больших комьюнити
Потому что невероятно огромный выбор хороших и не очень хороших пакетов\фреймворков
Потому что огромное количество вакансий (среди веба, только у JS больше)
Потому что 80% веба до сих пор PHP
Потому что язык жив и активно развивается
Все же PHP 5.x и PHP 7.x это очень разные языки.
А аргументация будет какая-нибудь? Всё же PHP 5.x от 7.x отличаются так же, как питон 3.4 от 3.5, наличием тайпхинтинга и пачкой других мелочей, и ничего фатального, что перевело бы PHP 7.х в разряд «очень разный язык» нет.
Вся аргументация есть в документации на php.net.
Учитывая вышеизложенные тезисы, то вся логика последующего комментария, которая отталкивается от этого замечания лишь плод вашего воображения, либо неудачное стечение обстоятельств. На практике же переход с 5.х на 7.х, если в проекте участвовали компетентные специалисты, не использующие функционал, который устарел лет на *дцать, требует ровно два телодвижения — установка 7.х-fpm и рестарт сервера.
Мы выполняем много маленьких чудес посредством проб и ошибок, чрезмерного использования грубой силы и многих испытаний, но зачастую этого недостаточно.
Оригинал:
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» хочется перевести как «и проведения огромного количества тестов».
Поправьте меня, пожалуйста, если я ошибаюсь
Тут именно "метод грубой силы", потому что речь идёт о надёжности программ и сложности их проектирования. Но судя по всему, у автора это получилось случайно, потому что "lots of testing — многих испытаний" — былинный отказ.
Я изначально понимал, что всё это сильно субъективно, поэтому мне было интересно мнение сообщества (кроме того mbait сказал, что мой вариант перевода неверен). Считайте, что это отсылка к спору по поводу использования интерсептор(интерцептор)/перехватчик, синглтон/одиночка, прокси/заместитель. Честно говоря, мне сильно претят варваризмы, но первые варианты даже в контексте мною воспринимаются четче, чем вторые.
Там все три варианта приведены как равноправные, причём «грубая сила» — как основной.
<режим ворчуна> в статье довольно много неточностей перевода (широкого круга приложений вместо широкого круга применений) и разного рода неточностей (багги), хорошо бы подтянуть знание языка перед переводом тематических текстов</режим ворчуна>
Ну не знаю как по мне проблема в инструменте. Люди они такие есть были и будут всегда. Всегда будет горстка толковых и куча аматоров. А инструмент должен если не предотвращать то не поощрять эти ошибки. С++ как бензопила без защитного чехла и предохранителя на цепочке.
Я к тому что с++ писался так буд-то вокруг одни гении и специалисты. Возможно когда-то это было так но явно не сейчас
Ну а как иначе? Если выдумывать какие-то безопасные инструменты, то вы рано или поздно упрётесь в необходимость подвигать биты туда-сюда.
Rust, конечно не имеет наследия в виде доисторического Си, но для меня этого недостаточно, тем более с++ со временем всё лучше и лучше, вон в версии от 17 года подсыпали сахарку ещё.
Само появление rust'a это следствие периода застоя в комитете с++, я сам когда знакомился с плюсами, был удивлён что вот это и есть то на чём написано всё в мире.
Не С ++, а С++!
ИМХО. С++ как один из инициаторов ООП 'эры' это беда.
Ещё студентом ощущал что c ооп что-то не так — на нем не удается красиво написать код увязав бизнес логику и ООП парадигму.
Сейчас по прошествии лет работы с разными языками это понимание только укрепилось.
Для котиков и окошек ООП отлично подходит, для бизнес логики где нет четкого наследования и нет необходимости в объектах, т.к. в основном код это данные и функции работы над данными(но не вместе) — не подходит.
а что мешает их разнести на классы, представляющие данные, и на классы, которые умеют их обрабатывать?Мне кажется, это будет противоречить духу ООП. И не очень понятно, зачем тут тогда вообще классы — со структурами и функциями все то же самое будет лучше смотреться процедурно.
И даже если для самой бизнес-логики классы и объекты оказались не очень-то нужны, то они могут пригодиться, к примеру, для тестирования и избавления от жестких зависимостей.
Т.е. вы предлагаете писать лишний код, чтобы решить проблемы которые при тестировании создает ООП, подход? Я это так понимают.
Вас удивит когда вы попробуете писать на языках с упором на минимальное количеством сэйта и чистые функции.
Все эти доп объекты "помогающие" в тестировании покажутся смешными и неудобными.
Вот и получается, что такой подход отличается от процедурного программирования по форме, но не отличается по сути: у нас те же данные, функции, а классы здесь особенно-то и не нужны. Поэтому я и говорю, что он, на мой взгляд, противоречит духу ООП.
PS: Я не великий эксперт, вполне могу ошибаться. Да и не факт, что верно понял ваше предложение.
До тех пор, пока нам не нужно их получать в разных видах, валидировать, и т.д.Как раз здесь я вас неправильно понял. Когда вы писали о «классах, представляющих данные», я думал, вы имеете в виду POD.
Разве это плохо?Вроде это более или менее известный антипаттерн. www.yegor256.com/2015/03/09/objects-end-with-er.html
Если в языке есть механизм неймспейсов, чтобы не захламлять глобальную областьПолностью согласен, что если в языке нет неймспейсов, то можно использовать классы для их замены. Но у нас же вроде C++.
Насчет Di согласен.
методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследованияИнкапсуляция, наследование, полиморфизм — это принципы ООП, которые, ИМХО, не есть сама суть ООП. А так называемый «дух», ИМХО, присущ не самому ООП, а программисту, который его использует. И если для кого то «дух» ООП — это использование наследования везде, где только можно, я советую обратиться к Саттеру и Александреску — они доходчиво объясняют, когда стоит использовать наследование, а когда рак на горе таки не свистит.
Суть ООП предельно проста: представление программы, как совокупности «линейно независимых» сущностей, скрывающих свое внутреннее состояние и доступных для взаимодействующих исключительно в соответствии со строго определенными протоколами. Такие сущности и «экспортируемые» ими протоколы в ООП и называются объектами. Как это делается средствами языка — вопрос десятый. В C++ — это класс и совокупность его публичных методов, в JS — это (как пример) сигнатура функции, возвращенной из другой функции и «закложурившей» в качестве «полей класса» экземпляры локальных переменных, в Rust — это (опять же, пример) структура + совокупность ее собственной реализации и реализуемых для нее трейтов, для C это может быть WinProc со switch-ом на десяток экранов. Варианты можно добавлять. Главное — есть инкапсулированное состояние и определение допустимых способов взаимодействия. По сложившейся традиции, если нет иерархии наследования и виртуальных методов, то такой подход называется «абстрактные типы данных», а если добавляется наследование и позднее связывание — то, почему-то, ООП.
Ну, а что касается Александреску и Сеттера, то они замечательные эксперты, но мне ближе Шон Пэрент, особенно его «Inheritance is the root cause of all evil».
Как-то так, что-то тема меня забрала, мог бы еще долго распространятся и аргументировать, но затыкаюсь ибо и так слишком длинно.
В моем понимании ООП — это то, что написано на Вики, только без последней фразы про иерархию наследования. Просто объединяем данные и методы их обработки в классы — вот и ООП. Если у меня четко одно поведение — не будет полиморфизма, ничего страшного. Если у меня простая структура, содержащая данные, к которым много где нужен прямой доступ — долой инкапсуляцию. А наследование всегда пытаюсь использовать по минимуму, ибо, несмотря на его удобство в правильных ситуациях, в остальных оно всегда вызывает проблемы. Принципы принципами, но пусть все же ООП работает на меня, а не наоборот. Это лишь мое понимание, которое, очевидно, не совсем совпадает с мнением большинства, но пока что как то так.
Единственное же, что я хотел сказать оскорбившим Вас комментарием — это то, что не стоит обвинять ООП в своих проблемах, а С++ — в проблемах ООП, ибо ООП — не единственная парадигма поддерживаемая в С++, а решение проблем — это не задача ООП.
Еще раз повторю основную свою мысль: ООП это это метод проектирования и реализации, позволяющий лучше справиться с управлением состоянием программы путем разделения этого состояния на меньшие части и ограничения на способы взаимодействия этих частей. Нет нетривиального и необходимого состояния — ООП не особо нужно. Например, когда программа есть функция, перемалывающая одни данные в другие — много «OOP inside» скорее вредит.
Есть более узкое понимание ООП: инкапсуляция, наследование, полиморфизм. Такое понимание «взлетело», потому что очень упростило программирование оконного интерфейса, вот его и стали всюду пихать, где надо и не надо. А классы тут просто деталь реализации. Сам Страуструп, кстати, про классы писал (цитирую по памяти): "… классы — это модули, но такие, что можно одновременно создавать много экземпляров ...".
class Cpp {
int a;
int b;
public:
void f() { ... }
};
эквивалентен:
struct PureC {
int a;
int b;
};
void f(struct PureC * this) {...}
Когда-то, во времена CFront, это так и было, я еще помню) Есть концептуальные моменты, например, конструкторы и деструкторы (как средства поддержания инвариантов и в меньшей степени управления жизненным циклом), но основная разница в удобстве программирования, а не в сути. А «дух ООП» пускай носится над бездной, в программировании ему мало места.
Я подумал, что, возможно, ситуация у комментатора выше похожа на ту, что была в одном из моих проектов, где не получалось нормально скрыть поля объектов (для любого чиха приходилось использовать много полей разных объектов), а функции работали с несколькими равноправными объектами и не очень-то собирались в логически связанные группы. И в этом случае, вместо того, чтобы писать
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: сейчас я уже как-то не очень уверен, что изначально автор имел в виду именно это, но сначала я понял его именно так.
А можете прояснить свою мысль более развернуто? И предложить парадигму, более подходящую для вашей бизнес-логики?
Я не хотел тут развиваться холивары по этому альтернативы специально не писал. А сделал акцент на недостатках ООП, которые на мой взгляд ставят эту парадигму под сомнения.
наследование — лишь один из инструментов, и не обязательно его везде пихать, если для конкретной задачи оно не нужно
В ооп все пропитано наследованием. Сама парадигма делает упор на то чтобы пытаться искать иерархию типов и пытается дать "удобный" инструмент для работы с ней. На мой взгляд.
Разумеется можно на это забить. Но тогда встает вопрос, если вы игнорирует ключевые части некоторой парадигмы — зачем она вам?
а что мешает их разнести на классы, представляющие данные, и на классы, которые умеют их обрабатывать?
Тогда мне так же, непонятно зачем нужен ООП. Если вы игнорируете идею объекта — как вещи в себе.
Какой нибудь JSON или HTTP запрос в своей сути является сочетанием 2-х коллекций ассоциативного массива и списка. Для манипуляции этими двумя типами (ассоциативный массив и список) есть отличные функции в любой стандартной библиотеке, для чего нужна обертка в виде класса?
что для чисто-функциональных языков нужно неслабо вывихнуть мозг тем, кто с ними будет работать.
Думаю что в вашем случае представление о FP извращено представителями вида Haskell, языки поддерживающие основные концепции FP не обязательно должны иметь сложную систему типов. Erlang, Clojure простые, но реализуют самые важные, С ПРАКТИЧЕСКОЙ, точки зрения концепции из FP.
Тогда мне так же, непонятно зачем нужен ООП. Если вы игнорируете идею объекта — как вещи в себе.
Обычно такие вопросы возникают у тех кто не смирился с мыслью, что объект в ООП не равен объекту реального мира. Это есть абстракция. А все абстракции кастрированы по определению — они реальность показывают далеко не со всех сторон. Об этом прямо говорит Single Responsability Principle — объект отвечает за что то одно и от этого зависит какой он — инкапсулирует что либо или наследуется или просто делает что то. За что должен отвечать класс/объект? — а вот это уже вопрос проектирования. А проектирование архитектуры программного кода как и любое проектирование есть не только инженерия, но и в не малой степени искусство. Поэтому нельзя просто понимать или не понимать ООП, принять его или не принять — это есть подход. Возможны другие подходы, но только те что позволяют проектировать. Иначе с их помощью не построить сложную систему. ФП в целом проектировать позволяет, но при этом свойства ФП и ООП различаются и выходит что и свойства спроектированных систем различны. Т е там где буксует ФП — отлично растет ООП и наоборот.
Обычно такие вопросы возникают у тех кто не смирился с мыслью, что объект в ООП не равен объекту реального мира.
Причем тут реальный мир, я писал что-то о реальном мире? А вот во всех книгах про ООП обычно и моделируются объекты из реального мира — животные и иерархия в компании и подобное.
В реальности 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
(пустая строка)
Которую в любом ЯП можно представить как ассоциативный массив.
Вот к чему приводит попытка все сделать в лучших традиция ООП, минимальное кол-во полезного выхода на объем кода.
А вот во всех книгах про ООП обычно и моделируются объекты из реального мира — животные и иерархия в компании и подобное.
Я бы не обобщал это на прямо все книги. Не вы не я не читали всех книг по ооп.
Можно привести примеры и теоретические выкладки где ФП буксует а ООП нет и наоборот. Без них вы как бы просто пустословите, ИМХО.
Давайте не будем бросаться колкостями если вы реально хотите диалога а не драки, хорошо? Как вам пример с оконными интерфейсами?
В реальности 99% кода это не реальный мир — кэш, HTTP, ответ от БД, обход коллекции, и т.д. На них как раз ооп и не ложится в отличии от вымышленных примеров.
Впервые слышу что на кэш или http ооп «не ложиться»
Которую в любом ЯП можно представить как ассоциативный массив
Вот как раз этого ООП старается избежать. Это называется «выхолащивание» абстракций. Т е в любой момент можно добавить/удалить из этого массива поле что приведет к неработоспособности кода, но с первого взгляда эта проблема будет скрыта и не то что компилятор не определит, но и программисту придется отслеживать все места в коде где идут операции с этими ассоциативными списками. Тогда как в ооп это либо вообще не скомпилируется, либо можно будет легко найти где идут операции с этим полем. Если уж хотите корректное сравнение с ФП тогда в пример нужно приводить записи(record) ну или алгебраические типы. Но записи мало чем отличаются от объектов с оторванными методами и в принципе их легко имитировать на ООП. Алгебраические типы конечно уникальны для ФП, но и они имеют свою нишу. Если уж на то пошло, то самое сильное отличие ФП от ООП — это использование ридонли-структур. Именно из этого вытекает большинство плюсов ФП и одновременно его же минусов.
Правда, и туда пробрались глобальный функции… )
Для котиков и окошек ООП отлично подходит, для бизнес логики где нет четкого наследования и нет необходимости в объектах
А почему нет необходимости в объектах? Объекты обладают свойствами: состояние, идентичность, поведение. Я думаю бизнес-объекты этим тоже обладают.
Инкапсуляуция обеспечивает абстракцию от деталей состояния. В ОО языке можно написать Сотрудник.Фамилия и эта строчка вернет фамилию в первой версии из поля, во второй слазит в отдельную табличку с историей фамилий и вернет последнюю.
Что такое "четкое наследование" и почему в бизнес логике его нет?
Из Мейера помнится, что при многопоточности в C++ f(g(x),y(z));
— это не то же самое, что auto a = g(x); auto b = y(z); f(a,b);
. А так язык неплохой, и Кьеркегор, как оказалось, в деле...
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, или только будет должен…
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
По-моему, здесь говорится о законченных выражениях ("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.
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 говорит о другом. Возможно, я где-то запутался.
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.
Ну тут дело вроде даже не в многопоточности, а в том, что в C++ не гарантируется порядок вычисления аргументов функции и даже то, что они будут вычислены последовательно. Это, например, приводит к опасным и трудно-находимым багам. Например,
f(unique_ptr<int>(new int(100)), g())
может привести к утечке памяти, если g()
выбрасывает исключение.
Разработчики программного обеспечения нейтрализуют поразительную производительность современного компьютерного оборудования, добавляя избыточные (программные) абстракции слой за слоем.
А ведь если тренды пойдут так, как сейчас — эти слова, которые надо выбить в граните, могут, увы, стать "Говорил я вам — не прислушались". Достаточно взглянуть, скажем, на Atom (который редактор)…
public static virtual *** &&
Не должны половину программы занимать служебные слова, не должны быть знаки * и & там, где они предполагаются по умолчанию.
А вот где математик нашел 'public static virtual'…
Бьёрн Страуструп: Проблема с программированием