То, что начиналось как маленький побочный проект на ноутбуке одного разработчика — сегодня стало одним из самых успешных языков программирования с открытым исходным кодом, которым пользуются Microsoft, Amazon, Google, Tesla, Discord и многие другие.
Если кто не знает эту историю — велком.
Программисты славятся тем, что часто создают разные одноразовые решения для быстрого устранения возникших проблем или удовлетворения конкретных потребностей. Но случается и так, что решение, созданное под конкретную задачу, оказывается гораздо больше этой самой задачи. И остается актуальным, развивается и процветает даже спустя десятилетия.
Семнадцать лет назад программист из Mozilla Грейдон Хоар вернулся с работы и обнаружил, что лифт в его доме вышел из строя. Он был вынужден подниматься на двадцать первый этаж, проклиная всё на свете. А потом узнал, что лифт не работал из-за сбоя программного обеспечения. Тогда он решил попробовать сделать язык программирования, который сводил бы такие ошибки к нулю. Чтобы даже начинающий разработчик мог бы написать код, который не зависал.
Хоар выплеснул все свои разочарования в код и за несколько месяцев создал основу для простого и гибкого языка, рассчитанного на минимизацию ошибок памяти и предотвращение таких проблем, как поломка его лифта. Он назвал его Rust («ржавчина») — в честь ржавчинных грибов, славящихся своей выносливостью и способностью выживать в любых условиях.
Дело в том, что старые языки программирования, такие как C и C++ (которым больше сорока лет), имеют характерные недостатки. С одной стороны, они обеспечивают гибкость в плане разработки кода и дают в руки пользователя ряд инструментов, позволяющих создавать самые разные программы для чего угодно, от автомобилей и дефибрилляторов — до Windows и Android. Но с другой стороны — они требуют от разработчиков тщательного управления транзакциями памяти. Отсутствие учета состояния этих транзакций легко может привести к сбою или нестабильностям в работе приложения.
Чтобы облегчить бремя постоянного управления памятью, такие языки как Java представили концепцию «сборщиков мусора». Эти сборщики предназначены для периодической очистки системной памяти, сводя к минимуму риск ошибок памяти. Однако это происходит за счет более высокого общего использования памяти и большего потребления ресурсов системы — для постоянного поддержания работоспособности сборщиков.
Хоар попытался создать язык программирования, преодолевающий разрыв между двумя этими (как говорят, устаревшими) подходами к управлению памятью. И хотя его язык требует от разработчиков соблюдения довольно жестких правил кодирования, он самостоятельно управляет памятью, гарантируя, что любой написанный код будет безопасен в этом плане.
Ошибки типа переполнения буфера и выхода за пределы массива в языке стали невозможны в принципе. А ведь как раз подобные (человеческие) ошибки в языках с ручным управлением памятью типа С и С++ и приводили к самым опасным уязвимостям вроде удаленного выполнения кода.
Mozilla взяла Rust на вооружение и начала спонсировать проект в 2009 году — в рамках разработки экспериментального быстрого браузерного движка под названием Servo. Этот проект был официально анонсирован компанией в 2010-м. С тех пор язык Rust стал широко поддерживаемым проектом с открытым исходным кодом, используемым для всего, от ПО для лифтов — до масштабных приложений, решающих задачи масштаба Microsoft и Amazon.
К 2013 году сторонники языка усовершенствовали систему управления памятью Rust до такой степени, что она больше вообще не требовала функции сборщика мусора. Язык очень активно развивался и получал поддержку от разработчиков по всему миру, что привело к выпуску первого официального стабильного релиза Rust в мае 2015 года.
Народная любовь
В январе 2014 года главный редактор компьютерного журнала Dr. Dobb's Journal Эндрю Бинсток прокомментировал шансы Rust стать полновесным конкурентом C++. По словам Бинстока, хотя Rust «многие считают удивительно элегантным языком», его внедрение замедлилось, потому что он чересчур сильно менялся между версиями.
Но популярность Rust после его официального релиза в 2015 году росла фантастическими темпами. Несмотря на свою молодость, Rust быстро вошел в число самых популярных языков программирования. Например, в индексе сообщества программистов TIOBE в июле 2019 года он занимал 33-е место, а уже к июлю 2020 года поднялся на 18-е. Точно так же, согласно опросу разработчиков Stack Overflow, Rust является «самым любимым» языком опрошенных с 2016 года. Его любят 86% разработчиков, на втором месте — TypeScript с одобрением 67%, на третьем — Python с 66,7%.
В опросе Stack Overflow показывается процент тех, кто разрабатывает с помощью языка или технологии и выражает заинтересованность в продолжении разработки с их помощью
В результате многие программисты теперь видят в Rust серьезную альтернативу C и C++ даже в сферах, где эти языки доминировали. Дэйв Херман, соучредитель Mozilla Research, расписал некоторые из преимуществ языка в своем посте:
Что отличает Rust от всех других языков, так это сочетание низкоуровневого управления с бескомпромиссной безопасностью. При начале масштабного использования Rust мы обнаружили то, что эта комбинация дает невероятные стимулирующие эффекты, позволяя начинающим программистам погружаться на самые низкие уровни программирования и побуждая опытных системных программистов стремиться к более высоким уровням.
Что сейчас
В бизнес-мире на одной любви не прожить. А поскольку у Mozilla сейчас не самые лучшие времена, в том числе из-за давления со стороны Chrome и Edge, то и развитие нового языка оказалось под угрозой.
В августе 2020 года Mozilla уволила 250 из 1000 своих сотрудников в рамках корпоративной реструктуризации, вызванной пандемией. Команда разработчиков Servo, браузерного движка, написанного на Rust, была тогда полностью расформирована. Это вызвало обеспокоенность по поводу будущего Rust, поскольку члены команды вносили активный вклад в разработку и поддержку языка.
На следующей неделе основная команда Rust признала серьезные последствия увольнений и объявила о планах по созданию фонда поддержки Rust. Первой целью фонда было стать владельцем всех товарных знаков и доменных имен, относящихся к языку, и взять на себя финансовую ответственность за их стоимость.
8 февраля 2021 года пять компаний-основателей (AWS, Huawei, Google, Microsoft и Mozilla) объявили о создании Rust Foundation. В сообщении в блоге, опубликованном в апреле того же года, Google заявила о поддержке Rust в рамках Android Open Source Project в качестве альтернативы C и C++. Низкоуровневый код для Android теперь в самой Google пишется на Rust.
К 2022 году размер сообщества Rust увеличился втрое и превысил три миллиона пользователей. Его включили в рекомендованный Агентством национальной безопасности США список безопасных для памяти языков. Rust поставили в один ряд с другими хорошо зарекомендовавшими себя языками, такими как Java, C# и Ruby.
Сейчас использование Rust продолжает расти, особенно в автомобильной и аэрокосмической промышленности, где критически важно, чтобы ничего не сломалось. Язык также любят многие крупные ИТ-компании, включая Microsoft, Amazon и Dropbox. За счет этого использование Rust продолжает расти, уменьшая общую зависимость разработчиков от C и C++, которые считаются менее безопасными, особенно в руках неопытных программистов.
От программирования лифтов — к запуску космических ракет и электрокаров. Неплохо для «ржавчины».
По мотивам.
P.S. Хотите работать над крутыми проектами? Лучшие вакансии — в телеграм-боте getmatch. Тысячи предложений от топовых компаний. Указываете нужную вилку зарплаты, и бот выдает вам лучшие предложения, и помогает пройти интервью. Всё бесплатно.
Комментарии (48)
lain8dono
00.00.0000 00:00+7Кстати servo недавно ожил.
domix32
00.00.0000 00:00+3Не сказать, что он умирал. Оксидация FF имеет довольно неплохой план и servo его пророк.
lain8dono
00.00.0000 00:00+8Новости идут до 2020-11-17 и потом два обновления 2023-01-16 и 2023-02-03. Два года перерыва.
Halt
00.00.0000 00:00После очередного административного апокалипсиса в Мозилле, дело почти заглохло. Stylo впилили, парсер медиафайлов влили, WebRender влили уже года полтора назад, но все так не выберется.
Целиком Servo никто в FF тащить не будет.
ElVibrio
00.00.0000 00:00+29Интересно наблюдать, как мифологизация становится значимой частью Computer Science.
...когда был Торвальдс маленький, с кудрявой головой
Он тоже бегал в валенках по горке ледяной!
a14e
00.00.0000 00:00+6Возможно я не в курсе про какую-то концепцию. Но я не помню, чтобы в C/C++ было понятие транзакций памяти. Ссылка на статью в Вики про транзакционную память -- это совершенно другое понятие, которое к ручному менеджменту памяти имеет весьма опосредованное отношение
SergeyTatevosyan
00.00.0000 00:00+4Можно подумать что все ошибки при написании кода сводятся к ошибкам при работе с памятью. Это просто фишка языка, которая есть почти у любого другого языка.
DirectoriX
00.00.0000 00:00+5которая есть почти у любого другого языка
Эти «почти все» другие языки в основном обеспечивают безопасную работу с памятью через сборку мусора, что накладывает свои ограничения и создаёт свои проблемы. А в Rust — безопасная память через принудительное RAII.
RAII в некоторой степени помогает работать и другим фишкам языка, например fearless concurrency (при захвате мьютекса создаётся MutexGuard, который автоматически разрушается при выходе из области видимости, и вместе с этим разблокирует мьютекс).SergeyTatevosyan
00.00.0000 00:00+4вы меня не правильно поняли, я имел ввиду в принципе фишки отличающие один язык от другого. Просто в статье информацию преподнесли так, будто это панацея от всех проблем. Немного преувеличено как мне кажется.
mikhanoid
00.00.0000 00:00+3Будто подход Rust не накладывает своих ограничений и не создаёт проблем. Впорос только в том, какие ограничения удобнее, и какие проблемы менее болезнены.
DirectoriX
00.00.0000 00:00+2Дайте угадаю, вы опять хотите поведать о том, что в Rust без unsafe нельзя сделать базовые структуры данных, поэтому этот язык не пригоден для серьёзной разработки?
staticmain
00.00.0000 00:00+1Простите, но если сам язык создавался для того чтобы в нем не было небезопасных мест то факт того, что в нем нельзя создать двусвязный список без unsafe - это ужасно. И политика "говорящих голов", что двусвязные списки не нужны, потому что есть массивы - это показатель уровня разработчиков.
DirectoriX
00.00.0000 00:00+7Так всё дело в том, что «правильный» двусвязный список не ложится в концепцию владения, потому что у каждого узла получается два равноправных обладателя.
Но двусвязные списки всё же есть, причём в стандартной библиотеке. Да, под капотом у них unsafe, но публичный интерфейс полностью доступен из safe-подмножества. Можно долго спорить, считается это «честной» реализацией или нет, но тогда давайте не забывать, что где-то в глубине стека вызовов всё равно нет-нет, да и происходит обращение к ядру ОС, которое unsafe просто потому что FFI.staticmain
00.00.0000 00:00С этим никто не спорит, но ведь тогда нельзя говорить, что это безопасно, если под капотом все равно unsafe linux/windows ядро. На любом шаге может быть факап, начиная с ядра и заканчивая условным libxml2
DirectoriX
00.00.0000 00:00+3Именно так, полная безопасность недостижима, ведь даже если ПО будет без багов, то всё равно может произойти аппаратный сбой.
Но это не означает, что к безопасности и стабильности не надо стремиться. Те же языки со сборкой мусора (с которых +- начался этот тред) именно поэтому и появились: работать с памятью сложно.
unC0Rr
00.00.0000 00:00+8Если под капотом небезопасно, то это не значит, что язык не может выражать только безопасные (без багов памяти) конструкции. К примеру, мы ведь не думаем, как избегать сегфолтов, пиша запросы в SQL? SQL же не считается небезопасным языком только потому что под капотом движок, написанный на C++, и ОС на чёрт знает чём. И то, что на нижнем уровне небезопасные языки, не является причиной того, чтобы и в языке запросов были конструкции для низкоуровневой работы с памятью без проверки корректности.
morijndael
00.00.0000 00:00+6Андроид, Хром и Мозилла сходятся на цифре 70. 70% уязвимостей так или иначе вызвано ошибками в работе с памятью.
Во вторых, borrow-checker часто ловит в том числе логические ошибки
В третьих, не borrow-checker-ом единым! У раста очень много других фишек, помогающих писать надёжный код. Option/Result вместо исключений, требование полноты для match, и многое другое — вынуждает программиста думать о всех путях выполнения кода. В том числе, когда что-то идёт не по плану. Возможные ошибки видны как на ладони, и просвечивают через сигнатуры. И они все должны быть обработаны, чтобы программа прошла тайпчек
И, по моему субъективному опыту, писать крупную долгоиграющую систему намного приятнее, когда гарантировано знаешь, где она может посыпаться, а где не может
easimonenko
00.00.0000 00:00+4О чём эта статья?
OneMike
00.00.0000 00:00+2Велком - что-то про колбасу, наверное, но видел в тексте только про грибы...
MiraclePtr
00.00.0000 00:00+6Тогда он решил попробовать сделать язык программирования, который сводил бы такие ошибки к нулю.
А потом окажется, что программа ПЛК, управляющая лифтом, скорее всего написана на вообще каком-нибудь языке лестничной релейной логики, то вполне возможно что Rust проблему не решит :)
Чтобы даже начинающий разработчик мог бы написать код, который не зависал.
Учитывая порог вхождения, начинающий разработчик просто не напишет никакого кода. Нет кода - нет багов и зависаний, badum-tsss :)
LinearLeopard
00.00.0000 00:00+4https://llvm.org/devmtg/2014-10/Slides/Baker-CustomHardwareStateMachines.pdf
Вроде, есть способы генерировать код для FPGA на llvm, в который и компилируется rust.
Правда, FPGA и PLC разные устройства (кстати, насколько? не в теме), так что придётся немного и железо поменять в лифте, а раз уже меняется, то можно и arm воткнуть. Разумеется с k8s и метриками.MiraclePtr
00.00.0000 00:00+1кстати, насколько? не в теме
Совершенно разные.
ПЛК - это по сути дела или микроконтроллер или SoC, обвешанный модулями ввода-вывода (входные/выходные дискретные/релейные, аналоговые, частотные, RS232, RS485, и т.д.). На нем работает какая-нибудь RTOS или Linux, исполняющая либо скомпилированный бинарный, либо байт-код управляющей программы.LinearLeopard
00.00.0000 00:00Спасибо, а зачем на RTOS или Linux свой язык лестничной релейной логики. Кажется, можно написать на более привычном C? Я думал, там что-то на уровне отдельных транзисторов, а не SoC. Это не так?
MiraclePtr
00.00.0000 00:00+1Там не только Ladder, там целое семейство языков, которые обычно используются в ПЛК.
LD удобен для переноса в ПЛК систем автоматики, которые были построены на релейной логике. FBD - для переноса систем автоматики, которые были построены на цифровых дискретных микросхемах (там те же самые логические блоки, счётчики, компараторы, таймеры, триггеры, и т.д.). IL - что-то типа ассемблера байт-кода, ST - что-то типа сильно урезанного Паскаля.
Причины того, что именно эти языки выбрали в качестве индустриального стандарта прозаичны, основная идея этих языков в том, чтобы 1) можно было легко переносить старые существующие системы автоматики на новые рельсы; 2) программу мог писать и модифицировать не программист, а электронщик, КИПовец или вообще электрик, для которых подобные графические схемв гораздо понятнее и привычнее, чем Си; 3) было минимум возможностей отстрелить себе ногу всяким неочевидным поведением (типа undefined behavior в Си). Я думаю, что возможно ещё была мысль о переносимости программ между ПЛК разных производителей, но по факту это практически невыполнимо, ибо языки-то общие, но каждый вендор что-то к ним досыпает от себя (хотя есть рантаймы, которые работают на разных ПЛК разных вендоров, например CoDeSyS, IsaGRAF). А ещё некоторые вендоры, кому не хватило денег на вышеупомянутые рантаймы и кому было лень/ниасилили написать свой рантайм, используют такую штуку как Beremiz, которая по сути дела является транслятором с МЭКовских языков в Си-код.
Так что да, самом деле, под некоторые ПЛК вполне можно писать сразу на C и C++. И некоторые даже пишут. Вот только многие заказчики такие проекты не любят и принимать такое не соглашаются. Так уж сложилось.
morijndael
00.00.0000 00:00Нет кода - нет багов и зависаний
Всё верно. Поэтому многие разработчики переходят на no-code
Chamie
00.00.0000 00:00+5С трудом уже сдерживаю желание вычислять по айпи и бить по голове тезаурусом
говнопереводчиков, использующих слово «кодировать» („encode“) для перевода слова, означающего «писать код»/«программировать».avril_rocks
00.00.0000 00:00В общем и целом – это одно и то же. Писать на естественном языке по мне – тоже кодирование
Chamie
00.00.0000 00:00+1Кодировать — это переводить входные данные в закодированные данные. Писать код и программировать — это совершенно другой процесс. Писать на естественном языке — это кодировать, да. Кодировать устную речь при помощи системы письменности. А вот придумывать, что написать — это, как и программирование, совершенно другая задача.
avril_rocks
00.00.0000 00:00-1В статье и употребляется "кодирование" в контексте "жестких правил", что исключает "придумывать, что написать".
Но по мне и придумывание так же можно называть кодированием, ведь в этом конечный результатChamie
00.00.0000 00:00+1Нет, в статье именно про то, что программа/алгоритм делает, а не то, как это записано. Правила записи на безопасность кода не слишком влияют, в отличие от требований учитывать владение переменной, обрабатывать исключения и прочего.
Solicitor
00.00.0000 00:00А потом узнал, что лифт не работал из-за сбоя программного обеспечения. Тогда он решил попробовать сделать язык программирования, который сводил бы такие ошибки к нулю. Чтобы даже начинающий разработчик мог бы написать код, который не зависал.
Какая элегантная подмена понятий.
Начинающий разработчик пишет программу для здания в 10 этажей (псевдокод):Пока(этаж<20) повторять
и она зависает.
пауза(1 сек);
anka007
00.00.0000 00:00О, а мне байку рассказывали, что для лифтов делают управление на плис, так как они доказательно верифицируются.
wataru
00.00.0000 00:00+2Ошибки типа переполнения буфера и выхода за пределы массива в языке стали невозможны в принципе.
Всмысле не возможны? Там встроенные проверки и программа падает при попытке записать что-то за границы массива? Как std::vector::at в C++?
Ну так это та же ошибка, только поведение при ней — аварийное завершение программы, а не возможная уязвимость.
DirectoriX
00.00.0000 00:00+2Есть get/get_mut, которые возвращают Option. То есть если индекс внутри массива — будет Some(&T) который можно использовать, а если за границами — всего лишь None. Есть даже конструкция
if let Some(value) = vec.get(index) {...}
как раз для подобных случаев.
Можно обращаться и с помощью квадратных скобок — тогда да, запаникует.wataru
00.00.0000 00:00Что будет, если этот Option программист попробует вывести или прибавить к счетчику?
А с записью как?
Ну вот, допустим, вам надо данные крипто-ключа записать в массив. Массив оказался коротким. Вижу 2 варианта: программа запаникует или надо проверять результат, вдруг ошибка вернулся. В любом случае, программа будет работать некорректно. Ну некуда ей этот ключ записывать, а что-то делать с обрезком бессмыслено.От зависнувшего лифта не помогает. Предотвращает возможность эксплоита — да.
DirectoriX
00.00.0000 00:00+3Option нужно распаковать перед использованием, именно поэтому он спасает от ошибок выхода за границу, не вводя панику.
А ещё массивы и ко. знают, какова их ёмкость, так что можно явно проверить перед записью.
Вот вам небольшой пример как это может быть использовано (можете раскомментировать строки 3 и/или 4 если хотите посмотреть поведение для чуть других типов).
zaiats_2k
00.00.0000 00:00+4Тема лифта не раскрыта совершенно. Как он узнал что сбой был именно из-за ПО, что за баг там был...
Zhbert
На фотке Торвальдс же?
plFlok
что особенно иронично если учесть, как Торвальдс сопротивлялся внедрению rust в код ядра линукса.
slonoten
А фотография попала из этой статьи https://www.techspot.com/news/96037-rust-programming-language-join-linux-kernel.html
Rrs
Вроде он сопротивлялся только появлению C++, для rust он выкатил список требований, которые они и удовлетворили.
u007
А есть подробности? Интересно почитать, но не гуглится этот список
Rrs
https://www.linuxadictos.com/en/rust-was-not-saved-from-the-criticism-of-linus-torvalds.html
Halt
Настолько сопротивлялся что вкатили поддержку в апстрим 6.1, в 6.3 будут готовы вливать драйверы.
aamonster
Это иллюстрация к "сводить ошибки к нулю" :-D