Так уж получается, что в последний месяц работать получается немного, зато много думается о разном и разнообразом. В том числе о том, остается ли для C++ место под Солнцем в современном мире. И, если остается, то какое и где (гусарам молчать!).
Данный пост появился под влиянием нескольких факторов.
Как скоро C++20 станет доминирующим стандартом?
Во-первых, не так давно прошла информация о том, что новый стандарт C++20 окончательно сформирован и дело теперь только в завершении официальных процедур по его регистрации в качестве международного стандарта.
Появление C++20 -- это знаковое событие. Сравнимое с появлением в свое время C++11.
Только вот я не очень понимаю, положительный ли или отрицательный знак у этого события. Ибо, с одной строны, в C++20 появились важные фичи, которые сильно продвинули язык (лично я сходу могу выделить концепты, сопрограммы и spaceship operator). Но, с другой стороны, в язык добавили модули, к которым сам я отношусь негативно, т.к., на мой взгляд, модули разрушают существующую экосистему C++ (в частности на помоечку отправятся разные доморощенные build tool-ы) и очень резко (можно даже сказать бесповоротно) делят код на старый и новый.
В связи добавлением в C++ модулей я не очень представляю себе, как быстро произойдет массовый переход на C++20.
Если вспоминать долгий и мучительный переход с C++98/03 на C++11, который, кстати говоря, местами еще так и не завершился, то можно предположить, что потребуется лет 7-8 для того, чтобы C++20 стал доминировать среди прочих C++ных стандартов.
С другой стороны, ситуация с C++11 изначально была хуже, т.к. нормальную и полноценную поддержку C++11 в основных копиляторах пришлось ждать несколько лет. Кроме того, 10 лет назад народ был как-то посдержаннее, переход на C++11 происходил неспешно и осторожно. Тогда как на C++14 и, тем более, на C++17 разработчики стали переходить гораздо активнее, чем в свое время на C++11.
Кроме того, времена так же изменились. ИТ всегда развивался динамично. И за последние 10 лет скорость повления изменений только увеличилась. В частности, появились и развились такие конкуренты C++, как Go и Rust. Даже давние соперники, т.к. C# и Java, эволюционируют ой как резво.
Так что в 2020-х годах уже нет роскоши ждать 3-4 года, пока кто-то другой набъет шишек с новым стандартом C++, а компиляторы избавятся от детских ошибок, чтобы затем потратить еще несколько лет и перевести свою разработку на C++11 (или C++14). Сейчас если что-то может дать хоть какие-то бенефиты для разработки, то это нужно использовать "не отходя от кассы".
Поэтому 7-8 лет, скорее всего, являются пессиместической оценкой. А оптимистической может быть оценка в 2-4 года.
Тем не менее, на ближайшие несколько лет C++ сообщество подвергнется еще одному сегментированию: кто-то сможет перейти на C++20, а кто-то будет вынужден оставаться в рамках предшествующих стандартов (пусть даже это будет C++17). И такое сегментирование явно не пойдет на пользу C++ экосистеме, т.к. она так же будет разделена на инструменты, которые уже заточены под C++20 и которые нельзя будет применить в проектах со старыми стандартами C++.
Ну а разработчикам C++ных библиотек добавится геморроя. Т.к. если хочешь широкого использования своего инструмента, то придерживайся старых стандартов. А если хочешь повышения своей производительности и снижения собственных издержек, то переходи на C++20 и пользуйся концептами вместо SFINAE на шаблонах или spaceship operator вместо ручного расписывания операторов сравнения...
Страшно далеки они от народа?
Вторым фактором к написанию сего поста стала вот эта статья на Medium о разработке HTTP-тунеля на Rust: Writing a Modern HTTP(S) Tunnel in Rust.
Меня там больше всего поразили вовсе не возможности, которые доступны в Tokio из коробки. А обыденные вещи, которые становятся доступны разработчику на Rust за счет системы макросов Rust-а. В частности, вот как выглядит описание аргументов командной строки для http-tunel:
let matches = clap_app!(myapp => (name: "Simple HTTP(S) Tunnel") (version: "0.1.0") (author: "Eugene Retunsky") (about: "A simple HTTP(S) tunnel") (@arg CONFIG: --config +required +takes_value "Configuration file") (@arg BIND: --bind +required +takes_value "Bind address, e.g. 0.0.0.0:8443") (@subcommand http => (about: "Run the tunnel in HTTP mode") (version: "0.1.0") ) (@subcommand https => (about: "Run the tunnel in HTTPS mode") (version: "0.1.0") (@arg PKCS12: --pk +required +takes_value "pkcs12 filename") (@arg PASSWORD: --password +required +takes_value "Password for the pkcs12 file") ) ) .get_matches(); |
В свое время я пересмотрел ряд C++ных библиотек для работы с аргументами командной строки (не говоря уже про то, что сам велосипедил в доисторические времена). И ни одна из них не идет ни в какое сравнение по декларативности вот с этим фрагментом. Имхо, конечно же.
Другой пример из этой же статьи -- это работа с конфигурационным файлом посредством библиотеки serde:
#[derive(Deserialize, Clone)] pub struct TargetConnectionConfig { #[serde(with = "humantime_serde")] pub dns_cache_ttl: Duration, #[serde(with = "serde_regex")] pub allowed_targets: Regex, #[serde(with = "humantime_serde")] pub connect_timeout: Duration, pub relay_policy: RelayPolicy, } #[derive(Builder, Deserialize, Clone)] pub struct RelayPolicy { #[serde(with = "humantime_serde")] pub idle_timeout: Duration, /// Min bytes-per-minute (bpm) pub min_rate_bpm: u64, // Max bytes-per-second (bps) pub max_rate_bps: u64, } |
И этого описания достаточно для того, чтобы работать с YAML-овыми конфигами вида:
target_connection: dns_cache_ttl: 60s allowed_targets: "(?i)(wikipedia|rust-lang)\\.org:443$" connect_timeout: 10s relay_policy: idle_timeout: 10s min_rate_bpm: 1000 max_rate_bps: 10000 |
Конечно же, за конфиги в формате YAML или JSON (не говоря уже про XML) нужно отрывать руки, но суть же в том, что вместо YAML/JSON может быть и какой-то нормальный формат, а декларации в Rust-овом коде останутся в принципе такими же.
И что лично мне говорят эти примеры?
Они мне говорят о том, что не смотря на внесение принципиальных изменений в C++20 (будь то концепты, короутины, модули или spaceship operators), эти изменения никак не упрощают решение поседневных задач для рядового разработчика. Которому нужно аргументы командной строки распарсить, конфиг прочитать, запрос к БД сделать, по HTTP куда-то сходить. И т.д., и т.п.
Причем новый C++20 не то, чтобы очень уж сильно и принципиально упрощает разработку библиотек/фреймворков для решения этих повседневных задач.
Вот и получается, что C++20 движется куда-то семимильными шагами, а процесс адаптации новых возможностей C++ в "дикой природе" затянется лет на 5, но удобство применения C++ для решения повседневных и банальных задач смогут ощутить не только лишь все :(
С++ становится инструментом для Enterprise?
Третий фактор -- это мое личное ощущение, что C++ постепенно превращается в язык для больших проектов и больших команд. А вот небольшие команды или отдельные разработчики C++ используют все меньше и меньше.
Для себя я это объясняю двумя основными причинами:
- Высокий порог входа в C++. Например, когда у меня за плечами 28 лет работы с C++, я могу спокойно использовать C++ даже для того, чтобы быстро набросать какую-то утилитку для разового использования. Не говоря уже про то, чтобы с командой в 3-5 человек с нуля поднять проект в 250-300KLOC, который затем будет работать годами. Но, подозреваю, что старперов, вроде меня, с десятками лет плюсового опыта за плечами, не так уж и много. Молодежи и проще, и интереснее применять что-нибудь современное и модное, а не бодаться с C++, к которому сейчас отношение такое же, как во времена моей молодости к Fortran и COBOL.
- Своеобразная экосистема и инфраструктура. Вроде бы всего навалом, но нужно потратить кучу времени и сил для того, чтобы из этого многообразия отобрать то, что тебе нужно, и заставить все это собираться в твоем проекте. Опять же, если за плечами большой опыт, то подобрать сторонние библиотеки для новой разработки не так уж и сложно. Просто уже знаешь где, что и почем. А вот если у тебя этого опыта нет?
Добавлю, что такое состояние экосистемы и инфраструктуры C++ не является сколько-нибудь серьезной проблемой для больших проектов с длинной историей развития, в которых своих велосипедов используется едва ли не больше, чем сторонних библиотек.
Посему мне кажется, что чем дальше, чем более энтерпрайзным инструментом становится C++. А это плохо тем, что наш stiffstream -- это совсем маленькая компания, чьими услугами пользуются небольшие/некрупные заказчики. Но чем меньше C++ востребован небольшими коллективами разработчиков, тем меньше нужны и наши услуги.
Ну и, соответственно, все более актуальным становится вопрос о том, а имеет ли смысл продолжать вкладываться в C++, если на этом рынке для мелких игроков все меньше и меньше места?
Вместо заключения
C++ активно развивается и это хорошо. Никуда C++ в ближайшее время не исчезнет.
Но вот есть ли смысл вкладываться в C++ в современных условиях, если ты не Yandex, Intel, Facebook или Google?
А вот хз. Сейчас я в положительном ответе на этот вопрос уже далеко не уверен.
Конечно же, прямо сейчас все бросать и отказываться от C++ я не буду. Есть еще некие долги по нашим OpenSource-проектам, которые хочется закрыть, дабы не оставалось горькое ощущение "ведь была же возможность, но..." Чем я и планирую заниматься в течении ближайших двух-трех месяцев.
Ну а дальше будем посмотреть. Говорят, что за пределами C++ есть жизнь. И даже проекты, отличающие от формошлепства ;)
2 комментария:
Было бы круто вам поближе познакомиться с Rust, обкатать его на паре-тройке небольших проектов.
Лично я думаю, что Rust все еще сильно недооценен, поэтому его мало используют, а это значит что его время еще не пришло. Но через пару лет ситуация может измениться кардинально: язык очень быстро развивается. Если не смущает некоторая сырость экосистемы - то нужно начинать использовать Rust, я считаю. Более того, сырая экосистема для либописателей - это скорее плюс, так как есть еще возможность вскочить на подножку уходящего поезда, написать что-то крутое и стать стандартным выбором де-факто в своей нише.
Однако есть и риски: в пессимистичном сценарии Rust все еще может не взлететь и так и остаться маргинальным языком на долгие годы.
Но лично я сделал выбор в пользу Rust :)
Да clap вообще крутая либа (как и serde), очень мощная по функционалу и довольно легкая в использовании. Решает проблему консольных интерфейсов для утилит раз и навсегда.
Кстати, помимо макроса, в ней можно также задавать параметры в функциональном стиле и декларативном, подобно тому, как делается в serde, с помощью Derive-макроса: https://github.com/clap-rs/clap#using-derive-macros
Вот эти всевозможные Derive - это еще одна сильная сторона Раста. Супер удобно: прописал требуемый режим в атрибуте #[derive(...)] и не надо писать никакой реализации вручную.
Отправить комментарий