Разработчики Rust прошли долгий путь и 15 мая ожидается выпуск первой версии языка с вечеринкой по случаю новорожденного. Лично я долго ждал этого события, хотя и вызывает оно довольно смешанные чувства. Вроде что-то и родилось, но хочу ли я это что-то использовать и стоит ли оно того? Вот в чем вопрос. Дело в том, что в процессе развития Rust претерпел довольно сильные изменения и теперь это далеко не тот же язык, о котором я писал в 2013
Как бы много изменений не претерпел язык, ряд основных заложенный в него концепций так никуда и не делся. Как и любой C/C++ разработчик я постоянно сталкивался с проблемами в области управления памятью и первое что меня привлекло в Rust несколько лет назад была его идея разделения памяти по пулам с контролем за использованием и передачей объектов на этапе компиляции. К счастью данный механизм из Rust никуда не делся, а только несколько заматерел и обрел форму.
Так же нельзя не отметить используемую модель CSP для взаимодействия между Задачами Rust. Решение получилось практичное и удобное в использовании, само собой куда более низкоуровневое если сравнивать с AKKA из Scala, но для языка системного уровня самое оно.
Говорить про синтаксис и синтаксический сахар я, наверное, не буду. Любой новый современный язык программирования включает в себя множество вещей упрощающих жизнь разработчикам, и Rust не стал исключением в данном вопросе.
Отрицательное
Но не обошлось и без ложки дегтя. Дело в том, что разработчики не осилили зеленые потоки и асинхронную сеть. С учетом того, что язык часто преподносился как Erlang, которые еще и компилируетсая, то выглядит это очень грустно. Официальная позиция по зеленым потокам – используемый для их построения libuv слишком медленный из за большого количества преаллокаций памяти. Хотя больше это похоже на то, что релиз выпускать надо (ну не дело же язык 5 лет пилить) и не критические фичи идут под нож.
Кроме того, у меня серьезные сомнения относительно наличия в языке ключевого слова unsafe и шареной памяти как в RO, так и в RW вариантах. С одной стороны причины их появления понятны и логичны “мы строим язык который не уступит C++ в скорости”. С другой стороны, если ты оставляешь лазейки, то вся красивая и логичная модель, защищающая от ошибок идет под откос. Есть возможность обойти и сделать по старинке? Так и сделаем именно этим способом! Зачем разбираться с чем-то новым? Именно так выглядят изрядное количество вопросов посвященных Rust.
И последний пункт – усложнение языка. По моим ощущениям он все больше и больше начинает напоминать C++ с точки зрения синтаксиса. Множество шаблонов и интерфейсов, разлапистые описания типов (особенно при создании объектов не на стеке), множество макросов. Но C++ уже 30 лет как живет и зачем нужен еще один?
Итого
Несмотря на то, что, казалось бы, язык готов к промышленному использованию у меня есть некоторые сомнения в его целесообразности. В своем текущем виде язык не имеет каких-то сколь нибудь серьезных преимуществ перед C++14. Само собой язык будет развиваться и дальше, но с учетом того, что C++17 не за горами, сказать что данная ситуация изменится в будущем тоже не получается.
И, как это не печально, но для меня размышления на тему выбора языка программирования для нового проекта так и не потеряли своей актуальности. Ничего проще и более подходящего для больших и критичных к производительности проектов кроме C++ как не было, так и не ожидается в ближайшем времени.
Для меня зелёные потоки были большим красным минусом. Во-первых они мне в принципе не нравятся. Кривая абстракция. Во-вторых сложный рантайм очень сильно усложняет взаимодействие. Это как использовать Java-метод из C++. Теоретически можно, но практически проще переписать. Сейчас Rust-овская функция это обычная функция, которую можно просто дёрнуть откуда угодно, не заботясь о рантайме, потоках и тд.
Для быстрого асинхронного IO всегда есть родные средства ОС и есть неплохая обёртка mio над ними.
Про усложнение языка я не согласен. Я язык изучал совсем немного (денёк почитал официальную книжку), но при этом сколько ни лазил в стандартную библиотеку — всегда всё понимал. В C++ и Scala, например, у меня это не всегда получалось.
Здравствуйте, vsb, Вы писали:
vsb>Про усложнение языка я не согласен. Я язык изучал совсем немного (денёк почитал официальную книжку), но при этом сколько ни лазил в стандартную библиотеку — всегда всё понимал. В C++ и Scala, например, у меня это не всегда получалось.
Вопрос на засыпку — что делает вот этот макрос: https://github.com/gfx-rs/gfx_macros/blob/master/src/shader_param.rs ?
Со сложностью, в принципе, не всё так плохо. Но вот уход в процедурные макросы ("compiler extensions") и прочие края — это уже верная смерть для языка. А ещё ведь хотят добавить и HKT — вообще полная Скала получится.
Здравствуйте, Cyberax, Вы писали:
vsb>>Про усложнение языка я не согласен. Я язык изучал совсем немного (денёк почитал официальную книжку), но при этом сколько ни лазил в стандартную библиотеку — всегда всё понимал. В C++ и Scala, например, у меня это не всегда получалось. C>Вопрос на засыпку — что делает вот этот макрос: https://github.com/gfx-rs/gfx_macros/blob/master/src/shader_param.rs ?
Не скажу, плагины к компилятору пока не доводилось писать.
А где эти штуки реализованы лучше? Как на C++ такое реализовать?
Ну и в конце концов это библиотека. Хотя и лучше, чтобы она была читаема всем, но по сути достаточно, чтобы авторы и контрибьюторы могли её пониамть, а для пользователей важно, чтобы использовать было просто.
C>Со сложностью, в принципе, не всё так плохо. Но вот уход в процедурные макросы ("compiler extensions") и прочие края — это уже верная смерть для языка.
Не так часто они встречаются по-моему. Простые макросы уж точно не сложнее, чем в C. Сложные — ну не надо их писать. Метапрограммирование опасная штука, но это не значит, что его надо намеренно усложнять.
Тут ещё нормальной IDE не хватает. Взять и развернуть макрос и всё станет понятным, имхо.
C>А ещё ведь хотят добавить и HKT — вообще полная Скала получится.
В этом я нифига не понимаю, но вроде штука полезная же. Хотя я бы предпочёл, чтобы они сконцентрировались на качестве компилятора после релиза, а фичи пусть потихоньку вызревают.
Здравствуйте, vsb, Вы писали:
vsb>Не так часто они встречаются по-моему. Простые макросы уж точно не сложнее, чем в C. Сложные — ну не надо их писать. Метапрограммирование опасная штука, но это не значит, что его надо намеренно усложнять.
Я подчеркнул главное. Сложные – ну не надо писать. unsafe – ну не надо использовать. Шаренная память – ну используйте отправку сообщений вместо. При этом доподлинно известно, что если что-то можно сделать через жопу, то очень многие разработчики выберут именно этот путь. А потом уже будет "теория разбитых окон" в действии. На C++ годами, даже скорее десятилетиями, вырабатывали правильный подход к разработке. А в случае с новым языком, будут сплошной поход по граблям, благо грабли разложены и готовы к работе
Здравствуйте, kaa.python, Вы писали:
KP>Я подчеркнул главное. Сложные – ну не надо писать. unsafe – ну не надо использовать. Шаренная память – ну используйте отправку сообщений вместо.
А если я хочу именно шаренную память — мне Rust поможет?
Здравствуйте, jazzer, Вы писали:
KP>>Я подчеркнул главное. Сложные – ну не надо писать. unsafe – ну не надо использовать. Шаренная память – ну используйте отправку сообщений вместо. J>А если я хочу именно шаренную память — мне Rust поможет?
Вполне, есть примитивы для разного вида блокировок. Внутри они как раз через unsafe и реализованы, но для прикладного кода это не важно, так как интерфейс у них гарантирует безопасное использование. По крайней мере, для стандартной библиотеки.
Здравствуйте, jazzer, Вы писали:
J>А если я хочу именно шаренную память — мне Rust поможет?
Я не совсем понимаю, какой именно помощи ты ожидаешь. В целом, язык хороший, но не сказать что предложит на много больше безопасности в разработке, чем дает тебе C++ в текущем его состоянии. Интересные концепции в языке сохранились, просто модель защиты поехала из за шареной памяти и unsafe.
В итоге, трата времени в его изучение мне не кажется выгодным вложением как минимум на данный момент. Но, опять таки, все зависит от задач.
Здравствуйте, Cyberax, Вы писали:
C>Со сложностью, в принципе, не всё так плохо. Но вот уход в процедурные макросы ("compiler extensions") и прочие края — это уже верная смерть для языка.
Почему смерть? Это ведь не хуже того, что в С++ на шаблонах пишут. Да и никто не заставляет макросы на каждый чих писать.
Впрочем, бегло читать растовые макросы я так и не научился, хотя и делал несколько подходов.
Сайт http://www.rust-lang.org/ встречает нас длинным списком преимуществ данного языка следующего содержания:
zero-cost abstractions
move semantics
guaranteed memory safety
threads without data races
trait-based generics
pattern matching
type inference
minimal runtime
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Ну а если серьезно, то Rust мне напоминает этакого франкенштейна с крайне туманными перспективами. Сдается мне, что Rust окажется этаким новым D. Я не вижу никаких основополагающих принципов, способных сделать из кучки разноплановых фич (по большей части уже в лучшем виде реализованных в других языках) под новым соусом синтаксисом нечто большее. Как C/C++ разработчик, я могу сказать, что наличие в языке встроенных умных указателей меня вовсе не прельщает. Ведь память — это далеко не единственный ресурс, а умные указатели — не единственный способ контроля за памятью. В Rust к тому же все равно придется иметь дело с зоопарком С/С++ библиотек и системных API, о порядке владения сущностями из которых компилятор не будет иметь ни малейшего понятия, а никаких средств для описания такого рода вещей язык не предусматривает.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Здравствуйте, kaa.python, Вы писали:
KP>Кроме того, у меня серьезные сомнения относительно наличия в языке ключевого слова unsafe и шареной памяти как в RO, так и в RW вариантах.
Ну шареная память — ладно, но unsafe чем не угодил? Имхо, совсем без этого язык был бы никому не нужен. Ведь даже FFI через unsafe делается и это выглядит вполне логично.
Меня больше другое напрягает. Недавно обнаружили, что в безопасном коде можно потерять вызов деструктора — задействовав Rc и Cell. Неприятно, но мне больше не нравится как они решили это "исправить": функцию forget, которая как раз заставляет не вызывать деструктор и которая была unsafe, хотят объявить безопасной.
Здравствуйте, DarkEld3r, Вы писали:
DE>Ну шареная память — ладно, но unsafe чем не угодил? Имхо, совсем без этого язык был бы никому не нужен. Ведь даже FFI через unsafe делается и это выглядит вполне логично.
Тем же, чем и шареная память – фактом своего существования. Это крайне не безопасная конструкция, которая дается в использование любому желающему. И само собой найдется куча желающий воспользоваться этой конструкцией только для того, что бы написать как привыкли. Благодаря наличию шареной памяти и unsafe Rust мало чем отличается от того-же C++. Rust предоставляет кучу дополнительных возможностей выстрелить себе в ногу в самом неожиданном месте причем проигрывая по скорости С++ в 2-3 раза и заставляя писать столько же кода в общем случае
В итоге выходит, что для использования в критических к скорости исполнения задачах язык еще медленный, а для написания универсального более-менее быстрого кода такой же как C++, только с отличным синтаксисом, который еще учить надо.
Здравствуйте, VTT, Вы писали:
VTT>по большей части уже в лучшем виде реализованных в других языках
Вот только многие из этих языков подходят как замена С++?
VTT>что наличие в языке встроенных умных указателей меня вовсе не прельщает.
Что значит встроенных? Они не больше "встроены", чем в С++ — так же находятся в стандартной библиотеке.
VTT>Ну а если серьезно, то Rust мне напоминает этакого франкенштейна с крайне туманными перспективами.
В С++ многое из этого уже притащили или планируют плюс ещё приходится старое для совместимости тащить, так что "франкенштейн" — это как раз не раст. Новые языки могут позволить себе более аккуратно фичи реализовать, с оглядкой на прошлый опыт. Разумеется, это идёт в комплекте с отсутствием библиотек, готовых инструментов и т.д.
Впрочем, с инструментами у раста не всё так плохо. Скажем, для С++ так и нет и вряд ли будет общая система сборки или "менеджер пакетов". В расте оно идёт из коробки. В С++ такие вещи исторически идут отдельно и их много разных.
Лично мне раст нравится пока что: неплохой синтаксис и удобные возможности вроде паттерн-матчинга. Ну и главная его фича, имхо, borrow checker. Впрочем, активно язык не применял.
Здравствуйте, DarkEld3r, Вы писали:
DE>Лично мне раст нравится пока что: неплохой синтаксис и удобные возможности вроде паттерн-матчинга. Ну и главная его фича, имхо, borrow checker. Впрочем, активно язык не применял.
Главная фича, из тех "что не выкинули". Но благодаря всемогущему unsafe её крайне легко похерить.
KP>Тем же, чем и шареная память – фактом своего существования. Это крайне не безопасная конструкция, которая дается в использование любому желающему. И само собой найдется куча желающий воспользоваться этой конструкцией только для того, что бы написать как привыкли.
А разве есть вообще практические языки без такой возможности? Всегда есть или аналог ансейфа или возможность сишные функции дёргать, что приводит к тому же результату. Но почему-то я не видел жалоб на шарп или джаву, что они ничего не гарантируют раз там можно позвать С код и расстрелять память.
Насчёт "кучи желающих" — мне кажется, что это какая-то страшилка. Говнокод, в том числе опасный, можно писать на любом языке. Ансейв, по моему, как раз удобен тем, что его легче заметить. В том числе, на ревью.
Можно было бы посмотреть проекты хотя бы на гитхабе, но лень, честно говорят. Хотя и интересно насколько такие опасения оправданы. В любом случае, меня больше заботит практическая сторона: с ансейфом можно писать безопасные абстракции, которые язык не предоставляет. Без него оставалось бы только ждать пока это реализуют разработчики языка.
KP>Rust предоставляет кучу дополнительных возможностей выстрелить себе в ногу в самом неожиданном месте
Это с ансейфом или без? Хотелось бы примеры посмотреть. Мне как раз показалось, что без ансейфа таких мест заметно меньше, чем в С++.
Здравствуйте, kaa.python, Вы писали:
KP>Главная фича, из тех "что не выкинули". Но благодаря всемогущему unsafe её крайне легко похерить.
Я тоже давно следил за языком и периодически изменения изначально расстраивали. Но после чтения их аргументации, как правило, соглашался с доводами. Скажем, по зелёным потокам особо не грущу. По моему, язык всё-таки чаще преподносится как "безопасный С/С++" — с этой точки зрения всё правильно сделали.
Здравствуйте, kaa.python, Вы писали:
KP>Rust предоставляет кучу дополнительных возможностей выстрелить себе в ногу в самом неожиданном месте причем проигрывая по скорости С++ в 2-3 раза и заставляя писать столько же кода в общем случае
Эээ... А почему?
Rust должен уметь работать со скоростью примерно равной или превосходящей С++. Это не считая нескольких проблемных вещей типа zeroing drop, которые в следующей версии удалят.