
Комментарии 40
Языки, ставящие совместимость с C++ во главу, уже есть, например Carbon. Вот только популярности они не набирают.
Ну так это обязательно, но не достаточно условие
Есть Rust, который можно сказать одной ногой в мейнстриме. Поэтому это не обязательное условие.
Обратная совместимость с миллиардами строк кода, написанными за последние 30-40 лет, это не обязательное условие? Ну-ну…
Ну я же привёл в качестве примера Rust, на котором ваше утверждение ломается.
Как уже выше заметили всякие cpp2, carbon, circle, safecpp, D и другие попытки не увенчались успехом. Из этого всего я бы сделал обратный вывод вашему - если вы ставите во главу угла обратную совместимость с С++ то ваш язык провалится.
Как уже выше заметили всякие cfront
cfront – это первый компилятор С++.
carbon
пока еще не родился вовсе.
D
У D никогда не было совместимости с C++. Впрочем, у D толком и с самим собой совместимости-то и не было нормальной.
Я это к тому, что языков, которые бы обеспечивали совместимость с C++ и обладали бы теми же особенностями (нативный язык, без GC), вообще как бы и нет.
Я это к тому, что языков, которые бы обеспечивали совместимость с C++ и обладали бы теми же особенностями (нативный язык, без GC), вообще как бы и нет.
В том то и дело, что возможно, и это пока подтверждается на практике, язык совместимый с С++, но без его изъянов невозможен.
Изъяны С++ вытекают из его семантики и стандартов, тогда как для обеспечения низкоуровневой обратной совместимости достаточно реализовать компилятор языка как трансплайтер в С++.
Отсутствие таких языков можно объяснить не только “невозможностью”, но и “ненужностью”. Грубо говоря, уже есть C++, можно брать и пользоваться. А раз так, то зачем что-то еще?
Востребованными как раз оказываются языки, которые дают в замен что-то другое. Например:
Java – переносимость на уровне скомпилированного кода, безопасность, GC;
Go – безопасность, GC;
Rust – безопасность.
При этом пользователям данных языков вообще не вперлась совместимость с С++. Там достаточно какой-то совместимости с Си для FFI. А там, где совместимость с C++ все еще вперлась и нельзя просто так взять и переписать, то C++ и остается. И если он там остается, то зачем какие-то условные замены, если C++ и так справляется.
D имеет пары по abi: ldc + clang или gcc + gdc, и пытается как то обеспечить частичную совместимость, что непросто
Nim, V - вообще транспилеры в С, как хочет автор
Но проблема в том, что в С++ слишком много возможностей, и обеспечить с ними совместимость это будет ещё один С++
Итого - утопия
Автор считает, что нужен трансплитеор не в С, а именно в С++ как раз для того, чтобы была возможность реализовать обратную совместимость с С++ в каком угодно объеме.
Ну не правда, есть cppfront ну или как его ещё называют cpp2 от Саттера. Компилируется в С++ и его можно смешивать с существующим С++.
Пример Rust - это демонстрация невозможности его применения как прямой замены С++ и использование только в нишевых областях или отдельных проектах без легаси кода.
Тогда как для замены С++ - обеспечение обратной совместимости - это обязательное, хоть и не достаточное условие согласно банальным экономическим соображениям.
Языки, ставящие совместимость с C++ во главу, уже есть, например Carbon.
А он уже есть? Вроде как был в состоянии эксперимента, так и остается.
Сделал опрос для статьи, чтобы была конкретика для обсуждения
Мне в плюсах не хватает только ява-лайк рефлексии, но я прекрасно понимаю, почему его нет и без стрёмных костылей не может быть.
А вот во всех остальных языках, кроме плюсов, мне не хватает такого огромного зеро-кост абстракционизьма и совместимости с ядерным/железным API (также зеро-кост)
Ну базовая рефлексия уже есть в С++26. Остался только token injection для полного счастья
Руки чесались добавить в КЛанг или ГКК, но не потяну… Хотя малыми издержками есть мысли, как это добавить (вариант от ЭДГ). Или ЭДГ спереть с КЭ)))
К сожалению, только базовая и только в виде требований, пока без поддержки в компиляторах
Стандарт ещё совсем недавно финализировали и уже 2 частичных имплементации есть.
Функционал уже очень близкий к полному. Из-за комбинаторной сложности темплейтов + рефлексии некоторых вещей можно добиться разными путями, и не все пути работают.
Как ни странно, но я больше переживаю за clang, так как там вся работа велась в форке. Хоть этот форк и появился очень давно, в апстриме только первые этапы имплементации (хотя может за пару недель с последнего просмотра дела поменялись)
Если просуммировать: ваш комментарий излишне пессимистичный)
Функционал уже очень близкий к полному.
Вы зря меня считаете пессимситом, я скорее реалист, так как это изначальное предложение по рефлексии было близким к полной, но потом её ужали только до рефлексии типов, чтобы хоть с чего-то начать. Это тоже очень хорошо, так как с помощью C++26 можно закрыть некоторые проблемы.
Про отдельный форк clang с реализацией рефлексии я знаю, но так не сумел его протестить самостоятельно. Решил дождаться официального анонса хоть в каком нибудь виде.
Интерпретатор C++ CINT появился в 1991 году. Его создал мой приятель Masaharu Goto, т.е. 35 лет назад.
Он позволил реализовать полную рефлексию в ROOT (я один из соавторов).
Одно условие, все классы наследовались от TObject.
Где-то в конце тысячилетия, мой друг и учитель Рене Бран, предлагал Бьярну Страустрапу пойти по этому. Но, тот отказался.
Потом эту идею "подхватили" мелко-мягкие, когда создавали C#, где все наследуется от класса object, даже обычный int.
Как и статье, в C# есть свой unsafe. Так же, как и аналог Qtшных signal-slots (BTW, наличие рефлексии позволило мне реализовать signal-slots в ROOT).
Я двуязычный, и программируют на обоих, как на C++, так и C#.
Герб Саттер когда-то анонсировал свой cpp2, который превратился в C++26, в котором Будет Усе... и reflection и memory safety.
Само название нового стандарта, как бы намекает, что счастье где-то близко, и скоро в тишине постучится в наши двери 😉
Остается надеятся и ждать.
А, автору не изобретать велосипед. :)
Он позволил реализовать полную рефлексию в ROOT (я один из соавторов). Одно условие, все классы наследовались от TObject.
Статическая рефлексия и рефлексия в рантайм, это не одно и тоже. И если речь идет о рефлексии в рантайме, то совершено правильно, что Страустрап на это не пошел.
Герб Саттер когда-то анонсировал свой cpp2, который превратился в C++26, в котором Будет Усе… и reflection и memory safety.
Герб Саттер не позиционировал свой проект, как замена С++, тем более с reflection и memory safety. In short, it aims to help evolve C++ itself, not to be a “C++ successor.”.
Я знаю, Саттер в своей эпической статье (не помню ссылку) всегда говорил, что он не изобретает новый язык, а идет тем же путем, как когда-то прошел сам С++ - полная обратная совместимость с С.
Статическая рефлексия и рефлексия в рантайм, это не одно и тоже
Не понял? Поясните.
В ROOT вроде как, есть и то, и другое.
BTW, рефлексия в ROOT позволяет даже извлекать комментарии к классу и к методам класса.
По моему, такого ни у кого нет.
Рефлексия в ROOT позволила сохранить все данные с Большого Адронного Коллайдера. А, это тысячи Пентабайт данных. Где еще больше?
Рефлексия может быть в рантайм (получить информацию о классе во время выполнения программы) и может быть статическая, т.е. только во время компиляции.
В С++ рефлексия статическая без рантайм оверхеда, который неизбежен в случае наследования всех классов от TObject.
gcc16 уже близок, в скором времени (надеюсь:)) можно будет опробовать без самостоятельной компиляции.
А рефлексия типов (и генерация агрегатов) - это уже много возможностей для адаптации кода под необходимости.
На самом деле кажется что для большинства функций C++26 уже достаточно. Да, нельзя генерировать *функции* с произвольным именем. Нельзя делать произвольную сигнатуру без темплейтов (полезность языковых серверов падает). Но реализация функции уже может извлекать ОЧЕНЬ много информации и адаптироваться.
Из перечисленных в опроснике проблем, часть проблем базово уже решена, остался только тяжелый переход. Если мы говорим о макросах и #include то С++20 модули, системы сборки научились работать с модулями, остался просто переход на модульную систему ( а это не быстро). Если мы говорим о сложности в метапрограммировании то она есть только на стандартах до с++17, после стало все гораздо лучше особенно с приходом с++20 (SFINAE мертво так как есть концепты). Если говорим уже о UB - то с++26 убирает часть UB. Сложность многопоточки решается больше уже поддержкой сообщества с появлением более удобных библиотек. Так что С++ решает свои болячки но не так быстро как хотелось бы
остался только тяжелый переход…
К сожалению “базовая”, это только на уровне типов. Часть проблема это снимает, вроде той же сериализации, но рефлексию для тела функции или хотя бы блоков кода наверно не будет вообще никогда.
Макросы и инклуды в модулях решались чуть ли не десять лет, и когда этот процесс завершиться пока еще непонятно.
Метапрограммирование лучше вообще не комментировать. Да, концепты улучшили ситуацию, хоть они и обсуждались с 2000-х годов, но в результате SFINAE все равно приходится тащить, так как обратная совместимость :-(
Сложность многопоточки решается больше уже поддержкой сообщества с появлением более удобных библиотек.
Так это потому, что нет других вариантов. Если бы была рефлексия не для типов, а хотя бы на уровне фрагментов AST, можно было бы реализовать часть проверок во время компиляции.
А раз ничего этого нет и не ожидается, вот и приходится городить огород с помощью библиотек. Но это ограничения на уровне договоренностей или ревью кода, т.е. “на счетном слове”, а не на уровне стандарта языка :-(
Ну ведь это ученый изнасиловал журналиста.
Проблема не в самой нулевой ссылке, а в том, что языки её не проверяют. В С/С++, проблема не в самом null, а в том, что ссылка может быть не инициализирована и иметь произвольное значение, т.е. проблема как раз в том, что она НЕ является нулевой :-)
понято! нул штука полезная и вреда от нее нет! убирать ее не будем!
Неинициализированные значения это отдельная боль, основная же проблема null как раз в том, что есть возможность разыменовать nullable ссылку (указатель в плюсах). И решается проблема запретом такого действия (Rust) и необходимостью сперва условно превратить такую nullable ссылку (Option) в ненулевую, что избавляет от ошибки доступа к памяти.
возможность разыменовать nullable ссылку (указатель в плюсах).
Так это проблема, что программист не проверяет указатель на недействительность, а не самого nullptr.
Можно принудительно кастануть Option, когда там нет инициализировнного указателя и тоже будет ошибка, но ведь это не становится проблемой Option?
Так это проблема, что программист не проверяет указатель на недействительность, не самого nullptr.
C++ позволяет делать это (не проверять), в этом и проблема.
Option, когда там нет инициализировнного указателя
Речь здесь уже про Rust, а там в safe коде нет такой возможности неинициализировать
В С++ все необходимое есть, используйте.
Не надо совать Rust во всякую дырку, тем более в статье описано почему.
Unwrap не требует unsafe, прекрасно упадёт и в rust
В С++ все необходимое есть, используйте.
Не беспокойтесь, использую. Речь шла о другом - о том, что позволяется не проверять и позволяется разыменовывать nullable ссылки (указатели).
Начиналась то ветка с ошибки на ярд долларов, это к этому вопросу
Не надо совать Rust
Это лишь как пример решения проблемы
Unwrap не требует unsafe, прекрасно упадёт и в rust
Упадёт, но не будет UB
Учите C++, пока не поздно: https://share.google/aimode/u3S4N2w2u0aLjuhh3
Ахиллесова пята C++ и будущая р̶е̶ эволюция