вторник, 10 апреля 2018 г.

[prog.flame] Недосказанное про Rust на C++ CoreHard Spring

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

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

Итак, с точки зрения программиста Rust меня не торкнул. Ну язык как язык. Жгучего желания на нем что-то разрабатывать не возникает. Да и вообще с желанием написать что-то на Rust-е не так все однозначно.

В чем достоинство Rust-а как языка программирования? В безопасности.

Но вот лично у меня нет насущной потребности взять более безопасный язык. Если бы я устал от постоянных сегфолтов, от гонок, от порчи памяти и прочих "прелестей" разработки на языках вроде C и C++, то тогда бы для меня Rust был бы глотком свежего воздуха, к которому бы я изо всех сил стремился бы. Но это совсем не так. Не потому, что у меня в С++ коде не случается ничего вышеперечисленного. Случается. Иногда. Время от времени. Но проблемой это не является. Уж не знаю почему, но не является. Соответственно, ценность главного преимущества Rust-а для меня лично оказывается сильно ниже, чем "в среднем по больнице".

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

Даже наличие Cargo в Rust-е не является для меня лично какой-то killer-feature. Т.е. созданные и проверенные за много лет собственные велосипеды в C++ позволяют себя чувствовать довольно комфортно и не сильно страдать от того, что в C++ нет де-факто стандартного менеджера зависимостей.

Т.е. я не вижу чего-то такого в Rust-е, чтобы меня однозначно подтолкнуло бы в его сторону. Да, там есть свои достоинства. Но ведь за них же придется платить. Очень специфическим синтаксисом. Отсутствием нормального ООП. Отсутствием шаблонов, которые могут параметризоваться скалярами. Отсутствием перегрузки функций. Отсутствием исключений. Наличием такой мощной штуки, как макросы (да, я из тех, кто считает, что мощная макросистема в языке служит лишь для того, чтобы компенсировать какие-то большие недостатки языка).

Но самое важное -- это очень верный афоризм Алана Перлиса: "Язык, который не меняет вашего стиля мышления, не стоит вашего внимания". Вот Rust не заставляет меня думать по другому. Pascal в свое время -- заставил. Переход на C++ и ООП -- заставил еще как. Знакомство с Ruby -- еще раз заставил. Попытки изучения Erlang, OCaml и Haskell -- так же сказались на том, как я думаю о программировании. А вот при штудировании Rust book-а ничего подобного не происходит. Т.е. Rust выглядит как хорошая и добротная компиляция вещей, которые уже давно были (я сейчас не про borrow checker говорю), но не как что-то, что заставляет тебя долго думать, а потом испытывать озарение "От оно как можно-то!"


А вот с точки зрения менеджера Rust выглядит сильно привлекательнее. Отмечу сперва достоинства Rust-а как технологии для разработки.

Во-первых, по опыту знаю, что с ростом размера команды в C++ проекте качество кода начинает падать. На C++ хорошо делать проекты небольшими командами из сильных разработчиков. А вот большие команды из хороших C++ программистов могут позволить разве что компании вроде Yandex-а, Wargaming-а и Kaspersky Lab. Тогда как с Rust-ом есть надежда, что при том же размере команды качество кода на Rust-е будет несколько получше. Сам язык этому способствует. Как за счет большего контроля, так и за счет кастрации (т.е. изъятия кучу полезных для разработчика вещей, см.выше).

Во-вторых, в Rust-е выполняется гораздо больше проверок в run-time, поэтому Rust обещает больший коэффициент спокойного сна, если придется разрабатывать что-то торчащее в Интернет. В С++ можно добиться того же, но это нужно будет делать вручную, да при этом еще и соблюдая известную дисциплину. Т.е. обойдется это дороже. Так что для написания каких-то нагруженных сервисов без сложной логики внутри, да еще и командой из нескольких десятков разработчиков, Rust и Go выглядят предпочтительнее, имхо, чем C++.

В-третьих, инфраструктура Rust-а. Она у него есть. В отличии от ;) Собственные велосипеды -- это не есть хорошо с точки зрения управления продуктом/проектом, т.к. эта штука жрет ресурсы, но не приносит денег. Поэтому от собственных велосипедов лучше бы перейти на использование инфраструктуры, поддержкой и развитием которой занимается кто-то другой.

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

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

С другой стороны, если у вас есть некоторая кодовая база на С++, то переход на использование Rust-а может привести к вопросу "а что делать с C++ным кодом?". Если C++ного кода много, скажем 500K строк и больше, вряд ли перед вами встанет вопрос о переписывании его на Rust. Тут у вас всего один вариант: поддерживать и то, и другое. Насколько это будет выгодно в долгосрочной перспективе? Не берусь судить, т.к. сам придерживаюсь мнения, что чем меньше языков в проекте, тем лучше.

Но вот если у вас 100K строк на С++. Или 250K строк. Или даже 350K, то перед вами возникнет соблазн: а давайте потихоньку перепишем старые С++ные куски на Rust. Ведь в долгосрочной перспективе это будет выгодно, образуется всего одна общая кодовая база, с которой работать будет проще. И вот тут, боюсь, начнутся основные сложности. Т.к. вряд ли получится просто так переписать C++ный код на Rust. Даже если это будет очень простой код на C++. Все равно просто так не получится. А уж если это будет навороченный код на "modern C++", то тут речь пойдет о том, чтобы на Rust-е не только переписать, но и перепроектировать. А это уже совсем другие трудозатраты.

В районе 2007-го года я всерьез хотел перейти с C++ на D. И одним из факторов, который мог сделать такой переход реальным было то, что некоторые куски C++ного кода можно было перевести в D только за счет небольшого изменения синтаксиса. Т.е. берешь какую-то C++ную программку или библиотечку, меняешь в ней некоторые ключевые слова или обозначения и у тебя оказывается уже D-шная программка. Вот с Rust-ом такое просто не пройдет.

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

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

Однако, самым важным вопросом на тему "Rust или не Rust" является вот какой вопрос: "А почему вообще вокруг Rust-а такой хайп?"

Ответ, на мой взгляд, кроется в том, что очень многие "наелись C++". Настолько "наелись", что готовы выбрать хоть Rust, лишь бы не сталкиваться с C++ (или C, что еще более понятно). Что означает, что сейчас в мире есть реальная потребность в низкоуровневом нативном языке программирования, который был бы проще и надежнее в использовании, чем уже давным давно существующие C, C++, Ada. И так уж получается, что на данный момент таковым оказывается разве что Rust. Отсюда и хайп вокруг него, не смотря на то, что Rust страшен как сама смерть ;)

Вот если бы появилось что-то вроде Rust-а, но с более похожим на C++ синтаксисом и набором возможностей (в том числе и в плане поддержки нормального ООП)... Вот это была бы бомба, имхо. Тогда как Rust -- это неизбежное зло. Такое же неизбежное зло, каким был C++ в конце 1980-х.

Комментариев нет: