avva: (Default)
[personal profile] avva
(будет интересно программистам на C++ и вряд ли кому еще)

Автор заметки std::visit is everything wrong with modern C++ несколько преувеличивает масштабы проблемы, но проблема тем не менее существует и реальна. Он пишет про новый тип std::variant в C++17, который позволяет сохранять в одном значении один из нескольких разных типов. В старом добром C такое делали втыканием внутрь структуры одновременно union и переменной, означающей, какой из членов union реально присутствует. std::variant позволяет добиться примерно того же, но с статической проверкой корректности. При том, что проверить наличие конкретного варианта внутри std::variant легко и понятно с помощью std::get, хочется также иметь возможность сделать аналог switch, выполняющий разные действия для разных вложенных вариантов - так, чтобы компилятор проверял, что все варианты указаны. И вот это, пишет автор, комитет по разработке C++17 сделать убедительно не смог - либо надо писать громоздкий класс с переопределением оператора вызова (), либо вообще заниматься какой-то прикладной магией типа рекурсивных темплейтов.

С одной стороны, он прав. В том виде, в каком std::visit сейчас существует, им неудобно пользоваться, и это упущение со стороны комитета (которое, возможно, будет исправлено). Но он неправ, когда пишет, что эта ужасная сложность самого языка показывает, что C++ двигается в неправильном направлении... это поезд, который давно ушел. C++ был слишком сложным языком для простых смертных в 2014-м году. До этого он был слишком сложным языком для простых смертных в 2011-м году, а до этого он был слишком сложным языком для простых смертных в 1998-м году, и сказать по правде, он был слишком сложным языком для простых смертных где-то так в 1990-м году уж точно.

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

А именно, формула такая: простой интуитивный API, предсказуемое и прозрачное использование памяти и копирование объектов; а если для воплощения всего этого нужна продвинутая магия, пользователю не нужно о ней знать. Магия остается спрятанной в исходниках библиотеки.

Это было верно в отношении std::string, std::vector и std::pair еще в 90-х. Для того, чтобы их написать, включая удобные методы их использования, нужно было знать много трюков и хитрых углов стандарта. Для того, чтобы использовать, нужно было просто интуитивно представлять строку как объект, сам хранящий память и расширяющий ее по мере надобности, вектор как очевидный аналог массива объектов итд.

Это остается верным в отношении std::unique_ptr и std::optional сегодня. Если читать их исходники, то можно ошибиться и на секунду подумать, что забрел в какой-то проект на Скале. Зато использование вполне интуитивно.

std::variant немного выбивается из этого паттерна, особенно в том, что касается проблемы "посещения всех альтернатив", и близок скорее к философии Boost - откуда он и взят почти без изменений, собственно. То, что C++{11,14,17} в целом сопротивлялись Boost-ификации языка и выносу продвинутой магии на поверхность, там, где программистам нужно постоянно с ней сталкиваться - одна из причин успеха современного C++.

Не верите мне? Спросите Джона Кармака:


Date: 2017-09-16 05:32 pm (UTC)
From: (Anonymous)
Да. Надо сначала формулировать, а затем шпицрутенами поддерживать дисциплину программирования. А когда надо, чтоб Curiosity долетела и села, переходить на Си.

Date: 2017-09-16 05:55 pm (UTC)
From: [identity profile] spamsink.livejournal.com
и сказать по правде, он был слишком сложным языком для простых смертных где-то так в 1990-м году уж точно

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

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

Date: 2017-09-16 07:06 pm (UTC)
livelight: (hot)
From: [personal profile] livelight
Вы забыли посчитать язык препроцессора :)

Date: 2017-09-16 07:19 pm (UTC)
From: [identity profile] spamsink.livejournal.com
Действительно, теперь надо и его считать, раз уже и он объединён общим парсером.

Date: 2017-09-16 05:58 pm (UTC)
From: (Anonymous)
Делов-то. Кто-нибудь напишет правильный overload, выложит на гитхаб, и все станут пользоваться.

Date: 2017-09-16 07:05 pm (UTC)
livelight: (lightning)
From: [personal profile] livelight
Имхо, насчёт слишкомсложности в 1998 году вы преувеличиваете - если "простым смертным" считать того, кто как-то освоил язык просто-Си. А если "простым смертным" считать пррлетария, не знающего, с какого бока подходить к просто-Си, и не способного его освоить без кровавых мозолей на мозге, то для него и просто-Си имени К & Р слишком сложен, по определению.

Date: 2017-09-16 07:21 pm (UTC)
From: [identity profile] spamsink.livejournal.com
Насколько я помню, виртуальное множественное наследование некоторым освоившим просто Си казалось слишком сложным с самого начала.

Date: 2017-09-16 08:10 pm (UTC)
From: (Anonymous)
Оно слишком хрупкое. Его нельзя делегировать, например.

captcha: avenida heritage ;)

Date: 2017-09-17 06:18 am (UTC)
From: [identity profile] mtyukanov.livejournal.com
Оно было слишком ненужным, пока не нашлось применение в виде интерфейсов. Его использование до того практически всегда означало плохой дизайн. Из-за ненужности и сложность -- запоминать то, что применяешь раз в несколько лет... Лонгджампы сишные в сегментных моделях тоже были непросты, но ими пользовались постоянно.

Date: 2017-09-16 07:53 pm (UTC)
From: [identity profile] fima.livejournal.com
Я вот использую std::variant и никаких проблем с написанием визиторов не испытываю. Гораздо больше раздражает невозможность в дебаггере, по крайней мере, в lldb, посмотреть какой же вариант сейчас сидит в переменной. Но это проблема дебаггера, надеюсь, рано или поздно это нормализуется.

Date: 2017-09-16 08:08 pm (UTC)
From: (Anonymous)
gdb прекрасно показывает

Date: 2017-09-16 08:06 pm (UTC)
From: (Anonymous)
>он был слишком сложным языком для простых смертных где-то так в 1990-м году уж точно.

Он был слишком простой в 1990. Недостаточно поддержанным.

Date: 2017-09-17 08:34 am (UTC)
From: [identity profile] vfork.livejournal.com
QVariant решает эти вопросы почти идеально. А поскольку он не наследует от QObject, то этот подход может быть использован и вне Qt

Date: 2017-09-17 09:32 am (UTC)
migmit: (Default)
From: [personal profile] migmit (from livejournal.com)
С плюсами у меня примерно как с эрэфией: если и подумаешь иногда «а может, можно будет и вернуться как-нибудь?», то достаточно прочитать какую-нибудь новость из этого мира, и дурь проходит.

Брррр

Date: 2017-09-17 02:31 pm (UTC)
From: (Anonymous)
си++ избыточно сложен, отвратителен и нелеп ибо был зачат в суете, молодым глупым программером, только и думавшим как бы в него побольше фич завернуть. Синтаксис поганый. Множественное наследование уродливо и запутано. Модификаторы доступа конечно еще больше огня поддают, на пару с генериками. Референсы, френдшип и консты как-то сделаны по-дурацки - намерение благое, но исполнение дурное. Чтобы реализовать тривиальную для жавы делегацию, надо целый концерт с бубном устраивать.

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

Date: 2017-09-17 02:59 pm (UTC)
From: [identity profile] daria klukin (from livejournal.com)
Когда о проблемах с++ говорят на примерах подобно этому это похоже на критику русского алфавита неспособного правильно передать звук другого языка.

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

Date: 2017-09-18 05:48 am (UTC)
From: [identity profile] gul-kiev.livejournal.com
Мне кажется, что программисту полезно понимать, что и как происходит "под капотом". Это позволит обходить грабли и выбирать более эффективные решения. "Оно работает на какой-то магии" - это подход гуманитария, а программисты - инженеры.

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

Нереально же

Date: 2017-09-18 06:07 am (UTC)
From: (Anonymous)
В проектах сложнее чем хелловорлд хотя бы на 3 порядка приходится использовать такое количество библиотек, что отдельному программеру просто невозможно знать детали реализации каждой. Приходится именно полагаться на порядочность и компетентность незнакомых разработчиков либо изобретать велосипеды. Конечно базу нужно понимать - например, что каждый новый тред приносит с собой ненулевой размер стека, что переключение контекстов не происходит бесплатно и тому подобное. Но все тонкости? Увольте.

Date: 2017-09-19 12:58 pm (UTC)
livelight: (lightning)
From: [personal profile] livelight
> всякие библиотеки и фреймворки работают в соответствии с документацией

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

Date: 2017-09-18 03:14 pm (UTC)
From: [identity profile] luarvique.livejournal.com
"C++ to C is what lung cancer is to lungs."

Date: 2017-09-23 07:50 am (UTC)
From: [identity profile] loyso-b.livejournal.com
Эх - типичные проблемы general purpose languages. Как всем быть счастливыми с единственным компромиссным API на всех.

June 2025

S M T W T F S
123 4 5 6 7
8 910 11 12 13 14
15 16 17 1819 20 21
22 23 24 25 26 27 28
29 30     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 3rd, 2025 03:53 pm
Powered by Dreamwidth Studios