- PVSM.RU - https://www.pvsm.ru -

У WG21 есть строгий график (см. P1000 [1]) выпуска стандарта каждые три года. И никаких задержек.
В течение каждого цикла мы регулярно получаем вопросы «ну почему так строго?», особенно от новых участников комитета, которые не знакомы с его историей и причинами текущего положения вещей. И во время предварительной телеконференции с администрацией Кёльна несколько человек порекомендовали описать, почему мы так делаем и как принималось решение о принятии этого графика.
Всё это я расписал в виде вопросов и ответов для следующего черновика Р1000, и разослал копию участникам комитета, направлявшимся в Кёльн. Этот материал будет опубликован в следующей публичной версии Р1000, её мы разошлём через несколько недель начиная с текущего момента.
Однако и черновик FAQ может быть интересен публике, поэтому предлагаю вашему вниманию его копию. Надеюсь, он будет для вас по большей части полезен, в чём-то просветит, и, возможно, даже немного развлечёт.
Конечно да, и нет.
Мы движемся в заданном направлении с выбранной скоростью: исправление багов запланировано на этот последний год, поэтому в графике в раннем С++ «19» (Kona) установлен крайний срок прекращения добавления функциональности (feature freeze) в С++ «20», чтобы у нас был год на исправление багов, включая работу с комментариями из разных стран этим летом. До начала 2020-го (встречи в Кёльне, Белфасте и Праге) мы должны дать обратную связь и применить любые другие решения проблем, а также исправления багов.
Конечно да, и нет.
Подождите, когда пройдёт ещё пара встреч (после Праги), и С++23 будет открыт для бизнеса, и в первую очередь проголосуем за добавление <название_фичи> в рабочий черновик С++23. Так мы поступили с концептами: они не были готовы к переходу из TS прямо в С++17. Поэтому на первой встрече по С++20 (в Торонто) проголосовали за перенос основной функциональности концептов в черновик С++20, что дало много времени на совершенствование и доработку остальной противоречивой части TS (не-«шаблонный» синтаксис), которая была внедрена в следующем году (Сан-Диего). Теперь вся функциональность готова.
Потому что в случае с релизом С++ IS это один из двух основных вариантов управления проектом, и опыт показывает, что этот вариант лучше второго.
Рад, что вы спросили.
В случае с релизом есть два основных варианта: выбрать фичи или срок релиза, и когда выбираешь одно, то теряешь контроль над определением другого. Нельзя одновременно контролировать и то, и другое. Вкратце:
| Если мы будем контролировать это | Мы перестанем контролировать это | Мы можем работать над «большими» многолетними фичами? | Когда мы добавляем фичи в рабочий черновик IS? | Что мы делаем, если обнаруживаем проблемы с добавленной фичей? |
|---|---|---|---|---|
| «Что»: фичи, которые мы отгружаем | «Когда»: срок релиза. | Да, в документах с предложениями и рабочем черновике IS. | Обычно раньше, чтобы провести больше интеграционных тестов → снижается средняя стабильность рабочего черновика. | Задерживаем выпуск стандарта. |
| «Когда»: срок релиза | «Что»: фичи, которые мы отгружаем | Да, в документах с предложениями и «ветках фич» в TS. | Обычно позже, когда фича лучше проработана → повышается средняя стабильность рабочего черновика. | Убираем фичу, позже можем добавить её снова, если она готова к моменту отправления следующего «поезда» IS. |
Поясняю:
(1) «Что»: выбираем фичи и отгружаем по мере готовности, не нужно выбирать время релиза. Если выясняется, что нужно больше времени на доработку фичи из черновика стандарта, то всему миру придётся тебя ждать. Ты работаешь над большими фичами, которые требуют нескольких лет разработки, а потом пытаешься вообще перестать работать над новыми фичами, пока стабилизируешь релиз.
Так было с C++98 (его ждали примерно в 1994-м, Бьёрн сказал, что релиз не выйдет к тому времени, это будет провалом) с C++11 (его назвали 0x, потому что x ждали к 2007-му). Это подход «оставляем пациента не зашитым» на неопределённый срок, который привёл к задержке интеграционного тестирования и релиза. А это, в свою очередь, привело к большой неуверенности на рынке относительно сроков выхода следующего стандарта, да и выйдет ли он вообще (да, не только участники разработки, но даже некоторые члены комитета серьёзно сомневались в 1996-м и 2009-м, появятся ли вообще соответствующие релизы). В течение нескольких лет большинство компиляторов не соответствовали стандарту, потому что никто не знал, сколько несовместимых изменений выкатит комитет в новом релизе, или когда его вообще ждать? Это привело к большому разнообразию и фрагментации поддержки С++ в компиляторах, доступных для сообщества.
Почему мы так поступили, мы что, идиоты? Не совсем, просто были неопытны и… скажем так, «оптимистичны». Это была дорога, вымощенная лучшими намерениями. В 1994-1996-м и в 2007-2009-м мы действительно верили, что сейчас передвинем ещё на одну-две-три встречи, и всё сделаем, и каждый раз переносили на сроки до четырёх лет. И теперь на своём опыте убедились, что не может быть переноса на год или два.
К счастью, всё изменилось благодаря варианту (2).
(2) «Когда»: выбираем срок релиза и отгружаем те фичи, что будут готовы, не нужно выбирать набор фич. Если выясняется, что нужно больше времени на доработку фичи из черновика стандарта, мы её выбрасываем и отгружаем то, что готово. Можно продолжать работать над большими фичами, на создание которых уходит времени как на несколько релизов, но делать это в сторонних «ветках», добавляя их в мастер-ветку IS по мере готовности. И ты постоянно работаешь над фичами, потому что их разработка полностью отделена от текущего релиза (нет большой точки соединения).
Этого подхода мы придерживаемся с 2012-го и не хотим от него отказываться. Это подход «регулярно зашиваем пациента», который приводит к ожиданию более высокого качества благодаря принудительным регулярным интеграциям и отказу от добавления работы в черновик IS, пока она не достигнет определённого уровня стабильности, обычно в рамках ветки фичи. Также это создаёт предсказуемый цикл релиза, на который может опираться рынок. За эти годы авторы компиляторов стали всё раньше и раньше после очередного релиза выпускать соответствующие стандарту версии своих продуктов, чего раньше никогда не было. А в 2020-м мы ожидаем выхода полностью соответствующих стандарту реализаций в один год с выходом стандарта, чего тоже никогда раньше не было. Это только во благо для всего рынка — разработчиков, пользователей, преподавателей.
И ещё обратите внимание, что с тех пор, как мы начали придерживаться этого подхода, мы стали делать больше (если оценивать по большим, средним и маленьким фичам) и с более высоким качеством (если оценивать по строгому уменьшению количества отчётов о багах и комментариев к черновикам каждого стандарта). Хотя отгружаем то, что успели подготовить (а если что-то не успели, то это не отгружаем).
Очень серьёзно относимся, и нет.
У нас есть статистика: в 2016-м в Джексонвилле, когда мы окончательно определялись с фичами для С++17, Бьёрн Страуструп выступил на пленарном заседании с предложением включить концепты в С++17. Когда консенсуса не достигли, Страуструпа прямо спросили, хочет ли он задержать релиз С++17 на год, чтобы включить в него концепты. Бьёрн без колебаний и увёрток ответил «нет», и добавил, что С++17 без концептов важнее, чем С++18 или С++19 с концептами, хотя Страуструп работал над ними около 15 лет. Выбор стоял такой: (2) выпускаем С++17 без концептов, а затем С++20 с концептами (что мы и сделали), или (1) переименовываем С++17 в С++20, что изоморфно (2) за исключением пропуска С++17 и отказа от выпуска того, что уже было готово для С++17.
Нет, потому что получится (1).
Фред Брукс в The Mythical Man-Month популярно объяснил про «мифический маленький перенос» и пришёл к заключению: «Не допускайте никаких маленьких переносов [2]».
Представьте, что мы перенесли С++20. Нам пришлось бы вернуться от (2) к (1), вне зависимости от того, как сильно мы стараемся избежать этого, и при этом не получили бы никаких выгод. Если бы мы решили отложить С++20, чтобы отполировать его, то мы задержали бы стандарт минимум на два года. Не бывает таких понятий, как перенос одной или трёх встреч, потому что за это время другие продолжат (справедливо) говорить: «ну, моей фиче нужно всего ещё одну встречу, мы же всё равно перенесли, давайте ещё одну перенесём». И если мы переносим как минимум на два года, то это означает, что С++20 становится С++22, а вероятнее всего С++23… но мы уже собираемся отгружать С++23! — То есть в любом случае мы будем отгружать С++23, и разница лишь в том, что мы не переносим С++20 с большим объёмом проделанной работы, готовой к релизу, и не заставляем весь мир ждать ещё три года. Задержка не пойдёт на пользу этим фичам, большинству из них или всем вместе.
Поэтому предложение равносильно «давайте превратим С++20 в С++22 или С++23», и простой ответ на него: «да, у нас будет и С++23, но в дополнение к С++20, а не вместо него». Задержка С++20 означает пропуск С++20 вместо выпуска хорошего, стабильного, готового продукта, и никакой пользы от этого не будет.
Не вопрос! Мы её можем просто выпилить.
В этом случае кому-то нужно будет написать в EWG или LEWG (в зависимости от ситуации) письмо с описанием ситуации, и предложить удалить фичу из рабочего черновика IS. Эти группы рассмотрят обращение, и если они решат, что фича сломана (и пленум с ними согласится), то фичу отложат до следующего релиза С++. Мы уже поступали так с концептами С++0х.
Но в случае с (1) мы перенесём не только эту фичу, а весь набор фич из С++20 в С++23! Это был бы… перебор.
Нет. Сначала мы так говорили, пока не поняли, что (2) всего лишь означает, что не нужно выбирать набор фич даже с точки зрения «основного/второстепенного» релиза.
Подход (2) означает лишь «отгружаем то, что готово». Релизы получаются:
C++14 и C++17 были относительно маленькими, потому что много усилий по стандартизации тратилось на долгоиграющие фичи, описанные в предложениях к внедрению (например, контракты) и «ветки фич» в TS (например, концепты).
Да. В C++20 много крупных фич. Три из крупнейших начинаются на «ко» (концепты, контракты, корутины), так что мы могли бы назвать его co_cpp20. Или co_dependent.
Нет, см. выше «раз на раз не приходится».
C++20 большой не потому, что за три года мы сделали больше, а потому что много долгих разработок (включая как минимум две, над которыми в текущем виде мы работали с 2012-го в виде P-предложений и TS-«веток») дошли до стадии готовности и их решили включить в черновик IS одного и того же релиза.
Практически всегда основные фичи разрабатываются по много лет. Главная разница между подходом (1) для С++98 и С++11 и подходом (2) заключается в том, что в С++98 и С++11 задерживали выпуск до готовности всех этих фич, а теперь мы отгружаем большие по мере готовности, и попутно с ними релизим многое другое.
С++20 прошёл через такой же трёхлетний цикл, как С++14 и С++17. Мы не сделали за последние три года больше, чем за два предыдущих цикла, просто допилили больше основных фич. Если бы какая-то из них не была готова, то мы бы её выкинули и доделывали уже для С++23. Если так произойдёт, мы сообщим об этом в предложении по внедрению и объясним причины.
С++14+17+20 составили наш третий девятилетний цикл (2011-2020) после С++98 (1989-1998) и С++11 (2002-2011). Но поскольку мы придерживались подхода (2), то также выпустили наработки, которые были готовы к окончанию трёхлетнего и шестилетнего циклов.
Конечно лучше.
Но если мы говорим о причинах задержки выхода стандарта С++, то этот вопрос подразумевает два ложных предположения:
Поясняю:
Наконец, не забывайте и о проблеме взаимодействия фич. Мы не только выпускаем их тогда, когда готовы, после этого нам ещё нужно время на поиск проблем взаимодействия между фичами и на добавление поддержки таких взаимодействий, о которых мы просто не можем узнать до того, как новые фичи станут широко использовать. И не имеет значения, насколько мы задержим релиз стандарта, всегда будут взаимодействия, которые мы сможем исследовать лишь гораздо позже. Управлять таким риском нужно с помощью гибкого проектирования, обеспечивающего совместимость фич, а не ждать избавления от всех рисков.
Да.
Если мы видим, что фича не готова, то мы должны её удалить из релиза.
Если мы видим, что фича может быть лучше, и знаем, что изменение может оказаться обратно-совместимым, то это не причина отказываться сейчас от её релиза. Её можно выпустить как расширение в следующем С++.
Мы намеренно выпускаем фичи, которые планируем улучшать в будущем, пока уверены в том, что можем соблюсти обратную совместимость.
Да. Мы стараемся.
Но мы не стараемся избежать всех рисков. Также существует риск и (возможная) цена отказа от выпуска того, что нам кажется готовым. И чаще всего мы оказываемся правы.
Да.
Согласно объективным метрикам, объёму комментариев из разных стран и отчётов об ошибках, С++14 и С++17 были нашими самыми стабильными релизами, и по этим метрикам они в 3-4 раза превзошли С++98 и С++11. А причина именно в регулярности релизов, в размещении больших фич сначала в TS-ветки (включая полные описания их интеграции с основным стандартом) и в их последующем вливании, когда мы убеждаемся в готовности.
С 2012-го основной стандарт всегда поддерживается в состоянии почти-готов-к-отгрузке (так что даже рабочие черновики такого же высокого качества, как релизы стандартов С++98 и С++11). Такого никогда не было ранее, когда мы долгое время держали пациента не зашитым, с длинными списками проблем и разложенными вокруг органами, которые мы собираемся скоро засунуть обратно. Теперь мы знаем, что можем выдерживать график с высоким качеством работы, потому что всегда остаёмся в состоянии близкой готовности к релизу. Если бы хотели, то могли бы выпустить CD хоть сейчас, без встречи в Кёльне, и всё равно качество было бы гораздо выше, чем когда-либо у CD C++98 или С++11 (по правде, и их опубликованных стандартов). А учитывая, что С++98 и С++11 были успешны, то понимание, что сейчас качество ещё выше, означает, что мы на верном пути.
Да: 1989-1998 и 2002-2011.
Повторюсь, я считаю, что правильно сравнивать С++14+17+20 как единое целое: это наш девятилетний цикл, но поскольку мы придерживались подхода (2), мы также выпустили и те наработки, которые были готовы к завершению трёхлетнего и шестилетнего циклов.
Конечно! Пока в нём нет слов вроде «должен включать в себя эти фичи», потому что тогда это будет подход (1).
Стремиться к определенному набору фич и отдавать одним из них приоритет — это нормально, но тогда это вопрос приоритетности. Пока что мы будем брать только то, что готово, но мы можем выбирать, над чем работать в первую очередь, чтобы подготовить как можно скорее.
Автор: AloneCoder
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/324457
Ссылки в тексте:
[1] P1000: https://wg21.link/p1000
[2] Не допускайте никаких маленьких переносов: https://www.cs.huji.ac.il/labs/parallel/Docs/C++/DesignPatterns/smallSlips.html
[3] P0592: https://wg21.link/p0592
[4] Источник: https://habr.com/ru/post/460665/?utm_campaign=460665&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.