суббота, 24 сентября 2022 г.

[prog.flame] Пару слов на тему cpp2/cppfront от Герба Саттера

Досмотрел выступление Герба Саттера на CppCon 2022, где он рассказывал про свой эксперимент на тему cpp2 и транслятора cppfront.

Впечатления сильно двойственные. Причем грустных впечатлений, наверное, все же больше :(

С одной стороны, мне нравится то, что показывал Саттер. Действительно, очень похоже на тот простой и понятный язык, который скрывается где-то внутри C++ и никак не может пробиться наружу.

Так что всячески желаю этому проекту успехов и бурного развития.

Но, с другой стороны, вот что меня сильно смущает.

Первое. Это всего лишь интересный эксперимент с непонятно какими перспективами перерасти в готовый для использования в продакшене язык программирования. Т.е. взять его в работу здесь и сейчас не получится.

ИМХО, даже если эту тему активно подхватят и вольют кучу бабла и ресурсов, потребуется пара-тройка лет, чтобы появился пригодный к повседневному использованию инструмент.

И я не знаю, будет ли мне это интересно через те самые 2-3 года. Как-то с 2020-го все больше и больше терзает мысль, что из C++ нужно уходить.

Дело не только в самом языке и в ушатах известной субстанции, которые выливаются на C++ в последние годы. Хотя мне все меньше хочется иметь дело с комьюнити, в котором такое говно, как CMake, считает нормой. Видимо, роль "адвоката C++" таки приводит к некоторому выгоранию.

Основная причина в том, что я уже неоднократно в блоге и в соцсетях говорил о том, что открыт для предложений о сотрудничестве, но нормальных заказов, связанных с C++ не случается. Есть постоянно усиливающееся впечатление, что C++ остается нужен лишь большим компаниям, в которых есть большой штат своих разработчиков, а мелкие контракторы-велосипедостроители им не нужны. Да и вообще, думается, велосипедостроители сейчас не котируются в принципе... :(

Так что не удивлюсь, если к тому времени, когда cpp2 станет полноценным новым языком программирования, я уже буду зарабатывать себе на жизнь каким-нибудь Rust-ом, Kotlin Native или даже Go :(

Второе. Герб Саттер много говорил в своем докладе о безопасности cpp2. Но, как по мне, cpp2 может быть безопаснее и надежнее нынешнего C++, но вряд ли он сможет сравниться по безопасности с тем же Rust-ом.

В качестве иллюстрации покажу слегка модифицированный пример из доклада Саттера:

main: () -> int = {
    words: std::vector = ( "A", "B", "C", "D" );
    sp: std::span = words;

    i := 0;
    for sp do :(in w: _) = {
        print_and_decorate(w);
        do_something_with_source_container(words);
        print_and_decorate(w);
    }
}

do_something_with_source_container: (inout cnt: _) = {
    cnt.push_back("A new value");
}

print_and_decorate: (thing: _) = {
    std::cout << ">> " << thing << " <<\n";
}

Здесь классическая ошибка традиционного C++: мы делаем итерацию по контейнеру, в процессе которой модифицируем этот самый контейнер. И, ожидаемо, получаем падение в run-time.

Rust от таких вещей защищает. Поскольку там есть lifetimes и borrow checker.

А вот в cpp2 ничего подобного нет. И вряд ли будет.

Так что на заявления о безопасности cpp2 я бы смотрел с изрядной долей скепсиса.

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

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

Я бы, наверное, для индикации функций использовал бы # а не :

Т.е., я бы предпочел писать так:

main# () -> int = {
    vec: std::vector = (1, 2, 3, 4, 5);

    std::ranges::for_each( vec, #(i: _) = { print(i); } );

    for vec do #(i: _) = { print(i); }
}

а не так, как сейчас:

main: () -> int = {
    vec: std::vector = (1, 2, 3, 4, 5);

    std::ranges::for_each( vec, :(i: _) = { print(i); } );

    for vec do :(i: _) = { print(i); }
}

Еще меня смущает синтаксис указателей. Разыменовывать указатель вот так: p* для меня как-то дико. Если уж мы в этом плане нарушаем совместимость с C++, то не проще ли использовать другой синтаксис? Скажем, как Паскале: p^. Как по мне, так это выглядело бы лучше и внимание к себе привлекало бы больше, раз уж в cpp2 адресная арифметика под запретом.

Ну и для взятия адреса я бы перестал использовать амперсанд, а заставлял бы явно писать std::addressof(obj).


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

4 комментария:

Stanislav Mischenko комментирует...

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

eao197 комментирует...

@Stanislav Mischenko

К сожалению, я уже так давно в программизме, что мне уже не хочется программировать для души. Сейчас если бы нужно было что-то запрограммировать, то я бы исходил из предметной области и требований к задаче. Это могли бы быть и C++, и Rust, и Kotlin или Ceylon (как альтернатива Java), и TypeScript или Dart (как альтернатива JavaScript).

Могу разве что перечислить языки, которые оставили у меня теплые воспоминания:

Turbo Pascal (еще до появления там поддержки ООП, но зато уже с модулями);
С++ где-то до C++17 включительно;
D1 времен 2007-2008 годов, затем уже D2 стал превращаться в какого-то монстра;
Ruby (но до тех пор пока проект не превышает условные 10000LOC).

Ну и есть несколько языков, с которыми не хочется сталкиваться. Прежде всего это Java и Go в силу своей убогости и ориентированности на недостаточно квалифицированных программистов. Добавлю сюда же и JavaScript, хотя я его изучал только в той степени, чтобы понимать фрагменты JS, которые размещаются в Web-страницах.

Stanislav Mischenko комментирует...

Спасибо за ответ.

> Прежде всего это Java и Go в силу своей убогости и ориентированности на недостаточно квалифицированных программистов.

Я много писал на Java под Андроид, с Go не знаком. Так вот, со временем, стал ценить именно простоту языка. Java многословна, но это легко невилирует автокоплит. За то читается очень легко, и код не превращается в ребус, в отличии от того же Котлина, где особо удурённые программисты могут легко что-нибудь эдакого навернуть.

eao197 комментирует...

> За то читается очень легко, и код не превращается в ребус, в отличии от того же Котлина, где особо удурённые программисты могут легко что-нибудь эдакого навернуть.\

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