Rust и Я

У меня, как наверное и у многих других C++ разработчиков какие-то сложные отношения с Rust. Этот язык вроде как и очень сильно нравится и в то же время всё сложно. На сей раз моя попытка заняться Rust в серьез зашла куда дальше чем обычно (обычно я после нескольких небольших тестиков удовлетворенно забрасывал изучение) – я нашел компанию которой нужны Rust разработчики, связался с ними и взял тестовое задание. Тестовое задание просто восхитительное, не сложное, но помогает понять главное – хочешь ли ты связываться с языком или нет?

На тестовое задание я честно потратил часов 8 и за это время успел заглянуть в tokio, которая, как я понимаю, является образцово-показательной библиотекой для написания асинхронных сетевых приложений. Честно говоря, я до сих пор в состоянии смятении, но точно знаю одно – видеть такое и не дай бог поддерживать на постоянной основе я точно не хочу. К примеру, вот кусок кода, который читает данные из канала и шлет их по TCP:

Box::new(tcp.map(move |stream| {
    let (sink, stream) = stream.framed(Bytes).split();
    pool.execute(stdin.forward(sink).then(|result| {
        if let Err(e) = result {
            panic!("failed to write to socket: {}", e)
        }
        Ok(())
    })).unwrap();
    stream
}).flatten_stream())

Несколькими месяцами раньше я баловался с биндингами к libClang, где было всё читабельно и очевидно, что наводит на мысли, что написать на Rust можно писать как в адекватном и легко поддерживаемом стиле, так и городить write-only код в духе приведенного выше. И надо отметить что в примере выше чувствуется и стиль и задумка. Если в него какое-то время повтыкать (желательно в IDE с навигацией, очень рекомендую IntelliJ Rust), то становится понятно что хотел сказать автор и почему. Только вот “НУ ЗАЧЕМ?!?!” не покидает.

В итоге мне в очередной раз стало казаться, что за пределами небольших сообществ гиков Rust взлететь не может, так как поддерживать столь неочевидные решения должно быть даже дороже чем решения на C++ с ручным управлением памятью (в конце концов, санитайзерами можно отловить практически всё). Не знаю чем это вызвано, скорей всего тем, что Rust развивает комьюнити гиков, а C++ комитет старперов. В результате в Rust тянут все, что круто выглядит, а в C++ только то, что “мегамозги” одобрили. Побочным эффектом этого выступает то, что в Rust многие удобные вещи доступны сразу или почти сразу, а в C++ это “наверное будет реализовано после C++20” (да-да, это я про Meta).

Наверное, меня всё равно не отпустит и баловаться с Rust я не перестану. Но вот подаваться на позицию “Rust разработчик” я довольно долгое время точно не буду, сообщество должно наиграться в “zero cost abstractions” для начала

7 Comments Rust и Я

    1. Alexander Stavonin

      Слишком большое количество разнородных действий в одной строке. Такое очень тяжело поддерживать.

      Reply
  1. ct0r

    >> можно писать как в адекватном и легко поддерживаемом стиле, так и городить write-only код в
    духе приведенного выше
    То ли дело на С++, там можно еще к этому парочку UB добавить, чтобы поддерживать было еще проще

    >> так как поддерживать столь неочевидные решения должно быть даже дороже чем решения на C++ с ручным управлением памятью
    Такое ощущение, что решения на С++ все сплошь очевидны. Какое-то странное сравнение.

    >> в конце концов, санитайзерами можно отловить практически всё
    До сих пор ловят. Почему-то не могут покрыть санитайзерами все 100% путей выполнения кода. Или проверять без сильной потери производительности и большого потребления памяти. Или одновременно запускать адресный с тредовым.
    И уж точно ни в одной доке к санитайзерам нету секции Limitations
    “Практически все” – слишком сильно сказано.

    Reply
    1. Alexander Stavonin

      > То ли дело на С++, там можно еще к этому парочку UB добавить

      ubsan

      >Такое ощущение, что решения на С++ все сплошь очевидны.

      Странное ощущение. В C++ есть устоявшиеся практики на тему “хорошо и плохо”, в Rust их пока что нет. И вот то чудище, что я привел вышел, вполне себе лежит в одной из основных библиотек языка.

      > “Практически все” – слишком сильно сказано.

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

      Reply
  2. ct0r

    >> В C++ есть устоявшиеся практики на тему “хорошо и плохо”, в Rust их пока что нет.
    Пока мне видится наоборот. Что ни проект, то свои правила. Недаром наверное пилится C++ Core Guidelines? И то, на него многие положат с пробором, я уверен. Да и не везде оно помогает.
    Куда не влезть, то либо самопальная или эзотерическая система сборки, то ужасные косячные cmake листы. Хоть сейчас какие-то сдвиги в best practices к cmake есть, уже хлеб.
    Шаблоны до сих пор: одни хейтят, другие упиваются (да что там шаблоны, даже макросы!). Где что разумно заюзать, это дискуссия же на неделю.
    Обработка ошибок – кто на что горазд. Исключения std и boost, коды ошибок с nodiscard атрибутами, optional, теперь еще и expected в бусте, все смешать и подавать горячим.
    Кто впихивает всякие наследования куда ни попадя, кто избегает их аки чумы.
    Для кого буст грааль священный, для кого отстой тормозной (более того, встречал всякие мнения и про стл).
    Продолжать можно еще и еще.
    Да практически любую тему взять, исключая явное отстреливание выступающих частей (это что-ли практики на тему “хорошо и плохо”?), найдется два лагеря плюсистов, думающих диаметрально противоположно.

    >> И вот то чудище, что я привел вышел, вполне себе лежит в одной из основных библиотек языка.
    Так какая конкретно С++ практика из “хорошо и плохо” мешает написать аналогично?
    Более того, на конфах плюсовых вроде такой код наоборот, считался бы образцовым. Могу тут конечно ошибаться.
    И еще уверен, что если буст ты можешь поддержать одной левой, то и с этим справишься.

    >> Нормально сказано, если пользоваться версией языка 11 и выше.
    Я уже привел примеры. Если для кого-то это практически все, – ну окей.

    Reply

Leave a Reply