Попробуем выдвинуть аргументы против Rust +49




Недавно я прочитал статью c критикой Rust. Хотя в ней было много правильных вещей, она мне не понравилась — слишком многое там очень спорно. В целом, я вообще не могу рекомендовать к прочтению никакой статьи с критикой Rust. Это нехорошо, ведь важно обсуждать недостатки, а шельмование низкокачественной и неумелой критики, к сожалению, заставляет пропустить мимо внимания действительно хорошие аргументы.

Итак, попробую привести аргументы против Rust.

Не всё программирование является системным


Rust — язык системного программирования. Он обеспечивает точный контроль над компоновкой данных и поведением кода во время выполнения, обеспечивая максимальную производительность и гибкость. В отличие от других языков системного программирования, он также обеспечивает безопасность памяти — глючные программы завершаются чётко определенным образом, не допуская (потенциально опасного) неопределённого поведения.

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

Сложность


Время программиста дорого стоит, а в случае Rust придётся потратить много времени на изучение самого языка. Сообщество приложило немало сил для создания высококачественных учебных материалов, но язык очень большой. Даже если вам выгодно переписать проект на Rust, само изучение языка может оказаться слишком дорогим.

Цена за улучшенный контроль — это проклятие выбора:

struct Foo     { bar: Bar         }
struct Foo<'a> { bar: &'a Bar     }
struct Foo<'a> { bar: &'a mut Bar }
struct Foo     { bar: Box<Bar>    }
struct Foo     { bar: Rc<Bar>     }
struct Foo     { bar: Arc<Bar>    }

В Kotlin вы пишете класс Foo(val bar: Bar) и приступаете к решению задачи. В Rust нужно сделать выбор, иногда достаточно важный, со специальным синтаксисом.

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

См. также презентацию «Почему C++ держится на плаву, когда корабль „Ваза” затонул».

Время компиляции


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

В дилемме дженериков Rust намеренно выбрал медленные компиляторы. В этом есть определённый смысл (рантайм действительно ускоряется), но вам придётся всеми силами бороться за разумное время сборки в более крупных проектах.

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

В отличие от C++, сборка Rust не распараллеливается до предела, количество параллельных процессов ограничено длиной критического пути в графе зависимостей. Разница будет заметна, если у вас больше 40 ядер для компиляции.

В Rust также нет аналогов для идиомы pimpl, так что изменение крейта требует перекомпиляции (а не просто перелинковки) всех его обратных зависимостей.

Зрелость


Пять лет — это определённо малый срок, так что Rust молодой язык. Хотя будущее кажется блестящим, но всё-таки более вероятно, что через десять лет мы будем программировать на С, а не на Rust (см. эффект Линди). Если вы пишете софт на десятилетия, то должны серьёзно рассмотреть риски, связанные с выбором новых технологий (хотя выбор Java вместо Cobol для банковского программного обеспечения в 90-е годы ретроспективно оказался правильным выбором).

Есть только одна полная реализация Rust — компилятор rustc. Наиболее продвинутая альтернативная реализация mrustc целенаправленно пропускает многие статические проверки безопасности. На данный момент rustc поддерживает только один продакшн-ready бэкенд — LLVM. Следовательно, поддержка процессорных архитектур здесь более узкая, чем у C, у которого есть реализация GCC, а также поддержка ряда проприетарных компиляторов, специфичных для конкретных вендоров.

Наконец, у Rust нет официальной спецификации. Текущая спецификация не завершена и не документирует некоторые мелкие детали реализации.

Альтернативы


Кроме Rust, для системного программирования есть и другие языки, в том числе C, C++ и Ada.

Современный C++ предоставляет инструменты и рекомендации для повышения безопасности. Есть даже предложение о безопасности времени жизни объектов в стиле Rust! В отличие от Rust, использование этих инструментов не гарантирует отсутствие проблем с безопасностью памяти. Но если вы уже поддерживаете большой объём кода C++, имеет смысл проверить, возможно, следование рекомендациям и использование санитайзеров поможет в решении проблем безопасности. Это трудно, но явно легче, чем переписывать весь код на другом языке!

Если вы используете C, то можете применить формальные методы, чтобы доказать отсутствие неопределённого поведения, или просто тщательно всё протестировать.

Ada безопасна для памяти, если не использовать динамическую память (никогда не вызывайте free).

Rust — интересный язык по соотношению затрат к безопасности, но далеко не единственный!

Набор инструментов


Инструменты Rust не назовёшь идеальными. Базовый инструментарий, компилятор и система сборки (cargo) часто называют лучшими в своём классе.

Но, например, некоторые инструменты, связанные со средой выполнения (в первую очередь, для профилирования кучи), просто отсутствуют — трудно размышлять о рантайме, если инструмента просто нет! Кроме того, поддержка IDE тоже далеко не соответствует уровню надёжности Java. На Rust просто невозможен автоматизированный сложный рефакторинг программы с миллионами строк.

Интеграция


Что бы ни обещал Rust, но сегодняшний мир системного программирования говорит на C и C++. Rust намеренно не пытается имитировать эти языки — он не использует классы в стиле C++ или C ABI.

Это означает, что между мирами нужно наводить мосты. Интеграция не будет бесшовной, она небезопасна, не всегда обойдётся без затрат и требует синхронизации между языками. В то время как местами интеграция работает и инструментарий сближается, на этом пути возникают случайные препятствия из-за общей сложности.

Одна из специфических проблем заключается в том, что самоуверенное мировоззрение Cargo (великолепное для чистых проектов Rust) может затруднить интеграцию с более крупными системами сборки.

Производительность


«Использование LLVM» не является универсальным решением всех проблем производительности. Хотя я не знаю бенчмарков, сравнивающих производительность C++ и Rust в целом, но нетрудно придумать задачи, где Rust уступает C++.

Вероятно, самая большая проблема в том, что семантика перемещения Rust основана на значениях (memcpy на уровне машинного кода). С другой стороны, семантика C++ использует специальные ссылки, из которых можно взять данные (указатели на уровне машинного кода). Теоретически, компилятор должен видеть цепочку копий, на практике это часто не так: #57077. Связанная с этим проблема заключается в отсутствии размещения новых данных — Rust иногда нужно копировать байты в/из стека, в то время как C++ может создать объект на месте.

Несколько забавно, что в дефолтный Rust ABI (в котором пожертвовали стабильностью ради эффективности) иногда работает хуже, чем у C: #26494.

Наконец, хотя теоретически код Rust должен быть более эффективным из-за значительно более богатой информации об алиасах, включение оптимизации, связанной с алиасами, вызывает ошибки LLVM и некорректную компиляцию: #54878.

Но, повторюсь, это редкие примеры, иногда сравнение происходит в другую сторону. Например, в Box у Rust нет проблемы производительности, какая есть у std::unique_ptr.

Потенциально более серьёзная проблема заключается в том, что Rust с его определениями дженериков менее выразителен, чем C++. Таким образом, некоторые шаблонные трюки C++ для высокой производительности не могут быть выражены в Rust с помощью хорошего синтаксиса.

Значение unsafe


Возможно, идея unsafe даже более важна для Rust, чем владение и заимствование. Выделяя все опасные операции в блоки unsafe и функции и настаивая на предоставлении им безопасного интерфейса более высокого уровня, можно создать систему, которая одновременно:

  1. надёжная (не отмеченный unsafe код не может вызвать неопределённое поведение),
  2. модульная (различные небезопасные блоки можно проверить отдельно).

Вполне очевидно, что так оно и есть: фаззинг кода Rust находит панику, но не переполнения буфера.

Но теоретические перспективы не столь радужны.

Во-первых, нет определения модели памяти Rust, поэтому невозможно формально проверить, является ли данный небезопасный блок допустимым или нет. Существует неофициальное определение «вещей, которые rustc делает или на которые может полагаться» и продолжается работа над верификатором рантайма, но фактическая модель не ясна. Таким образом, где-то может быть какой-то небезопасный код, который сегодня работает нормально, а завтра будет объявлен недействительным и сломается в новой оптимизации компилятора через год.

Во-вторых, есть мнение, что блоки unsafe на самом деле не являются модульными. Достаточно мощные блоки unsafe могут, по сути, расширить язык. Два таких расширения не делают ничего плохого в изоляции друг от друга, но приводят к неопределённому поведению при одновременном использовании: см. статью «Наблюдаемая эквивалентность и небезопасный код».

Наконец, в компиляторе есть явные ошибки.

Вот некоторые темы, которые я намеренно опустил:

  • Экономика («труднее найти программистов на Rust») — мне кажется, раздел «Зрелость» отражает суть этого вопроса, который не сводится к проблеме курицы и яйца.
  • Зависимости («stdlib слишком мал / везде слишком много зависимостей») — учитывая, насколько хорош Cargo и соответствующие части языка, я лично не вижу в этом проблемы.
  • Динамическое связывание («в Rust должен быть стабильный ABI») — не думаю, что это сильный аргумент. Мономорфизация фундаментально несовместима с динамическим связыванием, и если вам действительно нужно, то есть C ABI. Я действительно думаю, что здесь можно улучшить положение вещей, но вряд ли речь идёт о специфичных изменениях именно в Rust.

Обсуждение темы в /r/rust.




Комментарии (71):

  1. Alex_ME
    /#22117724

    Попробую высказать критику на критику и дополнения. Я соглашусь с вами в двух пунтках:


    • Rust еще слишком молод. Думаю, следствием этого являются пункты "Набор инструментов", "Интеграция", "Производительность" и "Unsafe". Есть основания полагать, что со временем будет происходит улучшение в этом плане. Ошибки есть и в GCC (сам видел).
    • Rust сложен и имеет более крутую кривую входа

    Я бы еще добавил, что проблема в том, что Rust позиционируется как более безопасный язык, чем Си, но компилятор он слишком неформализован и активно развивается, чтобы быть сертифицированным для применения в каких-то реально safety-critical задачах, где, к примеру, сертифицирован лишь какой-нибудь IAR.


    Еще из недостатков (как следствие молодости) добавлю малое количество библиотек. На С++, не говоря уже о С, больше. Захотел я GUI писать и приуныл. Пока что самая зрелая — веб-гуи на WASM, yew.


    Не всё программирование является системным

    Не соглашусь. Rust дает преимущества и не в системном программировании, не за счет модели работы с памятью, а за счет своей системы типов (ADT, pattern matching и все такое). Например, подход Option вместо исключений может сделать более понятным (по сигнатуре видно) и безопасным. Но проблема в том, что как, уже сказано, Rust имеет сложности, и все равно придется думать о владении, памяти, лайфтаймах и всяких Rc<RefCell>

    • Aleshonne
      /#22118532

      Я бы еще добавил, что проблема в том, что Rust позиционируется как более безопасный язык, чем Си, но компилятор он слишком неформализован и активно развивается, чтобы быть сертифицированным для применения в каких-то реально safety-critical задачах, где, к примеру, сертифицирован лишь какой-нибудь IAR.

      Для safety-critical я бы посоветовал упомянутую в статье Аду в режиме SPARK.
      Там есть контракты, которые в C++ уже давно обещают, но никак не завезут, формальная верификация, много приятностей вроде параллельности из коробки и значений нестандартного размера (вроде массива из 8 элементов по 3 бита каждый) и удобочитаемый синтаксис. Есть, правда, и суровый минус — писать на этом тяжело. Впрочем, это можно считать и плюсом: набирая Очень_Длинный_Идентификатор_Из_Стандартной_Библиотеки_Языка_Ада программист успеет ещё раз обдумать реализацию. И какой нибудь Unchecked_Deallocation явно говорит о том, что надо всё перепроверить.

      • Siemargl
        /#22118914

        Как парируем сентенцию из статьи?

        Ada безопасна для памяти, если не использовать динамическую память (никогда не вызывайте free).

        • Aleshonne
          /#22119024 / +2

          В режиме SPARK нельзя выделять динамическую память вообще (и использовать контролируемые типы, для которых переопределена процедура инициализации). Только автоматическое создание переменной при входе в её область видимости и удаление при выходе. На крайний случай есть пакет Unchecked_Deallocation (когда выгрузить что-то из памяти вот прям очень нужно), но у него даже название звучит страшно и на его использование будет warning.
          Впрочем, с высоты моего опыта (аж одна полноценная программа на Аде), динамическая память там нахрен не сдалась, всё и так нормально работает.

          • Siemargl
            /#22119042 / +2

            Тут вот оно чё, Михалыч.

            Как только нет динамической памяти с указателями (или есть GC) и нет многопоточности, то все языки становятся надежными, как Раст =) Остальное плюс минус мелочи.

            Впрочем многопоточность тоже минорный фактор в этом сравнении.

            • arthuriantech
              /#22119116 / +2

              Между прочим, правила MISRA C тоже запрещают malloc/calloc/free.

            • dmitryrf
              /#22120388

              С позволяет писать за границы массива независимо от способа выделения памяти.

              • Siemargl
                /#22120572

                Как бы Раст тоже позволяет. Будет паника.
                Аналогичного результата в С получим с -fsanitize=bounds

                • dmitryrf
                  /#22120634 / +2

                  #include <stdio.h>
                  
                  int main(void)
                  {
                      char buf[5];
                      char buf2[5];
                      int m = 1000000;
                  
                      sprintf(buf2, "%d\n", m);
                      sprintf(buf, "%d\n", m);
                      printf("%s%s", buf, buf2);
                  
                      return 0;
                  }
                  
                  $ gcc -fsanitize=bounds -o oob ./oob.c 
                  $ ./oob 
                  1000000
                  100001000000
                  

                  Тишина, все довольны. Или я что-то не так делаю?

                  • Siemargl
                    /#22120672

                    Вообще то да. Путаешь массивы и указатели =)

                    Собственно, это было выдвинуто на премию C’s Biggest Mistake

      • 0xd34df00d
        /#22127738 / +1

        Для safety-critical я бы посоветовал упомянутую в статье Аду в режиме SPARK.
        Там есть контракты, которые в C++ уже давно обещают, но никак не завезут, формальная верификация

        Почему аду, а не агду? В ней есть полноценная внутренняя формальная верификация, зависимые типы и вот это вот всё.


        И какой нибудь Unchecked_Deallocation явно говорит о том, что надо всё перепроверить.

        А могли бы типы говорить.

        • Aleshonne
          /#22128024

          Почему аду, а не агду?

          А есть ли у агды стандарт? Все нормативные документы (вроде ISO 26262) требуют наличия стандарта для языка программирования при использовании его в safety-critical областях, дабы через условные 20 лет в случае катастрофы эксперты вооружились этим стандартом и проверили, что код был написан правильно (или неправильно), а не гадали, что делает какой нибудь оператор вроде [@!], удалённый из языка 15 лет назад (а историю коммитов потеряли 10 лет назад при переезде на другой сервер). На аду есть стандарты ГОСТ и ISO, на си — ISO, даже на яваскрипт есть стандарт ECMA. Яваскрипт, правда, не проходит из-за динамической типизации, так что мы вряд ли увидим ракету, которая сложила -2 и 10 и, получив -210, улетела в сторону ближайшей чёрной дыры хвостом вперёд.
          PS Я сам люблю функциональное программирование, но это не те задачи, в которых его сейчас можно применять. Мир к этому ещё не готов.

          • 0xd34df00d
            /#22128212 / +1

            Все нормативные документы (вроде ISO 26262) требуют наличия стандарта для языка программирования при использовании его в safety-critical областях

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


            дабы через условные 20 лет в случае катастрофы эксперты вооружились этим стандартом и проверили, что код был написан правильно (или неправильно), а не гадали, что делает какой нибудь оператор вроде [@!], удалённый из языка 15 лет назад (а историю коммитов потеряли 10 лет назад при переезде на другой сервер)

            Наличие шильдика ISO не защищает магическим образом от аналогичной потери чего-нибудь при переезде на другой сервер, а агдой всё-таки пользуется достаточно много людей, чтобы распределённая природа гита взяла своё.

            • Aleshonne
              /#22128336 / +1

              этакая бюрократическая верификация
              Ну так бумажки — это же самое главное! Мы живём в мире победившей бюрократии.
              Но если хочется что-то на самом деле доказать, то они не лучший выбор.
              Как минимум SPARK можно статически проверить на соответствие программы спецификации и на отсутствие исключений. Не верифицируется только стандартная библиотека (прувер считает, что в ней нет ошибок), но все контракты для неё прописаны и их соблюдение будет проверено.
              Наличие шильдика ISO не защищает магическим образом от аналогичной потери чего-нибудь при переезде на другой сервер, а агдой всё-таки пользуется достаточно много людей, чтобы распределённая природа гита взяла своё.
              Стандарт фиксирует определённое состояние языка на некий момент времени. Ребята из ISO уверены, что это важно, и я им доверяю. А гарантировать, что агдой будут пользоваться спустя сколько-то лет никто не может, вдруг выйдет какой-нибудь Coq2, который будет лучше и на который все переедут. А напечатанный на бумаге стандарт прекрасно пролежит в библиотеке лет 200.

              • 0xd34df00d
                /#22128430 / +1

                Как минимум SPARK можно статически проверить на соответствие программы спецификации и на отсутствие исключений.

                А насколько выразителен язык спецификации? То, что я сходу нагуглил, говорит о SMT-разрешимых VC, а это заведомо довольно слабая штука.


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


                Не верифицируется только стандартная библиотека (прувер считает, что в ней нет ошибок), но все контракты для неё прописаны и их соблюдение будет проверено.

                Лучше всё ж доверять всего лишь ядру проверялки, а не ядру проверялки + стандартной библиотеке.


                Стандарт фиксирует определённое состояние языка на некий момент времени. Ребята из ISO уверены, что это важно, и я им доверяю. А гарантировать, что агдой будут пользоваться спустя сколько-то лет никто не может, вдруг выйдет какой-нибудь Coq2, который будет лучше и на который все переедут.

                Так это вполне себе решаемые вопросы. В хаскеле, например, есть такая штука, как stackage snapshots, и в проекте указывается конкретный снапшот. Я так, например, не так давно вытащил какой-то старый проект, который закончил в 2016-м, и спокойно собрал его в том же окружении, что четыре года назад, с тем же компилятором, теми же версиями зависимостей, и, вполне возможно, получив до бита такой же бинарник. В идрисе, агде и коке такого вроде как нет, но это, опять же, исключительно вопрос тулинга, а не какая-то фундаментальная недоработка.


                А напечатанный на бумаге стандарт прекрасно пролежит в библиотеке лет 200.

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

                • Aleshonne
                  /#22128576

                  А насколько выразителен язык спецификации? То, что я сходу нагуглил, говорит о SMT-разрешимых VC, а это заведомо довольно слабая штука.
                  А то я просто сейчас вот пишу недостатью, где описываю какой-то модельный язычок, и в этой своей агде я описываю язык и доказываю формально всякие интересные свойства этого языка. Можно так в аде?
                  Я, в общем то, нагуглил то же самое. У спарка ограничения довольно серьёзные. Описывать свой язык — это к дружной компании из агды, идриса и кока. Ада и спарк, это скорее, проверять, что протокол общения с каким-нибудь исполнительным механизмом не может быть нарушен.
                  Кстати, вот тут есть справка по тому, что спарк может. А там в конце в разделе Alternative Provers скромно так говорят, что можно в параметрах командной строки написать --prover=Coq, что уже несколько расширяет возможности языка.
                  Лучше всё ж доверять всего лишь ядру проверялки, а не ядру проверялки + стандартной библиотеке.
                  В стандартной библиотеке есть код, на который проверялка ругается. Сырые указатели, дёрганье ОС напрямую и т.д. Остаётся надеяться, что разработчики проверили корректность работы всего этого добра.
                  это, опять же, исключительно вопрос тулинга, а не какая-то фундаментальная недоработка
                  Вот только задумались о такой нужной вещи только разрабы хаскеля. Я, например, о таком для фортрана мечтаю, но оно и близко не предвидится.

    • sshikov
      /#22122782

      >>Не всё программирование является системным
      >Не соглашусь.
      Ну а почему? Реально же не всё. Если бы даже Rust был пригоден только для системного — это разве было бы реально серьезным недостатком?

      Ну и наборот тоже, вот скажем упоминание kotlin в одном контексте вас разве не смущает? Вот уж котлин-то вообще для системного программирования скорее всего не годится. Ну и ничего, никто не жалуется, есть ниши, где он хорош — ну и прелестно.

  2. krizhanovsky
    /#22117916

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


    В качестве практического примера приведу быстрые парсеры. В моем случае для разработки быстрого HTTP прасера понадобился не только GOTO, которого нет в Rust, но еще и computed labels — это уже compiler specific расширения для C.


    Т.е. вот, есть реальная, не такая маленькая, задача, которую C решает лучше Rust. Но я не видел ни одной задачи, которую Rust решает лучше C. Удобство и быстрота разработки — возможно, но не скорость работы.


    Если мучительно отлаживать указатели на C, то мы используем C++ с его smart pointers, RAII и пр. (Я могу вспомнить пару плохонаписанных, не наших, C проектов, которые мы переводили на C++ и в наиболее геморойных местах заменяли C указатели на smart pointers). В C++ можно всегда и просто встроить код на C, который будет работать очень быстро: совместимость с C — ключевое свойство C++ для системного программирования. C Rust, как и с D (тоже была такая 'лучшая' альтернатива C++), будут еще телодвижения на совместную компиляцию с C.


    А еще видел неплохое, относительно нейтральное, сравнение C и Rust.

    • freecoder_xx
      /#22118430

      Но я не видел ни одной задачи, которую Rust решает лучше C. Удобство и быстрота разработки — возможно, но не скорость работы.

      Вот тут есть некоторые задачи, которые Rust решает быстрее: https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust.html
      Значит ли, что в принципе это возможно?

      • krizhanovsky
        /#22118512

        Давайте посмотрим на первый бенчмарк Rust и C. Во-первых, эту программу на Rust, как многие другие для этих бенчмарков, написала команда разработчиков Rust — коментарий из копирайта:


        contributed by the Rust Project Developers

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


        Реализация на С https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/binarytrees-gcc-3.html — достаточно короткая реализация на OpenMP и APR, но явно не оптимизировалась вообще.

      • technic93
        /#22118908 / +1

        Не очень хороший сайт с бенчмарками по двум причинам.
        1) Формулировка критериев оцениявания решения размыта. Заявляется, что типа решение должно быть "идиоматическое" но что это значит определяет левая пятка владельца бенчмарков. Отсюда там у него были истории что он то забанит решения то разбанит.
        2) Гоняется это на старом по меркам 2020 железе.


        Upd. Да что далеко ходить. Прямо на вашом примере


        As a practical matter, the myriad ways to custom allocate memory will not be accepted.
        Please don't implement your own custom "arena" or "memory pool" or "free list" — they will not be accepted.

        Cмотрю топ2


        using MemoryPool = std::pmr::monotonic_buffer_resource;

        use typed_arena::Arena;

        ?\_(?)_/?

        • mayorovp
          /#22118952 / -2

          Дык std::pmr и крейт typed_arena — это не your own custom "arena", это нечто общедоступное

    • Antervis
      /#22118588

      в большинстве случаев сравнивать результат надо при сравнимых трудозатратах. Потому что если абстрактный Вася напишет на том же расте за вдвое меньшее время, это значит не только что его решение на 20% медленнее, но и то, что он может потратить оставшееся время на оптимизации боттлнеков. Ну или, чаще, решения других задач.

      • krizhanovsky
        /#22118642

        Вася на Rust не напишет в 2 раза быстрее, потому что "Вася" — это средний программист, который о Rust только слышал, в бою его не пробовал. Начиная новый проект, мы знаем, что на рынке много C/C++ разработчиков, много наработанных библиотек, инструментариев и просто ответов на StackOverflow.


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

        • Antervis
          /#22118706

          мой поинт именно в сравнении с си, поэтому от подмены абстрактного Васи с растом на абстрактного Петю с плюсами мало что поменяется.

          • Siemargl
            /#22118902 / +1

            В сравнении с Си, абстрактный Вася будет писать вдесятеро дольше, правда и отлаживаться вдесятеро меньше =)

            • technic93
              /#22118938 / +1

              Мой абстрактный Вася на си породит такое гавно что оно будет падать в половине случаем и отлаживать его ещё два года. На расте даже питонист может настаковерфловить решение за несколько дней =)

            • Antervis
              /#22118960

              чет у вас Вася сильно абстрактный получился. Берите хотя бы с полугодом опыта коммерческого программирования

        • 0xd34df00d
          /#22127774 / +1

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

          Средний программист не будет ничего писать с computed goto, а будет отстреливать себе ноги UB'ами в С, и в итоге не напишет вообще ничего и никогда.


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

          Я где-то тыщ пять разных вечеров скоротал за C++, и в итоге решил, что да ну нафиг, надо прекратить совершать sunk costs fallacy, и стал разбираться в матчасти немного других языков, и мои волосы в итоге стали мягкими и шелковистыми.


          А что до ваших HTTP-парсеров, я лучше набросаю на хаскеле eDSL и транслятор в какой-нибудь LLVM IR, чтобы не бороться с компилятором, где это не нужно, и не писать код на ассемблере в презервативе через какой-то адовый прокси из С-с-подглядками-в-дизасм, а сразу писать почти ассемблер.


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

    • ahdenchik
      /#22119524

      C Rust, как и с D (тоже была такая 'лучшая' альтернатива C++), будут еще телодвижения на совместную компиляцию с C.

      Какие? Ежедневно компилирую вместе D и C без каких-либо проблем.

    • bolk
      /#22119550

      Разве у Си++ всё ещё осталась совместимость с Си? Или имеется ввиду АБИ?

      • krizhanovsky
        /#22121400

        Я имел ввиду, что из C++ программы я могу заинклюдить C хедер и в общем случае (не учитывая, напирмер, использование new идентификаторов в C) это "работает из коробки". Есть интеграция из C++ в C через extern "C". Так или иначе, но С++ наиболее совместим с C. Например, наткнулся на такой пост про использование C хедеров из D: https://atilaoncode.blog/2018/04/09/include-c-headers-in-d-code/ .

    • YetAnotherSlava
      /#22124684

      «нужен именно „чемпионский“
      »GOTO"
      «Удобство и быстрота разработки — возможно, но не скорость работы»

      Сам топи урановые ломы во ртути

      PS: я кстати очень надеюсь, что это ваше Си просто запретят. Ну как нельзя ездить по дорогам общего пользования на автомобиле без тормозов и ещё многих вещей.

      Потому что сперва у вас «лучшие бенчмарки на рынке» и «чемпионский код», написанный методом «мамой клянус, надёжно работает», потом у вас ХХХХ прибыли, а когда в вашем чемпионском коде находят уязвимости, у других людей возникает 100*XXXX убытков.

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

      Переживёте вы поди без чемпионства, без высокой прибыли и без первенства на рынке. Хотите чтобы не тормозило — уймите фантазию фронтендеров.

  3. dark_ruby
    /#22118092

    "системный язык программирования" — это очень неопределенный термин, как его понимать? это значит что на Расте можно только драйвера или ядро писать? — Явно ответ нет! Можно и веб-странички писать при желании, не спроста там впилена поддержка WebAssembly.
    Единственный "аргумент" против раста это лайфтаймы, но их просто надо понять, и в большинстве тривиального кода они не используются.

    • freecoder_xx
      /#22118544

      Мне вот тоже видится, что применение Rust шире ниши низкоуровневых системных задач. Но я уже писал статью на этот счет: https://habr.com/ru/post/504622/

  4. Antervis
    /#22118154

    В Rust также нет аналогов для идиомы pimpl
    не хватает forward declarations и разделения объявления/реализации?
    Динамическое связывание («в Rust должен быть стабильный ABI») — не думаю, что это сильный аргумент. Мономорфизация фундаментально несовместима с динамическим связыванием, и если вам действительно нужно, то есть C ABI
    оборачивать туда-обратно через C ABI неудобно и накосячить можно практически везде, даже из плюсов, которые к сям явно ближе.

  5. math_coder
    /#22118224 / +3

    После того, как освоил Rust в достаточной мере, на C становится писать невозможно: если до этого писал и не думал, что тут может быть какая-то проблема, то после достаточно плотного знакомства с Rust ты понимаешь, что то нельзя, это нельзя, и надо проверить, не происходит ли вот этого… (за чем в Rust следил компилятор), и в итоге оказывается, что просто невозможно за всем уследить и всё необходимое проверить.

    • Siemargl
      /#22118910

      Это симптомы Параноидного психоза, читаем 2й абзац =)

      • gotozero
        /#22120626 / +1

        Ну конечно. «Я то пишу без ошибок» )
        Видали мы таких. Я сижу на КДЕ, где плюсы, и местами довольно свежие.
        Такого количества глупых багов, вечно повторяющихся тут сотни.
        Спасибо, не надо.

      • ratijas
        /#22120984 / -1

        Проклятие знания / осведомленности.

      • 0xd34df00d
        /#22127786 / -1

        Надо было на прошлых работах брать надбавки за вред для психики.

  6. freecoder_xx
    /#22118414 / +1

    Сложность Rust имеет двойственную природу.


    С одной стороны, в языке присутствуют мощные, и от этого довольно сложные для новичков концепции, которые, однако, упрощают разработку любой программы, которая чуть сложнее, чем hello world. Такая сложность является препятствием только при первом освоении языка, а в работе она собой компенсирует значительную сложность самой программы. Да, вы можете взять язык сильно проще, но потом будете дольше устранять проблемы в своем коде, особенно если его много и он многопоточный.


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

    • Alex_ME
      /#22119188

      Можете привести пример исключений из красивых концепций? Мне кажется, что, примером исключений из концепций является C++, который (по моему скромному опыту, я больше по Си) состоит из исключений и замороченного поведения чуть менее, чем полностью. (Например, я все еще немного вздрагиваю, когда надо возвращать что-то из функции. Ну да, guaranteed copy elision, но похоже на магию).

      • Gorthauer87
        /#22119358

        Попробуйте async метод в трейте обьявить.

      • freecoder_xx
        /#22120532

        Нет специализации, impl Trait можно использовать только для функций, const generics до сих пор не стабилизированы — из-за этого небольшой адок при работе с массивами, по сравнению со срезами, auto Trait можно использовать только внутри std, даже некоторые фичи паттерн-матчинга еще не работают: хорошо, что недавно стабилизировали паттерны [..], но вот так до сих пор нельзя:


        let tuple @ (a, b) = (1, 2);

        error[E0658]: pattern bindings after an `@` are unstable
         --> src/main.rs:2:18
          |
        2 |     let tuple @ (a, b) = (1, 2);
          |                  ^
          |
          = note: see issue #65490 <https://github.com/rust-lang/rust/issues/65490> for more information

  7. untilx
    /#22119504

    Не знаю, как это спросить так, чтобы не выглядело, будто я тролль, но попробую. Вот попадаются статьях в упоминания Ada. Народ это всерьёз или ради хохмы? Ну, просто я не знаю, кто реально её использует, а вакансий с ней я не видел вообще ни разу, при том, что даже Haskell и Delphi периодически попадаются.

    • kunix
      /#22119616

      Ну во-первых, Язык Ада — это красиво :)

    • Aleshonne
      /#22119808

      Например, всё ПО самолёта Бе-200 на Аде написано. И у ракеты-носителя Vega.
      Отдельные вакансии на Аду встретить тяжело, так как ищут не абстрактного программиста на Аде, а разработчика ПО систем авионики или специалиста по ПО космических аппаратов. Знание предметной области в данном случае важнее знания языка программирования.
      Ну и вот, например, любопытный документ.

      • untilx
        /#22129048

        Соглашусь, вот это уже серьёзно

    • 0xd34df00d
      /#22127792 / +1

      Вы так говорите «даже хаскель», как будто мы в 2008-м, а не в 2020-м году живём.


      Вот когда я видел вакансии на идрис, это да, это было удивительно.

  8. devopg
    /#22120344 / -1

    На расте 95% всех вакансий блокчейн. Кроме блокчейнов раст гдето нужен?

    • ratijas
      /#22121056

      Давайте развернем столы, и спросим: а блокчейн где-то нужен?


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


      PS пишу как человек, почти устроившийся на такую работу, но вовремя заботавший матчасть.

      • 0xd34df00d
        /#22127798

        В блокчейнах традиционно множество матана и пруфов корректности кода

        Для чего раст, чсх, подходит плохо.

        • ratijas
          /#22127856

          Выпад в сторону недоделанных const generics засчитан.

          • 0xd34df00d
            /#22128216

            const generics тут недостаточно. Это уже в том же хаскеле есть, но писать на хаскеле завтипоподобный код всё равно больно, а доказывать, что ваша свеженаписанная монада на самом деле монада, а бинарные числа — на самом деле бинарные числа, и вовсе невозможно.

  9. snuk182
    /#22120640 / -1

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

    • devopg
      /#22121034 / -1

      да мне кажется останется уделом блокчейна

      • snuk182
        /#22121150 / +2

        Время еще не пришло
        Вообще остаются всего несколько незакрытых вопросов, мешающих языку войти в мейнстрим, и все они ИМХО связаны с переиспользованием кода — динамическая диспетчеризация в кругах растеров штука немодная, ею просто никто не занимается (хотя ее регулярно спрашивают), на расширение структур данных и вовсе смотрят как на врага, так что приходится колхозить ансейфы, NLL работают раз через три, приходится либо копипастить, либо воевать с сигнатурами методов. Остальной язык несложный и отлично дисциплинирует.

    • freecoder_xx
      /#22134772

      Я думаю первостепенное значение играет количество и качество имеющихся библиотек в экосистеме, поэтому для Rust важно, чтобы он был популярен в Open Source. Когда количество библиотек перевалит за критическую черту, бизнесу станет выгодно его использовать. А если так, то становятся важны в первую очередь те качества, которые могут способствовать распространению Rust в среде свободного, а не коммерческого ПО.

  10. Gryphon88
    /#22121422

    Вот читаю я про мощные, концептуальные и лаконичные языки, и встаёт такой холиварный вопрос: представьте, что можно отправить в 1970й спецификацию, учебник и компиляторы (self-hosted и на ассемблере) любого современного языка в виде распечаток. Какой бы Вы выбрали, чтобы история CS развивалась гармоничнее?

    • kozar
      /#22121734

      Как разрабочик для веба, я бы отправил спецификацию ES6 в 1995 :) А если серьёзно, то python, хотя бы без спецификации, а только Zen of Python. Хотя для прода и не писал на пайтоне, зеном руководствуюсь, и жалею, что другие — нет.

    • mayorovp
      /#22121936

      Rust, Haskell и Powershell. Без компиляторов (их там всё равно никто не потянет), только документацию.


      Rust — чтобы продемонстрировать, что переменная после перемещения должна становиться недоступной, а не содержать мусорные данные.


      Haskell — чтобы объяснить, что ФП — это не куча скобочек, а более глубокая концепция.


      Powershell — чтобы показать как должен выглядеть истинный unix way… и что может родиться если шеллы не будут следовать ему изначально.

      • Gryphon88
        /#22122122

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

      • Antervis
        /#22122636

        Powershell — чтобы показать как должен выглядеть истинный unix way… и что может родиться если шеллы не будут следовать ему изначально.
        unix-way это в первую очередь про совместимость. Сделать очередное проприетарное решение на замену стандартного — вот ни разу не unix-way

        • mayorovp
          /#22122668

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


          Разумеется, под "похожестью" я понимаю объектный конвейер, а не жуткие многословные команды.

          • AnthonyMikh
            /#22123578

            А почему тогда не nushell?

            • mayorovp
              /#22123722

              Потому что он недоделан ещё. Но можно и nushell, идейной разницы нет.

          • Antervis
            /#22124312 / -1

            Разумеется, под «похожестью» я понимаю объектный конвейер, а не жуткие многословные команды.
            конвеер из многословно описываемых объектов или жуткие многословные команды, хм, я даже не знаю что выбрать…

            Насколько я осведомлен, пош неплох как инструмент для виндовых сисадминов. Чтобы стать заменой баша, альтернатива должна быть открытой, кроссплатформенной и стандартизованной.