Как вы думаете, почему в одной большой и в нашей стране хорошо известной компании почти половина всей кодовой базы — это C++, хотя основной язык — Java? Подумайте над этим, а то окажется, что ваши представления о стоимости производительных решений на Java не вполне адекватны, а вы и не знаете.
Теперь, вы пробовали писать многопоточный код на Java? А управлять ресурсами в многопоточном коде? В Rust компилятор защищает от большинства проблем многопоточности, чего хватает в 90% случаев. Управление ресурсами — элементарное, точно такое же, как и общее управление памятью. Вот посмотрите неплохой доклад о некоторых проблемах управления ресурсами в Java: https://youtu.be/K5IctLPem0c В Rust таких проблем нет.
Что касается типизации — я вообще не понимаю, как человек, имеющий хоть какой-то опыт enterprise-разработки может сомневаться в ее полезности? Ну да, давайте сэкономим на проектировании абстракций, слабаем императивную лапшу и остаток жизни будем чинить вечные баги, так что ли? К слову, и на Rust можно писать лапшу, только делать это труднее.
Опять же, чем лучше контроль типов — тем проще код дорабатывать и рефакторить. Потому что компилятор больше проверок делает за вас, читаемость кода тут вообще не причем (хотя я не вижу проблем и с читаемостью: у меня были претензии к синтаксису Rust только до тех пор, пока я его не изучил в достаточной мере и не приобрел опыт работы с кодом на Rust).
Единственный реальный недостаток — это молодая, пока недостаточно развитая экосистема. Но, к счастью, не все компании желают только пользоваться свободными компонентами, но есть и те, кто готов вносить и свой вклад в их развитие.
Вот поддержу. Как-то надо было разобраться, как работает некоторая часть большого js-проекта — пришлось перелопатить чуть ли не половину проекта, чтобы понять, что конкретно делает и с какими данными работает одна функция. В Rust, конечно, сигнатуры обобщенных функция выглядят сильно перегруженнее и трудночитаемее js-овских, но время на осознание того, что делает код в этом месте они сокращают кардинально.
Если вы все будете писать словами — получится литературный текст, его как программу тоже будет тяжело читать. Будет также, как при расписывании математических теорем текстом.
Задача как-раз в том, чтобы найти баланс использования спецсимволов, ключевых слов и пользовательских идентификаторов (которые обычно всегда слова) с тем, чтобы улучшить восприятие кода и сократить его набор. То есть, если у вас написано:
New tuple equals begin first and second end.
То далеко не факт, что это лучше читается, чем
let tuple = (first, second);
Потому что программа — это не литературное произведение, это не текст, имитирующий последовательность звучащих слов речи, это — структурированные данные, отражающие работу некоторого алгоритма. И так уж получается, что спецсимволы зачастую предпочтительнее в качестве структурных разделителей и на их фоне пользовательские имена воспринимаются быстрее и вернее, если, конечно, они не однобуквенные.
так а макрос писать не нужно? Или разбираться в том что сгенерировано как оно работает?
Достаточно это сделать один раз при изучении того, как работает макрос. И то, это в сложных случаях, когда нет документации и если по контексту вызовов не понятно, как он работает.
Или точку останова поставить (если такое возможно).
Мне в своей более чем трехлетней практике использования Rust в разработке приходилось пользоваться отладчиком ровно один раз, и то для того, чтобы понять, как работает внешняя С-библиотека. Ни разу ни мне, ни моим знакомым и коллегам не приходилось отладчиком смотреть внутрь макроса.
Или если бы этот код написать без макроса — стал бы он намного лучше?
Почти всегда есть обходной путь. Не нравятся макросы — не используйте. Тот же actix-web имеет и API без макросов. Другое дело, что без них придется больше писать шаблонного кода, который в целом сильнее затрудняет чтение программы, чем декларативные атрибуты, например.
да и вообще — зачем пытаться писать веб на Rust? Понимаю что можно в теории, но это должен быть исключительный случай и в 99% случаев тупо не имеет смысла.
Но ведь web на Rust многие пишут! Я лично знаю несколько компаний, разрабатывающих свои веб-приложения на Rust.
Rust быстрый, абстракции у него либо бесплатные, либо очень дешевые. Для систем, работающих под нагрузкой — это важное качество. Далее, в Rust очень мощная система типов для в целом императивного языка. Она позволяет избежать массы проблем, всегда возникающих в больших проектах. Также дает возможность переложить на компилятор больше проверок логики, выраженной в системе типов. Опять же, из-за правил владения и системы типов очень просто писать многопоточный и асинхронный код. Инструментарий отлично развит, легко создавать модули и управлять зависимостями, простая и эффективная встроенная поддержка тестов, настраиваемый автоформаттер и много, много чего еще.
Эти преимущества настолько очевидны и столько раз уже были озвучены, что мне как-то странно, что у кого-то, кто следит за этой темой, еще возникают вопросы на этот счет.
Если вам нужен молоток — и только — то зачем вам Rust? Используйте C, его для ваших потребностей судя по всему должно хватить. А вот определение того, зачем в Rust такой широкий инструментарий и почему его следует применять в прикладной разработке, оставьте тем, кому он реально нужен в таком качестве.
Строго говоря, копенгагенская интерпретация — это не интерпретация вовсе. Это просто аппарат, который обобщает наблюдаемые экспериментальные данные.
Приведу аналогию: можно исследовать устройство часового механизма по отпечаткам, которые тот оставляет на стене после его размажжевания о нее. При этом строить вероятностый мат. аппарат о том, какая шестерня в каком оказывается месте и в какую сторону крутится. Но при этом реальность может быть как в точности соответствующей этому мат. аппарату и не более, так и гораздо шире, точнее и замысловатее, а мат. аппарат оказывается лишь описанием результатов весьма специфических экспериментов.
Так вот, те интерпретации, которые считают волновую функцию реальным физическим объектом — философски расписываются в своем субъективном идеализме, так как навязывают физическому миру наше текущее его восприятие.
Зачем в этой мастерской набор разных ключей, шуруповерт, дрель, тиски?.. То ли дело молоток! Им и гвозди, и шурупы прекрасно забиваются. Он предельно простой и его нужно держать всегда только в одной руке. Все эти переусложнения — ни к чему.
Та интерпретация квантовой механики, которая господствует сегодня в околонаучных, большей частью популярных, кругах — насквозь идеалистическая. Но она хорошо вписывается в общую идеологическую повестку современности. Детерминистические концепции сегодня не в почете, это порождения совсем другой философской позиции, которая не нуждается в гипотезе "свободной воли" и беспричинной случайности.
Вам Rust не дает никаких "новых удобств"? Чем же вы таким занимаетесь, что вам ни контроль времени жизни ссылок, ни единообразная работа с ресурсами с автоматическим их освобождением, ни мощная система типов с нулевым оверхедом, ни подконтрольная компилятору многопоточность, ни развитые средства метапрограммирования, ни прекрсный тулинг не дают никаких удобств?
Из того, что в std Rust хорошо все задокументировано, как вы делаете вывод, что код там не самодокументированный? По-вашему в дополнении к самодокументированному коду невозможно написать хорошую документацию?
Но цена этого — вы не можете использовать общие данные между потоками в safe Rust.
Это совершенно не верно. Как минимум можно использовать безопасные примитивы синхронизации. Также и без них можно шарить между потоками объект по статической ссылке.
Ну а если вы подразумеваете, что в конечном итоге все равно где-то "под капотом" будет вызываться unsafe — то да, без этого не обойдется ни одна сколь-либо значимая операция. Я не могу взять объект из Vec по индексу или проитерироваться по массиву с тем, чтобы не стриггерить какой-нибудь unsafe-код. Ну и что с того?
Ну, от "протекающего" unsafe никто не застрахован, поэтому сообщество всегда внимательно следит за тем, как небезопасный код в той или иной реализации перетекает в safe Rust. unsafe означает, что гарантии безопасности перекладываются с компилятора на программиста.
Внимание, еще раз: unsafe не означает отсутствие гарантий, он означает, что эти гарантии должен предоставить программист в отношении внешнего API, который внутри использует unsafe.
И пример с Actix тут скорее с положительной стороны характеризует подход Раста, так как сообщество добилось того, чтобы в популярной и важной для экоситемы библиотеке не было неправильного unsafe.
Rust нигде не скрывает такого своего подхода к безопасности, какие тут к нему претензии? Ах, компилятор не может полностью гарантировать безопасность кода, где происходит разыменование сырых указателей. А компилятор какого языка это может?
Сколько там в Расте? o_O
Так это только в Расте или еще в LLVM и сишных библиотеках, которые использует rustc?
Единообразное решение на все случаи вряд ли возможно. Как отличить ссылки, время жизни которых не больше времени жизни объекта на которые они указывают от тех, что предполагают продление времени жизни? Если вы возвращаете ссылку из функции, то это так и задумано и просто нужно продлить время жизни объекта или это ошибка?
Можно, конечно, навязать силой одну единственную схему управления памятью, но тогда язык перестанет быть универсальным. А если позволять пользоваться разными, то предстоит решить, какую лучше сделать по-умолчанию. Как часто в реальном коде вам действительно требуются Arc, Rc, Mutex и Box? В моем опыте прикладной разработки на Rust — они требуются намного реже, чем обычные & и &mut.
Да, сигнатуры обобщенных функций — одно из главных трудночитаемых мест в синаксисе Rust. И дело не только в синтаксисе, с ним могут помочь where-блоки. Дело в том, что плотность информации на строчку кода высока.
Сгенерированная документация у Rust тоже кликабельная. Часто проще посмотреть в документацию, потому что там для каждого типа приводится полный набор реализованных трейтов, все в одном месте.
Как вы думаете, почему в одной большой и в нашей стране хорошо известной компании почти половина всей кодовой базы — это C++, хотя основной язык — Java? Подумайте над этим, а то окажется, что ваши представления о стоимости производительных решений на Java не вполне адекватны, а вы и не знаете.
Теперь, вы пробовали писать многопоточный код на Java? А управлять ресурсами в многопоточном коде? В Rust компилятор защищает от большинства проблем многопоточности, чего хватает в 90% случаев. Управление ресурсами — элементарное, точно такое же, как и общее управление памятью. Вот посмотрите неплохой доклад о некоторых проблемах управления ресурсами в Java: https://youtu.be/K5IctLPem0c В Rust таких проблем нет.
Что касается типизации — я вообще не понимаю, как человек, имеющий хоть какой-то опыт enterprise-разработки может сомневаться в ее полезности? Ну да, давайте сэкономим на проектировании абстракций, слабаем императивную лапшу и остаток жизни будем чинить вечные баги, так что ли? К слову, и на Rust можно писать лапшу, только делать это труднее.
Опять же, чем лучше контроль типов — тем проще код дорабатывать и рефакторить. Потому что компилятор больше проверок делает за вас, читаемость кода тут вообще не причем (хотя я не вижу проблем и с читаемостью: у меня были претензии к синтаксису Rust только до тех пор, пока я его не изучил в достаточной мере и не приобрел опыт работы с кодом на Rust).
Единственный реальный недостаток — это молодая, пока недостаточно развитая экосистема. Но, к счастью, не все компании желают только пользоваться свободными компонентами, но есть и те, кто готов вносить и свой вклад в их развитие.
Вот поддержу. Как-то надо было разобраться, как работает некоторая часть большого js-проекта — пришлось перелопатить чуть ли не половину проекта, чтобы понять, что конкретно делает и с какими данными работает одна функция. В Rust, конечно, сигнатуры обобщенных функция выглядят сильно перегруженнее и трудночитаемее js-овских, но время на осознание того, что делает код в этом месте они сокращают кардинально.
Если вы все будете писать словами — получится литературный текст, его как программу тоже будет тяжело читать. Будет также, как при расписывании математических теорем текстом.
Задача как-раз в том, чтобы найти баланс использования спецсимволов, ключевых слов и пользовательских идентификаторов (которые обычно всегда слова) с тем, чтобы улучшить восприятие кода и сократить его набор. То есть, если у вас написано:
То далеко не факт, что это лучше читается, чем
Потому что программа — это не литературное произведение, это не текст, имитирующий последовательность звучащих слов речи, это — структурированные данные, отражающие работу некоторого алгоритма. И так уж получается, что спецсимволы зачастую предпочтительнее в качестве структурных разделителей и на их фоне пользовательские имена воспринимаются быстрее и вернее, если, конечно, они не однобуквенные.
Достаточно это сделать один раз при изучении того, как работает макрос. И то, это в сложных случаях, когда нет документации и если по контексту вызовов не понятно, как он работает.
Мне в своей более чем трехлетней практике использования Rust в разработке приходилось пользоваться отладчиком ровно один раз, и то для того, чтобы понять, как работает внешняя С-библиотека. Ни разу ни мне, ни моим знакомым и коллегам не приходилось отладчиком смотреть внутрь макроса.
Почти всегда есть обходной путь. Не нравятся макросы — не используйте. Тот же
actix-web
имеет и API без макросов. Другое дело, что без них придется больше писать шаблонного кода, который в целом сильнее затрудняет чтение программы, чем декларативные атрибуты, например.Но ведь web на Rust многие пишут! Я лично знаю несколько компаний, разрабатывающих свои веб-приложения на Rust.
Rust быстрый, абстракции у него либо бесплатные, либо очень дешевые. Для систем, работающих под нагрузкой — это важное качество. Далее, в Rust очень мощная система типов для в целом императивного языка. Она позволяет избежать массы проблем, всегда возникающих в больших проектах. Также дает возможность переложить на компилятор больше проверок логики, выраженной в системе типов. Опять же, из-за правил владения и системы типов очень просто писать многопоточный и асинхронный код. Инструментарий отлично развит, легко создавать модули и управлять зависимостями, простая и эффективная встроенная поддержка тестов, настраиваемый автоформаттер и много, много чего еще.
Эти преимущества настолько очевидны и столько раз уже были озвучены, что мне как-то странно, что у кого-то, кто следит за этой темой, еще возникают вопросы на этот счет.
Вот как это выглядит для программиста:
А то, что вы привели — результат кодогенерации.
А я не согласен: Что делает Rust универсальным языком программирования
Если вам нужен молоток — и только — то зачем вам Rust? Используйте C, его для ваших потребностей судя по всему должно хватить. А вот определение того, зачем в Rust такой широкий инструментарий и почему его следует применять в прикладной разработке, оставьте тем, кому он реально нужен в таком качестве.
Строго говоря, копенгагенская интерпретация — это не интерпретация вовсе. Это просто аппарат, который обобщает наблюдаемые экспериментальные данные.
Приведу аналогию: можно исследовать устройство часового механизма по отпечаткам, которые тот оставляет на стене после его размажжевания о нее. При этом строить вероятностый мат. аппарат о том, какая шестерня в каком оказывается месте и в какую сторону крутится. Но при этом реальность может быть как в точности соответствующей этому мат. аппарату и не более, так и гораздо шире, точнее и замысловатее, а мат. аппарат оказывается лишь описанием результатов весьма специфических экспериментов.
Так вот, те интерпретации, которые считают волновую функцию реальным физическим объектом — философски расписываются в своем субъективном идеализме, так как навязывают физическому миру наше текущее его восприятие.
Зачем в этой мастерской набор разных ключей, шуруповерт, дрель, тиски?.. То ли дело молоток! Им и гвозди, и шурупы прекрасно забиваются. Он предельно простой и его нужно держать всегда только в одной руке. Все эти переусложнения — ни к чему.
Весь окружающий мир есть плод моего воображения. Это всегда соответствует наблюдаемым мной данным.
Та интерпретация квантовой механики, которая господствует сегодня в околонаучных, большей частью популярных, кругах — насквозь идеалистическая. Но она хорошо вписывается в общую идеологическую повестку современности. Детерминистические концепции сегодня не в почете, это порождения совсем другой философской позиции, которая не нуждается в гипотезе "свободной воли" и беспричинной случайности.
Вам Rust не дает никаких "новых удобств"? Чем же вы таким занимаетесь, что вам ни контроль времени жизни ссылок, ни единообразная работа с ресурсами с автоматическим их освобождением, ни мощная система типов с нулевым оверхедом, ни подконтрольная компилятору многопоточность, ни развитые средства метапрограммирования, ни прекрсный тулинг не дают никаких удобств?
А зачем вам примитивы, если вас интересовал
Pin(&T)
. Для&T
DerefMut
не реализуется.https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=74a5a762501e2fadba60e5a729ae7729
Из того, что в std Rust хорошо все задокументировано, как вы делаете вывод, что код там не самодокументированный? По-вашему в дополнении к самодокументированному коду невозможно написать хорошую документацию?
В документации это прекрасно видно, метод
as_mut
присутствует только в impl-блоке для техP
, которые реализуютDerefMut
: https://doc.rust-lang.org/std/pin/struct.Pin.html#method.as_mutЭто совершенно не верно. Как минимум можно использовать безопасные примитивы синхронизации. Также и без них можно шарить между потоками объект по статической ссылке.
Ну а если вы подразумеваете, что в конечном итоге все равно где-то "под капотом" будет вызываться
unsafe
— то да, без этого не обойдется ни одна сколь-либо значимая операция. Я не могу взять объект изVec
по индексу или проитерироваться по массиву с тем, чтобы не стриггерить какой-нибудьunsafe
-код. Ну и что с того?Ну, от "протекающего"
unsafe
никто не застрахован, поэтому сообщество всегда внимательно следит за тем, как небезопасный код в той или иной реализации перетекает вsafe
Rust.unsafe
означает, что гарантии безопасности перекладываются с компилятора на программиста.Внимание, еще раз:
unsafe
не означает отсутствие гарантий, он означает, что эти гарантии должен предоставить программист в отношении внешнего API, который внутри используетunsafe
.И пример с Actix тут скорее с положительной стороны характеризует подход Раста, так как сообщество добилось того, чтобы в популярной и важной для экоситемы библиотеке не было неправильного
unsafe
.Rust нигде не скрывает такого своего подхода к безопасности, какие тут к нему претензии? Ах, компилятор не может полностью гарантировать безопасность кода, где происходит разыменование сырых указателей. А компилятор какого языка это может?
Так это только в Расте или еще в LLVM и сишных библиотеках, которые использует rustc?
Единообразное решение на все случаи вряд ли возможно. Как отличить ссылки, время жизни которых не больше времени жизни объекта на которые они указывают от тех, что предполагают продление времени жизни? Если вы возвращаете ссылку из функции, то это так и задумано и просто нужно продлить время жизни объекта или это ошибка?
Можно, конечно, навязать силой одну единственную схему управления памятью, но тогда язык перестанет быть универсальным. А если позволять пользоваться разными, то предстоит решить, какую лучше сделать по-умолчанию. Как часто в реальном коде вам действительно требуются
Arc
,Rc
,Mutex
иBox
? В моем опыте прикладной разработки на Rust — они требуются намного реже, чем обычные&
и&mut
.Да, сигнатуры обобщенных функций — одно из главных трудночитаемых мест в синаксисе Rust. И дело не только в синтаксисе, с ним могут помочь
where
-блоки. Дело в том, что плотность информации на строчку кода высока.Сгенерированная документация у Rust тоже кликабельная. Часто проще посмотреть в документацию, потому что там для каждого типа приводится полный набор реализованных трейтов, все в одном месте.
Сейчас все-таки ситуация меняется.