Как стать автором
Обновить
3
0

Разработчик

Отправить сообщение

Подскажите пожалуйста, а есть где-то в природе up-to-date собрание текущих пропозалов по этой теме и обсуждений по ним? Особенно хотелось бы почитать обсуждения. Потому что мне известны только оригинальный пропозал с симметричным UFCS (за авторством, кажется, Страуструпа) и более простой асимметричный.

Cinnamon всё? В 17м-18м он отлично работал на Mint'е.

Вы можете спросить у появившихся тут падших в прошлых битвах со мною.

Ну и эго у вас… Вам, видимо, не приходило в голову, что людей просто утомляет пытаться отвечать на поток взаимоисключающих параграфов вроде


то что я называю C++ не имеет никакого отношения к C++

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

С моей скромной т.з. стоило тогда уж озаботиться нормальными extension methods. Это бы решило и кейз deducing this, и столь желаемый многими (мной тоже, не скрою) UFCS.

Вот Царь все-таки спорит, применяя первый тип спора, а отдельные поклонники раста — исключительно второй.

Не берусь утверждать про Царя, но конкретно ncwca имеет свойство начинать громогласно орать про манипуляции, как только ему указываешь на его неправоту. Подобное поведение и крайне похожий стиль были замечены в аналогичных статьях в конце 2019го.

Нет. И да, они не отказались.

Они отказались. Паника спокойно переключается в режим abort.


Потому как притащенное из C++-раи без них не работает. В расте есть C++-исключения.

А вот здесь ошибаетесь вы. RAII ортогонально исключениям и прекрасно живёт без них. Можете посмотреть на тот же Qt, не дружащий с исключениями и использующий RAII в хвост и в гриву.


Отказ там произошёл по той причине, то это сложно. А далее уже каждый расскажет, что выбор у него был.

Да, это сложно. Для вас это сюрприз? Исключения требуют того самого волшебного хранилища для своих данных. Требуют дополнительных секций и лэндинг падов в коде функций для корректной раскрутки стека. И всё это должно присутствовать в т.ч. в стороннем коде, через который эти исключения могут пролететь. Открытость набора типов приводит к обязательности RTTI, который раздувает бинарники и тоже далеко не всем нравится.


Это не проблема. Эту проблему придумали вы.

То-то я вижу в разных библиотеках коды возврата из функций, out-параметры (ау, std::filesystem), специальные методы в типах под код ошибки (ау, std::basic_ios), глобальные переменные с теми же кодами ошибки (ау, std::errno), глобальные и per-function коллбэки, получающие информацию об ошибке (stdlib, на удивление, не отметилась) и много чего ещё.


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

Смысл Either и подобных как раз в возможности однозначно вернуть либо результат, либо ошибку. Без возможности вытащить вторую половину.


Здесь происходит попытка подмены контекста. Я говорил про раишные векторы и прочее, а теперь мне рассказывают про какие-то "векторы".

Для raii исключения являются единственным способом обработки ошибок. Именно поэтому в расте есть исключения и именно поэтому никакие ошибки там без исключений не обрабатываются.

Вектор всегда вектор, написан он с учётом RAII или нет. Про ортогональность RAII и исключений ответил выше.


box/vector — любые операции. Что угодно раишное.

Т.е. пруфов таки не будет. Голословное утверждение, так и запишем.


Опять манипуляции. Происходит попытка подмены тезисы. Я нигде не говорил что dyn box это про try.

Происходит попытка показать, что я там не знаю что такое try и мне тут рассказывают очевидные вещи. Очевидно, что это враньё и доказывается это очнеь просто:

Какой-то вы нервный.


? в язык никогда не затащат, надеюсь. Это не более чем костыль. В языке нет expr, которые влияют на поток управления.
? — это костыль, чтобы try не выглядел как страшно. Это синоним в данном случае. Из "влияют на поток управления" следует и if и return, потому как они явлются управляющими конструкция.

Вы сначала говорите об expressions, а потом резко перескакиваете на statements. Кто теперь занимается подменой? Для других читателей оставлю ссылку, о чём я говорил: https://en.cppreference.com/w/cpp/language/throw. Озаглавлено throw expression. Т.е. throw является выражением, и при этом влияет на поток управления. Для сравнения, return является statement. https://en.cppreference.com/w/cpp/language/return


Далее ещё одна манипуляция направленая на тех, кто мало знаком с темой и на последоватей раста, которые будут безусловно плюсовать любые базовые лозунги. Для первых я посню, со вторым разговаривать бессмысленно.

Вы промахнулись, мой основной язык С++.


У нас есть две библиотеки, каждая из которых имеет свой enum err, пусть это будет erra|errb. Далее мы пишем функцию, внутри которой мы получаем return erra; и return errb; одновременно.

Врасте нет выовда типов для возврата,

Это утверждение не относится к теме, однако отвечу: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c4792aaa4e85980bdb40e70298aee9a3
Для parse тип возвращаемого значения вполне себе выводится.


а даже если бы и был — это не поможет. Мы никак не можем два разных енума свести к одному типу. Всё, мы не можем ничего с этим делать. Раст здесь заканчивается.

Мы можем спокойно создать errC с двумя вариантами, в одном errA, в другом errB.


Именно поэтому вы можете пойти и посмотреть реальный код на расте. Там везде будет либо dyn err, либо () вместо ошибки. Либо будут использовать ошибки только из одного закрытого типа.

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


И эта проблема никак не решаема. Мы можем попытаться обмазываться хаками, которые будут сливать руками разные enum в один новый, потом генерировать конвертацию из всех других enum в новый. И каждый раз нам нужно будет перечислять все enum. И чем больше вложенность, чем больше разных библиотек и прочего — там больше проблем. Там будут десятки разных enum.

Без использования вложенных исключений вы получите прилетающую непонятно откуда какую-нибудь invalid argument. А с ними получите либо цепочку исключений, без возможности выбрать как её составлять (и с чертовски кривым кодом по размотке этой цепочки), либо почти точно такой же толстенный тип, содержащий всю необходимую информацию. И да, бонусом в каждом месте, где нужно будет добавить контекст, будет try-catch ручками.


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

https://doc.rust-lang.org/std/convert/trait.From.html. Достаточно описать преобразование один раз, и? либо try будут делать автоматичеки.


При этом о какой эргономики речи не идёт — это будет треш и угор, которым никто не сможет пользоваться. Примерно тоже самое, чтоб было с checked exception в С++.

Exception specifications. Потому что так же не были нормально вписаны в систему типов, как и в Java. Была точно та же проблема с отсутствием автоматического преобразования. Которое и не могло быть реализовано в С++.


Всё эти "откровения" уже давно изучены и их проблемы поняты.

Для тех кому интересно как оно выглядит — может посмотреть на жаву. Где чуть ли не каждую функцию оборачивают в try{}catch, чтобы сужать типы исключений.

Да. Потому что исключения там вписаны в систему типов криво. Нельзя быть, к примеру, generic по типу исключения. Много чего нельзя.


У исключений используется открытый тип. Именно поэтому мы можем возвращать любые типы исключений с одним интерфейсом. В расте это dyn.

В случае С++ это вообще всё, включая int, bool. Спасибо, не надо.


В ситуации с исключениями у нас есть некий магический сторедж,

Ага. Good luck ABI compatibility.


где хранится наш тип исключения. В result такого нет. Нам нужно где-то его хранить. Хранить в err неизвестный тип неизвестной длинны мы не можем. Здесь и нужен box. Можно попытаться убрать dyn используя в качестве памяти память самого err. Но тогда err нужно делать большим, но не забываем, что result — это union, а размер его равен размеру самого большего элемента. И каждый раз мы будем копировать этот гигантский юнион, даже если мы возвращаем из функции int.

Вот здесь мы подобрались к сути, отлично. Но дело в том, что в случае с Result у вас есть выбор — держать десяток вложенных энамов, "ужимать" лишние или выделять на куче. А в случае с исключениями выбора нет. ABI фиксирован, но при этом никак не специфицирован.


Далее манипуляций ещё больше. Мне достаточно и этих.

Пока что ими отличились в основном вы.

А как там у rust с эргономикой исключений? Странно сравнивать язык, который предполагает наличие исключений с тем, кто предполагает их отсутвие.

В Rust целенаправленно отказались от исключений, по многим причинам. Проблема С++ не в наличии исключений, а в отсутствии единого вменяемого способа обрабатывать ошибки без них. Про std::error_code можете не говорить, это довольно примитивный механизм обработки ошибок из платформенных API.


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

У С++ нет монополии на те же векторы, хеш-таблицы и подобные объекты. И исключения не являются единственным способом обработать ошибки.


Поэтому большинство ошибок никак не обрабатываются и триггерят паники.

Пруфов, что их именно большинств, конечно, не будет?


Аналогично try практически не работает без dyn box, не говоря уже об оверхеде на каждый вызов. Аллокатор же не особо более предсказуемый, нежели расркутка стека. Без dyn box там какая-либо эргономика отсутвует как класс.

try это вообще не про dyn box. try это всего лишь макрос для сокращения шаблонного кода вида "unwrap value or return error". И аллокатор для обработки ошибок в общем случае не требуется.


Сам же result элементарен и зачем его тащить в язык? Чтобы что? Делать новые интерфейсы с ним? Ни на что в текущей stdlib это не повляет. Для кода вне языка есть библиотеки.

Он нужен прежде всего как common ground для библиотек. Единый тип для возврата либо результата операции, либо информации об ошибке.


Особенно в контексте Qt/Unreal Engine это выглядит максимально нелепо. Почему библиотеки не решают создаваемые ими проблемы? Почему вы не спрашиватее с них, а требуете это от языка?

Хотелось бы спросить, но это проекты с чертовски долгой историей. Qt 1.0 релизнулся в 1995м, до первого стандарта. Первый релиз Unreal (не Engine) состоялся в 1998м.


Альтенативой исключений без исключений могут быть только статические исключение. Это фича языка и её действительно можно требовать. Правда её нет ни в одном мейнтримном языке, поэтому предъявить за это нельзя.

Статические исключения — по сути реализация Either/Result на уровне ABI вместо системы типов. Их нет в других мейнстримных языках именно потому, что все желающие используют Either или аналоги. Спроектированы они таким образом чтобы работать с конструкторами и другими сущностями, которые физически ничего не могут вернуть. Ну и мимикрия под обычные исключения как бонус.


? в язык никогда не затащат, надеюсь. Это не более чем костыль. В языке нет expr, которые влияют на поток управления.

Для С++ согласен, будет костылём. Да и не надо в общем-то. А вот expr, влияющие на поток управления, в С++ уже есть. Почитайте про throw в выражениях.


Если их вводить, то вводить нормально и это ящик пандоры. Лупхолы здесь покажуться детской игрушкой.

Насчёт вводить норально — полностью согласен. Я бы предпочёл GCC expression blocks в какой-то форме. А вот насчёт ящика пандоры — как же тогда функциональные и околофункцинальные языки живут?


Превращать язык в помойку, в которую суют что угодно бессистемно

Почему бессистемно? No-exceptions код это вполне себе распространённый случай, который комитет довольно долго игнорировал. Зато зета-функцию Римана добавили, вот уж нужная всем на свете штука!


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

Неофитов, знаете ли, тоже надо привлекать. Чтобы через 10-20 лет было кому писать. У С++ и так не самая плавная, мягко говоря, кривая обучения.

Причин, думаю, несколько.
Одна — эти флаги появились либо когда стандарта не было как класса (первый — ЕМНИП С++98), либо во времена, когда на точное соответствие стандарту все радостно забивали. Напомню, что MSVC перестал противоречить стандарту только в последних версиях Visual Studio 2017, а это что-то около 2019го года.
Другая причина — в момент появления исключений и RTTI (середина 90х) они давали нагрузку на размер бинарника и перформанс, которая тогда была неприемлема. Тот же Qt до сих пор по факту не является exception-neutral.
Вообще же, три из наиболее широко используемых сейчас компилятора (MSVC, GCC, CLang; про ICC не скажу) реализуют не чистый стандарт, а диалекты-надмножества, причём каждый своё.

За новость про expected спасибо. Касательно же монадического интерфейса через корутины, мне это сильно напоминает традиционное в С++ использование фич не по назначению.

Маленькая проблемка. В С++ как языке и стандарте нет такого понятия как отключаемые фичи. К примеру, любой проект, написанный с отключенными исключениями, по сути не соответствует стандарту. Так что если хотите оставаться в рамках стандарта, платить будете всегда. Как и за RTTI.

Стектрейсы это конечно замечательно. Меня, правда, смущает полнейшее игнорирование потребностей тех областей, где исключения отключены полностью и принудительно. Это, к примеру, Qt (кор не гарантирует, продвигаемый ими QML гарантированно ломается) и Unreal Engine. Нет ни expected, ни каких-то расширений эргономики, которые позволили бы реализовать аналог макроса try! из Rust.

Этот подход работает, но, увы, только если у вас проект уровня Hello World. Стоит докинуть пару усложнений вроде внешней зависимости не в вашем любимом пакетном менеджере или кодогенератора - и CMakeLists начинает шустро так распухать. Это усугубляется крайне убогим уровнем скриптового языка CMake. Один гигакостыль generator expressions чего стоит. К примеру, задача добавить в PATH или ещё куда пути всех зависимостей при запуске под отладчиком до сих пор решается руками.

В целом же, одна из основных проблем С++ - крайне фрагментированный тулинг. Интероп между разными системами сборки или пакетными менеджерами отсутствует как класс. Либо используешь фиксированный набор вроде CMake+VCPKG, либо вынужден покупать асбестовый стул.

Уточните пожалуйста, как NFT может защитить от копирования исходника работы как простого потока байт? От переподписи того же блока данных другой подписью?

EDIT: Правильный ответ - никак. В таком случае неясно, что такого уникального предоставляет NFT по сравнению с другими способами цифровой подписи файлов.

Я понимаю, что эту проблему можно обойти. Можно дописать хелпер. Загвоздка в том, что это ещё одно "плохое" поведение по умолчанию, которых в С++ и так хватает.

В целом-то понятно, что технически лямбда и корутина - разные объекты. Вопрос в том, зачем добавили ещё одни подводные грабли. Корутина не запущена, но её контекст уже создан.

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


То есть интеграция сопрограмм и лямбд в новом стандарте прошла у нас на ура!

Сарказм в словах ваших ощущаю я.

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

Подскажите пожалуйста, где можно прочитать, почему появился запрет, видимо религиозный, на клавиатуру со стрелочками нормального размера?

Нет, аналог var.

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

Информация

В рейтинге
Не участвует
Откуда
Украина
Зарегистрирован
Активность