Rust — это язык системного программирования, создатели которого уделили внимание трем вещам: параллелизму, скорости и безопасности. И хотя Rust считается молодым языком программирования — его первая стабильная версия вышла в 2015 году — он разрабатывается уже более десяти лет.

Сегодня мы бы хотели заглянуть в прошлое и рассказать историю языка Rust, показать, как изменились его функции и возможности за время разработки и привести конкретные примеры внедрения этого ЯП на практике.


/ изображение Jeff Vier CC

Личный проект (2006–2010)


Технология из прошлого, которая призвана спасти будущее от самого себя

— Грэйдон Хор (Graydon Hoare), разработчик Rust
Это одна из цитат Грэйдона Хора, которую озвучил Стив Клабник (Steve Klabnik) из команды разработчиков проекта Rust во время своей презентации на конференции ACM в 2016 году (слайды к презентации вы можете найти по ссылке, а для того, чтобы перемещаться между слайдами, используйте стрелки на клавиатуре). Эти слова хорошо отражают тот факт, что Rust — не революционный язык, имеющий передовые функции. Он просто включает в себя множество рабочих методов из «старых» языков (в том числе C++), повышая их безопасность.

Грэйдон Хор начал разработку Rust в 2006 году – в то время он был сотрудником Mozilla и занимался проектом в свободное от работы время. По словам Грэйдона, язык получил название в честь грибов семейства ржавчинные, поскольку те являются «распределёнными организмами», не имеющими «единой точки отказа», и обладают исключительной живучестью. Такие грибы имеют пять стадий жизненного цикла и быстро прорастают. Хор решил, что это хорошая аналогия для ЯП, сфокусированного на безопасности и скорости работы.

Занимаясь языком, Грэйдон установил определенные правила. Он отмечал, что в первую очередь необходимо уделять внимание семантике языка, а работа над синтаксисом — это последнее дело. Поэтому в ранней реализации Rust ключевые слова были не длиннее пяти символов — язык был «кратким» и использовал такие операторы, как log, ret и fn.

Например, первый код на Rust, который увидел свет, выглядел так:

fn main() {
    log "hello, world";
}

fn max(int x, int y) -> int {
    if (x > y) {
        ret x;
    } else {
        ret y;
    }
}

Как отмечает Стив Клабник, со временем это ограничение было снято: часть ключевых слов «удлинили», например, ret превратился в return, а часть заменили совсем. Для сравнения, в современной реализации языка вывод строки «Привет, мир!» выглядит так:

fn main() {
    println!("Hello, world!");
}

Также за время эволюции часть концепций и ключевых слов языка была убрана. Когда над языком работал Грэйдон, Rust был объектно-ориентированным и использовал оператор obj для описания объектов. Сейчас как таковое ООП языком не поддерживается, но Rust дает возможность реализовать многие его понятия с помощью абстракций.

Rust также работал с функциями параметрического полиморфизма. Концепции обобщенного программирования в языке сохранились и сейчас (оформление кода вы можете найти в этом документе), однако десять лет назад для обозначения типа параметров использовались квадратные скобки:

obj swap[T](tup(T,T) pair) -> tup(T,T) {
    ret tup(pair._1, pair._0);
}

fn main() {
    auto str_pair = tup("hi", "there");
    auto int_pair = tup(10, 12);
    str_pair = swap[str](str_pair);
    int_pair = swap[int](int_pair);
} 

Самостоятельно над Rust Грэйдон работал на протяжении четырех лет. За это время ему удалось воплотить в жизнь примерно 90% задуманных функций (часть из которых имела довольно грубую реализацию). Среда для выполнения кода была завершена на 70%. Всего за это время Хор написал 38 тыс. строк кода для компилятора на OCaml.

Переход к Mozilla (2010–2012)


Я не считаю, что у языка должны быть какие-то главные особенности.

Он должен состоять из набора понятных и надежных модулей, которые хорошо «работают» в комбинации друг с другом


— Грэйдон Хор (Graydon Hoare), разработчик Rust
По прошествии четырех лет, Грэйдон решил показать свой прототип менеджеру в Mozilla. В компании проявили интерес к проекту, поскольку искали инструмент для перестройки стека браузера на более простых технологиях, чем C++. Поэтому в компании создали команду (во главе с Грэйдоном) для работы над Rust, который стал основой браузерного движка Servo.

Тогда движок Mozilla не мог полноценно работать с мультиядерными системами, поскольку имел однопоточные схемы обработки контента. Например, однопоточными были функции формирования содержимого окна и запуска JavaScript. Rust позволил разделить код рендеринга на мини-задачи, выполняемые параллельно и экономящие ресурсы центрального процессора.

Кроме ускорения работы за счет распараллеливания операций, Rust позволил повысить защищенность браузера. На тот момент Firefox был реализован на C++ и содержал 4,5 млн строк кода. C++ — это «точный» язык программирования, требующий повышенного внимания к деталям, поэтому ошибки программистов могли приводить к возникновению серьезных уязвимостей. Задачей Rust стало снижение влияния человеческого фактора с помощью компилятора.

В 2010 году разработчики языка сменили используемый до этого компилятор OCaml на компилятор, написанный на Rust. В 2011 году Грэйдон опубликовал сообщение о том, что компилятор сумел успешно «собрать» сам себя, а в 2012 команда Rust объявила о релизе альфа-версии компилятора — его документация была не полной, а скорость создания билда оказалась далека от идеальной, однако он уже поддерживал большинство функций языка и кросс-компиляцию.

Годы typesystem (2012–2014)


Наша целевая аудитория — «разочарованные разработчики C++»

— Грэйдон Хор (Graydon Hoare), разработчик Rust
В этот момент Грэйдон отошел от работы над Rust и переключился на другие проекты. Как рассказывает Стив Клабник, после этого система управления стала более «распределенной». Была сформирована федеративная структура, в которой за изменения, вносимые в разные части проекта, отвечала отдельная группа разработчиков.

Команда продолжила расти, и в ней стали появляться люди, разбирающиеся в сложных системах типов. Поэтому началось активное развитие typesystem, и все больше аспектов языка выносились в библиотеки.

Например, на ранних этапах Rust был реализован «сборщик мусора» (GC — Garbage Collector), который Грэйдон внедрил для повышения защищенности памяти. Однако потом разработчики пришли к выводу, что они могут обеспечить тот же уровень надежности с помощью системы типов, и от GC отказались.

Это решение также сказалось на системе указателей, используемой в Rust. До удаления «сборщика мусора» в языке было три основных указателя:


После удаления GC система указателей претерпела изменения и приняла такой вид:

  • Box (уникальный указатель)
  • & (заимствованный указатель, который назвали «ссылкой»)

На этом этапе разработки языка программирования также было сделано множество улучшений, не связанных с typesystem. Например, велась работа над менеджером пакетов Cargo и онлайн-репозиторием Crates.io. Разработчики добавили возможность кастомизации настроек компилятора, что упростило переход на Rust с других языков. «Новичкам» не приходилось выяснять, для чего нужен тот или иной флаг при компиляции. Кстати, команды для менеджера пакетов Cargo вы также можете найти в презентации Стива Клабника.

Период с 2012 по 2014 год — это время, когда сообщество Rust начало обретать форму. В нем образовалось три больших «лагеря»: пользователи C++, пользователи скриптовых языков и функциональные программисты. Их экспертиза повлияла на язык — постепенно он стал сочетать в себе парадигмы функционального и процедурного программирования.

В марте 2014 года также был сформирован RFC-процесс, который использовался для представления значимых изменений в языке. Решение строилось по образу и подобию Python PEP, и сейчас в нем сделано 3 тыс. коммитов. Причем в RFC попадает любое изменение, даже вносимое разработчиками. По правилам команды Rust, никто не может вносить крупные изменения, не обсудив решение с сообществом.

Релиз (2015)


Мы не знаем наверняка, что из этого получится

— Грэйдон Хор (Graydon Hoare), разработчик Rust
В начале 2015 года была выпущена версия Rust 1.0 Alpha. В ней стабилизировали ядро языка, развили систему макросов, и, наконец, закрепили за целочисленными типами int и uint названия isize и usize. В начале второго квартала того же года Rust 1.0 перешел в бету — к этому моменту репозиторий crates.io имел 1700 крэйтов (структурная единица компиляции), а количество скачиваний из репозитория превысило один миллион.

В мае 2015 года состоялся официальный релиз — Rust 1.0. Это ознаменовало начало стабильности. С этого момента все вносимые изменения должны были иметь обратную совместимость, что позволило использовать Rust в реальных проектах. Он начал находить применение в таких сферах, как game dev, веб-разработка и разработка операционных систем.

Переход в продакшн (май 2016)


Если язык хорош лишь в чем-то одном, то это — провал

— Грэйдон Хор (Graydon Hoare), разработчик Rust
В 2015 году площадка StackOverflow провела опрос среди разработчиков, в котором их попросили отметить, с какими языками программирования они работали и с какими хотели бы познакомиться. Тогда Rust занял третью строчку рейтинга. Однако годом позднее он переместился на первое место — 79% пользователей изъявили желание продолжить работу с ним.

Один из резидентов Hacker News назвал главными достоинствами языка прозрачность и простоту документации. Другие пользователи также отмечали открытость и доброжелательность Rust-сообщества, которое всегда готово помочь с изучением особенностей ЯП.

При этом многие разработчики решают продолжить работу с этим языком из-за его механизмов безопасности. Как сказал один из пользователей Reddit: «Программирование на Rust — это как паркур со страховкой и в защите; иногда это выглядит странно, но вы можете делать многие трюки, не боясь сломать себе что-нибудь».

С момента релиза стабильной версии Rust начался период его полноценного использования в продакшн. Одной из первых компаний, которые применили Rust в своем проекте, стала Mozilla. Часть «внутренностей» Firefox 45 для Linux были переписаны на Rust, а начиная с версии Firefox 47, Rust-код присутствует и в версии для Windows. Их Project Quantum, анонсированный в октябре 2016 года, также имеет в своем составе компоненты Servo.

Rust используется и в Dropbox — на этом ЯП написано ядро их продукта. Компания Dropbox создала свое новое облачное хранилище Magic Pocket, в которое перенесла информацию с Amazon S3. Изначально оно было реализовано на языке Go, но при больших нагрузках проблемой становилось высокое потребление памяти и низкая предсказуемость поведения кода на Go. Для решения этих проблем был частично задействован Rust.

В прошлом году использовать Rust для обработки пакетов JavaScript начали в npm. Rust помог исключить задержки в системе, работающей с 350 миллионами пакетов в день. Специалист службы поддержки npm Эшли Уильямс (Ashley Williams) рассказывала об опыте использования Rust на конференции RustFest в Украине. Видео вы найдете по ссылке.

Rust также используем и мы в компании Bitfury. На этом языке программирования реализован наш фреймворк для создания блокчейнов Exonum. Впервые мы представили платформу на конференции RustFest 2017, где показали её возможности и провели воркшоп, на котором продемонстрировали работу сервиса по созданию криптовалют (краткое руководство о том, как создать криптовалюту на Exonum вы можете найти здесь).

Реализация на Rust оказалась кстати при работе со смарт-контрактами. Благодаря этому умные контракты Exonum имеют большую производительность, чем контракты Ethereum (или Fabric). Код платформы полностью открыт и лежит в репозитории проекта на GitHub.

Rust также находит применение в сфере информационной безопасности. Такие проекты как Tor уже переносят часть кода на Rust.

В целом, сегодня Rust в своих продуктах используют 105 компаний. Полный их список (в котором также отмечена и Bitfury Group) можно найти на странице Friends of Rust на официальном сайте. И количество компаний, создающих программные продукты на Rust, постоянно увеличивается, чему разработчики языка очень рады.



  • 28 февраля в Москве мы проведем Rust-митап с разработчиками Exonum, Bitfury Group и Parity Technologies. Будем обсуждать создание смарт-контрактов с помощью Rust & WebAssembly. Кроме доклада будет и практическая часть по созданию WASM-контрактов на Exonum. Подробнее об эвенте тут.

  • 1 марта мы проведем открытый воркшоп, на котором покажем, как можно перевести на WASM не только смарт-контакты, но и клиентскую часть Exonum-блокчейна. Подробности встречи можно узнать по ссылке.

Вход на мероприятия свободный по предварительной регистрации.

Комментарии (112)


  1. beduin01
    25.02.2018 16:31

    Крайне сложно представить себе реальный проект в котором писать Rust было бы экономически оправдано. Вся структура языка заточена на то, чтобы вынуждать человека указывать достаточно низкоуровневые подробности не тогда, когда это действительно нужно, а ПОСТОЯННО. Исключение где Rust может быть реально полезен могут составлять только Embedded и hard real-time системы. Однако это капля в море разрабатываемого софта.


    1. Crandel
      25.02.2018 17:06

      Не вижу большой разницы при написании кода на Расте и Джаве, не говоря уже про С. По моему вы преувеличиваете


      1. andy128k
        25.02.2018 17:28

        Разница всё же небольшая есть, но если есть опыт в C++, то низкоуровневые вещи легко пишутся «на автомате». А если есть опыт в Scala (OCaml, Haskell), то и высокоуровневые части языка понятны и приятны.


        1. Crandel
          25.02.2018 17:36

          Я имею в виду, что к примеру есть скриптовые языки — Python, Ruby, Javascript и есть статически типизированные, как Java, Scala, C#, C++. Вот между этими групами — разница действительно большая и мне после Python тяжело было пробовать Java и Go. Но вот когда уже Rust изучал — единственное не было понятно — это life time. А в остальном — очень похоже. Так как на Java/С#/Go очень много веба делается, то и Rust тоже может получить свою долю


          1. Jamdaze
            26.02.2018 07:31

            Написано же что ЦА это «несмогшие» в с++, а у вас опыт языков с GC, как я понял.


        1. mikhanoid
          25.02.2018 19:15
          +2

          Когда есть опыт в OCaml и Haskell, высокоуровневые части не кажутся приятными. Слишком громоздко.


          1. Optik
            25.02.2018 20:51

            И хреново композятся.


            1. mikhanoid
              25.02.2018 21:12

              (grammar-nazi-mode компонуются), но по сути согласен


          1. ozkriff
            27.02.2018 09:09

            Это смотря какие части имеются в виду :) Типажи, итераторы и подобное — вполне себе. Более высокие материи в ржавчине, да, не так красиво выглядят, конечно, но без толстого рантайма и не понятно как их органично реализовать можно.


      1. beduin01
        25.02.2018 17:32

        >Не вижу большой разницы при написании кода на Расте и Джаве, не говоря уже про С.
        Сравните ради интереса пару типовых приложений. К примеру word-count и убедитесь в том, что на Rust потребуется в 2-3 раза больше кода, чем на многих других языках.


        1. Crandel
          25.02.2018 17:40

          У меня есть одна программа, написанная на Go и на Rust и я не вижу большой разницы в обьеме кода. Единственная существенная разница — на Go почти все встроенно в стандартную библиотеку, а в Rust — очень много сторонних крайтов


          1. creker
            25.02.2018 20:54

            Но все таки сложно спорить с тем, что Rust очень сильно перегружен синтаксически. В нем очень много специальных символов, ворох которых существенно усложняет чтение. И в этих условиях сравнение Go только против Rust работает — при всей мощи системы типов Rust он не выглядит таким уж лаконичным и читабельным, а даже наоборот. По крайней мере Go синтаксически довольно примитивен и специально, чтобы его читать можно было как дважды два. А Rust при каждом случае, когда я сталкиваюсь с его кодом, вызывает похожие чувства, как перегруженный синтаксическими изысками C++. Ни в какое сравнение это не идет с Java, Go или Python.

            Но Rust в итоге это можно простить, потому что на нем сказывается его специализация на thread-safety и те жертвы, на которые он идет ради этого. Только все это делает его несколько узкоспециализированным, и сложно его представить как полноценную drop-in замену тому же C++. Он способен его заменить разве что по мощности синтаксиса и скорости выполнения.


            1. Gizmich
              26.02.2018 00:07

              Вот подумал ровно так же. Пробовал знакомиться с Rust но синтаксис меня просто раздражал, так и не осилил. Решил дальше дружить с Go


            1. WFrag
              26.02.2018 02:57

              Мы пишем на Rust систему, которую традиционно бы писали на Java (условный «кровавый энтерпрайз»). После пары месяцев активного написания, когда основные моменты Rust сходу понимаешь, каких-то особых трудностей нет.

              Приходится больше думать, например, о владении объектов (в Java можно практически вообще не думать), но в целом чувствую себя вполне продуктивным. И уж Java-то по количеству кода грех не уделать — в Rust более мощная система построения абстракций (типажи, макросы, аттрибуты, более мощные параметры типов).

              Но синтаксиса разного много, это да. Не вижу серьёзной проблемы с точки зрения долгосрочной коммерческой разработки — надо три месяца, будут у тебя три месяца на освоение. Это марафон, а не спринт.


              1. creker
                26.02.2018 03:50

                Любой язык после погружения в него перестанет казаться непонятным. Но я, смотря на него извне, вижу его излишне сложным для чтения. Для меня видится, что такой код будет сложно поддерживать в условиях, когда ты не держишь постоянно в голове его, а периодически возвращаешься к нему спустя какое-то время. Обычно языки со сложным и богатым синтаксисом страдают в этой ситуации. Даже C# вроде бы и то заставляет иной раз погрузиться в код, чтобы вспомнить, чего он такого хитрого делает с его куче синтаксических конструкций. И мне кажется, что Rust сильно ушел в сторону усложнения своего синтаксиса и системы типов, а о читабельности забыл. Не найден баланс. Собственно, в задачах языка этого и нет — safety, speed, and concurrency. Это все конечно замечательно, но это определенно продолжит удерживать rust от роста его доли на рынке. Stackoverflow не показатель ничего в этом плане.


                1. JDTamerlan
                  27.02.2018 11:29
                  -1

                  Stackoverflow не показатель ничего в этом плане.

                  Мне кажется, это как раз показатель. Показатель того, что с ним возникает очень много вопросов.


                  1. PsyHaSTe
                    27.02.2018 12:35
                    +2

                    > Существует лишь два вида языков программирования: те, которые постоянно ругают, и те, которыми никто не пользуется ©

                    То, что по Rust задают вопросы не означает ничего плохого. Во-первых там действительно есть некоторые концепции, которые непривычны неподготовленному человеку. Уверен, какие-нибудь темплейты после чистого С казались странной конструкцией. Во-вторых я не припомню, чтобы по какому-то «простому» языку на SO не задавали бы вопросы. Блин, там есть вопрос «как сложить 2 числа с помощью jQuery» с 7000 апвотами. Означает ли это, что сложить 2 числа в JS сложная задача, с которой у многих проблема?


              1. VulvarisMagistralis
                26.02.2018 06:33

                Мы пишем на Rust систему, которую традиционно бы писали на Java (условный «кровавый энтерпрайз»).


                Странный выбор.
                Хотя… Селектел тоже писал на Haskell свой «кровавый энтерпрайз». Даже получилось. Потом переписали. Почему-то.


                1. WFrag
                  26.02.2018 08:30

                  Время покажет, странный выбор или нет.


                  1. VulvarisMagistralis
                    26.02.2018 08:40

                    Время покажет, странный выбор или нет.


                    Разработчики тут по сравнению с предприятием очевидно в выигрышной ситуации.
                    Глубокое погружение в язык — полезно.


            1. Crandel
              26.02.2018 15:21

              В Go нет ни дженериков, ни макросов, так что сравнение совсем некорректное. ПРо необходимость этих фич давайте не будем спорить, но их наличие существенно меняет синтаксис. Для меня это не критично, мне главное — возможности, предоставляемые языком. В целом Go — очень неплохой язык, но меня раздражает пару моментов в нем. Как раз за наличие этих нескольких фич, особенно обработка ошибок я и люблю Rust


              1. creker
                26.02.2018 15:25

                Вы сравнили, не я. И при условии, что в Go этого всего как раз нет, у вас получился примерно одинаковый по объему код. Это не в пользу Rust говорит.


                1. Crandel
                  26.02.2018 15:32
                  +1

                  Разве не наоборот? Если обьем кода одинаков, а возможностей намного больше, то в чью пользу будет сравнение?
                  Это если брать совсем грубо. И Go и Rust имеют как плюсы, так и минусы. Абсолютно идеального языка к сожалению еще не придумали)


                  1. VulvarisMagistralis
                    26.02.2018 16:16

                    Если обьем кода одинаков, а возможностей намного больше


                    Возможностей выполнить конечную задачу у языков этого типа — поровну совершенно.
                    Потенциальный путей (вы видимо это обозначаете словом возможности) больше — код лучше не становится, код становится путанее.


                    1. Crandel
                      26.02.2018 16:26

                      Возможностей выполнить конечную задачу у языков этого типа — поровну совершенно.

                      Не согласен. Дженерики и макросы очень сильно упрощают код. Да и обработка ошибок в Расте мне сильно приятнее.


                      1. VulvarisMagistralis
                        26.02.2018 17:51

                        Не согласен. Дженерики и макросы очень сильно упрощают код. Да и обработка ошибок в Расте мне сильно приятнее.


                        Макросы — создают уж больно много головняков. На фоне пользы от макросов, — не стоит оно того.

                        Обработка ошибок — вкусовщина. В go приняли такую схему не потому что авторы не знали о других способах


                        1. Crandel
                          26.02.2018 17:58

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


        1. khim
          25.02.2018 18:05

          К примеру word-count и убедитесь в том, что на Rust потребуется в 2-3 раза больше кода, чем на многих других языках.
          Лаконичность — далеко не всегда достоинство. Перерлюнуть Forth в этом отношении тяжело, но много вы видели программистов на Forth?


          1. beduin01
            25.02.2018 20:27

            >Лаконичность — далеко не всегда достоинство
            Ручное управление памятью и пресловутое Memory safety тоже нужно дай бог в нескольких процентах реальных проектов.


            1. VulvarisMagistralis
              26.02.2018 06:27

              Ручное управление памятью и пресловутое Memory safety тоже нужно дай бог в нескольких процентах реальных проектов.


              Вот для таких проектов он и создан.
              А для прочих — есть более удобные Go, Python и пр.


              1. PsyHaSTe
                26.02.2018 21:42
                +1

                Ресурс это не только память.

                Если с памятью GC кое-как справляется, то вовремя закрывать файлы/сокеты он не умеет. Поэтому у нас в расте всякие Disposable и существуют. В GO полагаю тоже есть какие-то способы полу-автоматически Close вызывать на ненужных объектах. Но когда компилятор не заставляет их закрывать, начинается беда.

                Кстати, типовой ответ на это — «так никто не пишет»


                1. PsyHaSTe
                  27.02.2018 12:38

                  У нас в сишарпе, прошу прощения, оговорился


          1. Jef239
            25.02.2018 23:46

            Это вы ещё APL не изучали.

            А программистов на форте я видел порядочно (и регулярно вижу в зеркале). У форта всего одна проблема — нужно полгода, чтобы переучить мозги действовать в стековой парадигме.

            Зато APL — в обычном ASCII не записывается. Слишком уж много там спецсимволов.


            1. khim
              26.02.2018 00:20

              Это вы ещё APL не изучали.
              Изучал как раз. Я ж по специальности математик, не программист.

              Но в APL есть проблема: многие математические алгоритмы записываются коротко и просто, но многие другие, не ложащиеся на матрицы — просто ужасно.

              Зато APL — в обычном ASCII не записывается. Слишком уж много там спецсимволов.
              Для таких случаев есть J и его потомки.

              В любом случае реальную операционную систему на этом сделать нельзя, на rust или forth — можно. Так что это языки для совсем разных ниш.


              1. Jef239
                26.02.2018 01:07

                Ну предела для извращений нет. Была IBM 5100 с микропрограммной реализацией APL. Так что для неё ОС- разумно было писать на APL, ибо ничего другого не было.

                Там очень забавный диалект APL был — с файловыми операциями и всем прочим.


        1. BlessMaster
          26.02.2018 00:03
          +4

          в 2-3 раза больше кода, чем на многих других языках

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


          public static void main (String[] args) {
          
              System.out.println("Simple Java Word Count Program");
          
              String str1 = "Today is Holdiay Day";
          
              String[] wordArray = str1.trim().split("\\s+");
              int wordCount = wordArray.length;
          
              System.out.println("Word count is = " + wordCount);
          }

          extern crate regex;
          
          fn main() {
          
              println!("Simple Rust Word Count Program");
          
              let str1 = "Today is Holdiay Day";
          
              let spaces = regex::Regex::new(r"\s+").expect("Can't compile regex");
              let word_count = spaces.split(str1.trim()).count();
          
              println!("Word count is = {}", word_count);
          }

          Что мы здесь видим? Когда что-то внесено в стандартную библиотеку да ещё и автоматически импортируется, с этим бывает проще работать. В примерах выше у Rust таким лаконичным оказывается ввод-вывод, у Java — регулярные выражения, принимаемые как строковой аргумент.


          В остальном… Rust принуждает обрабатывать ошибки — если мы пишем качественный код, им придётся уделять внимание в любом случае, но с Rust — все ошибки явные и их обработка входит в привычку. Java же кидает исключения, которые далеко не так удобно обрабатывать на каждом шагу и всегда есть соблазн отложить их обработку на потом.


          Вышеприведённый код на Java честно украден со StackOverflow, вероятно его можно ещё чуточку упростить, использовав аналогичным образом итератор?


          В одном из альтернативных ответов предлагают использовать StringTokenizer API, что позволяет, наверно, надёжней считать слова: new StringTokenizer(str1).countTokens() однако не выглядит лаконичней, чем приведённый код. Такому сценарию можно сопоставить использование какой-нибудь библиотеки по работе с текстом и мне сложно представить, что её API для тех же задач будет сложнее.


          Если посмотреть на другие варианты ответов — умение писать компактный код на Java — далеко не такой распространённый навык, как можно было бы ожидать.


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


          С другой стороны — в Rust реализован впоне здоровый компромис между детальностью описания и "догадливостью" компилятора. Нет необходимости уточнять вот прям всё-всё-всё — Rust умеет выводить типы, библиотеки предоставляют инструменты для конвертации типов. И есть неплохая система кодогенерации, позволяющая сокращать количество пользовательского кода на порядок, чем популярные библиотеки (и упомянутый в статье Exonum) достаточно часто пользуются.


          1. Optik
            26.02.2018 09:32

            Много текста слабо связанного с приведенным кодом, который показывает примерно ничего.

            Ну вот вам в довесок для рассуждений еще (на таком аналитическом примере можно разных языков притащить).

            {-# LANGUAGE OverloadedStrings #-}
            module Main where
            
            import Data.Text hiding (length)
            import Prelude hiding (words)
            
            main = do
                putStrLn "Simple Haskell Word Count Program"
            
                let str1 = "Today is Holdiay Day"
            
                let wordCount = (length . words . strip) str1
                putStrLn ("Word count is = " ++ show wordCount)
            


            1. BlessMaster
              26.02.2018 14:52
              +1

              Предлагайте более актуальные примеры, мы с удовольствием их обсудим и, возможно, это станет началом улучшения языка. Rust — развивается не в последнюю очередь в ответ на потребности сообщества. Я же лишь ответил на конкретный комментарий выше, с утверждением "реализации на Rust требуют в 2-3 раза больше кода, чем на других языках", что "несколько преувеличено" ©.


              1. Optik
                26.02.2018 16:17

                Вероятно надо развернуть мою мысль, потому что мою нападку на комментатора, восприняли как нападку на раст. С последним у меня нормальные отношения. И я вижу в нем как плюсы так и минусы. При этом компактность в рассмотрении вообще не участвует. Язык или дико вербозный или должно быть пофиг на его компактность, ибо есть вещи важнее. Когда постоянно высказываются за компактность кода, то свидетельствует только о том что сказать больше нечего. Я пользуюсь в некоторой степени растом, и у него есть проблемы, но не компактность.

                О комментаторе же, подробнее:

                Комментатор говорит за лаконичность кода и для примера используют внешнюю либу в своем примере. Понятно что любой код можно завернуть в вызов функции, только это о самом языке говорит ничего.

                `println` — это не картина мира о вводе выводе. Даже не картина о выводе. Потому что под капотом забит конкретный кейс вывода в стдаут (в любом языке).

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


                1. BlessMaster
                  27.02.2018 13:58
                  +2

                  Ок, давайте о комментаторе подробней, комментатор не против ;-)


                  Комментатор говорит за лаконичность кода и для примера используют внешнюю либу в своем примере.

                  Комментатор пытает честно сравнить объём кода, который потребовался для решения задачи на двух разных языках. Объём кода растёт из всего, в том числе и из подключения внешних модулей, и необходимости создавать служебные объекты, и из необходимости обрабатывать ошибки, что мы и видим на примере Regex.


                  При этом использованная внешняя либа — находится в так называемом "nursery", который отделён от стандартной либы очень тонкой (сходящей на нет) гранью. Это сравнивается с тем, что в Java аналогичная функциональность закопана в stdlib.


                  println! и иже с ним всякие write!, format! в Rust доступны программисту без дополнительных телодвижений (если он не делает странного), в Java аналогичные вещи нужно либо импортировать, либо вызывать полностью прописав весь путь к соответствующим классам и это тоже видно на примере кода.


                  И вот всплывают действительные различия на уровне семантики языков, а комментатор бодро их игнорит в примере.

                  Эмм, мы можем развить эту тему, наверняка Вы знаете экстремальные примеры, где обработка ошибок — это бессмысленно, больно и много кода? На синтетическом примере с wordcount — здесь негде развернуться.


                  О чем это вообще? Вроде ни акторы ни каналы не присутствовали в контексте.

                  То есть, на самом деле Вы просто не поняли о чём речь и из этого преждевременно сделали вывод, что комментатор говорил без конкретики, вместо того, чтобы прямо сообщить комментатору, что он как-то непонятно выразился?


                  Язык программирования — это таки язык — средство коммуникации, в данном случае человека с машиной. Акторы и каналы здесь ни при чём. Язык должен позволять человеку описывать то, что он хочет получить от машины.


                  1. Optik
                    27.02.2018 19:11
                    -1

                    На синтетическом примере с wordcount — здесь негде развернуться.
                    В этом и основной мой посыл был. Пример показывает ровным счетом ничего, но выводов сделано прям как при сравнении тысячи строк.

                    println! и иже с ним всякие write!, format! в Rust доступны программисту без дополнительных телодвижений (если он не делает странного), в Java аналогичные вещи нужно либо импортировать
                    Т.е. притащить либу это ни о чем, а импорт целая катастрофа. Это я ёрничаю над объективностью оценки, на самом деле мне лично пофиг и на то и на то (ну кроме идиотского формата в принтлне с перечислением аргументов, вместо использования плейсхолдеров). В плане ио гораздо больше имеет значение работа с файлами. doc.rust-lang.org/1.22.1/std/fs/struct.File.html и что-то я опять не вижу особых различий по примеру, телодвижения ровно такие же как в любом другом языке. Можно рыть глубже и смотреть работу с буфферами для записи/чтения. Зато здесь есть куда более интересный момент с тем, что возвращаемые значения врапнуты (Result), что есть уже далеко не везде. Почему не сравнить это? Вполне практическая вещь, показывающая плюсы (можно спорить насколько жирный плюс, но уж не минус точно).

                    Про коммуникацию не буду обсуждать, у вас своя волна каких-то теплых человеческих чувств к машине.

                    Вы напали на бредовый вброс про многословность раста, но сами при этом ответили не особо более качественно.


              1. VulvarisMagistralis
                26.02.2018 17:06

                же лишь ответил на конкретный комментарий выше, с утверждением «реализации на Rust требуют в 2-3 раза больше кода, чем на других языках», что «несколько преувеличено»


                Плюньте. Это ж beduin01. У него все что не D-lang ( RIP праху его ) — то говно.


                1. beduin01
                  26.02.2018 18:09

                  Вы хоть потрудитесь с синтаксисом D ознакомиться для начала. Вот вам пример seb.wilzba.ch/b/2018/02/the-expressive-c17-coding-challenge-in-d

                  D — 17 строк кода
                  Rust — 83 строки

                  Вопрос. Нафига в 4 раза больше кода писать? Вашу работу по количеству строк кода оценивают? Или для вас самоцель не решение задачи, а графоманство?


                  1. VulvarisMagistralis
                    26.02.2018 19:17
                    +1

                    Вопрос. Нафига в 4 раза больше кода писать?


                    Думаю, для каждой пары достаточно различных языков можно найти различные искусственные ситуации, где у одного языка одно выпячивается, а у другого языка — прямо противоположенное.

                    Спасибо, что практически «Hello, World» предлагаете рассмотреть в качестве примера. То, что вы привели — весьма полезно для студенческих тренировок, согласен.

                    Но в реальной жизни программы… как бы вам сказать, побольше и посложнее и там вперед выступают иные качества.

                    Например, в сравнении мелких же примеров применения типа вашего Java тоже здорово сольет. А еще JVM долго стартует. И на этом основании можно сказать, что, к примеру, Perl лучше для «кровавого энтерпрайза» или для Android. Но ведь ПО для Android хорошо управляется Ява-машиной.


                  1. nexmean
                    26.02.2018 19:39
                    +4

                    Это решение на Rust можно чуть ли не один в один переписать. Разница будет максимум в 10-15 строк (объявлять переменные и писать импорты в одну строку это конечно круто, но нет).



        1. nexmean
          26.02.2018 00:08
          +2

          fn word_count(string: &str) -> usize {
              line.split_whitespace().count()
          }

          И действительно, какая же длинная функция получается.


    1. Gorthauer87
      25.02.2018 18:00

      Плюсы вот мейнстрим, а там намного внимательнее нужно быть. И плюс тулзы очень слабо развиты.
      Но все равно очень много вещей на них пишут.
      Лайфтаймы уж явно проще какого нибудь sfinae для восприятия. А главное раст реально не дает сделать множество видов ошибок просто по недосмотру


      1. VulvarisMagistralis
        26.02.2018 06:55

        И плюс тулзы очень слабо развиты.

        Вы об инструментах для С++, которых чуть ли не больше чем для всех прочих языков?


        1. ozkriff
          26.02.2018 10:24

          Я бы очень хотел, что бы у плюсов появился более-менее стандартный языковой пакетный менеджер, например. Пока к этому ближе всего https://conan.io, но даже он на практике ооочень далек от совершенства и тем более от общепринятости. Мало того что задача сложная из-за специфики языка и уже существующей инфраструктуры, еще и не так много кто понимает что это вообще нужная штука. :(


          1. eao197
            26.02.2018 11:00

            еще и не так много кто понимает что это вообще нужная штука
            Понимают-то как раз многие, отсюда и такая движуха в развитии менеджеров зависимостей для C++.

            Другое дело, что кроме отсутствия явного лидера, есть еще и такой фактор: разработчики в массе своей уже приспособились и каждый коллектив научился решать эту проблему по-своему. Кто-то использует только системы пакетов из своих дистрибутивов. Кто-то применяет git submodules. Кто-то CMake-овские ExternalProject_Add. У кого-то свой велосипед.

            Т.е. для большого количества C++ных команд эта проблема тем или иным образом уже решена. И пока нет явного лидера менять что-то работающее на что-то новое готовы не только лишь все :)

            У Rust-а в этом плане все гораздо привлекательнее.


          1. Gorthauer87
            26.02.2018 12:27
            +2

            Я бы еще сказал, что в плюсах например нет встроенных тулзов для автотестов и приходится заниматься подчас странными шаманствами, чтобы тесты подключить к проекту.


            1. humbug
              26.02.2018 19:13
              +1

              Угу. Сколько крови у меня попил GTest, ужас. https://github.com/0x7CFE/llst/blob/master/cmake/GTest.cmake


              1. Falstaff
                26.02.2018 22:58

                Я со своим уставом не лезу, боже упаси, просто интересно — не легче было просто в проект его положить? GTest очень легко прямо в проект на cmake вставить (там всего два исходника компилировать), и весит он всего ничего, да и внешних зависимостей меньше.


    1. gra
      25.02.2018 21:08
      +1

      Какие именно низкоуровневые подробности Rust вынуждает указывать «ПОСТОЯННО»?


      1. WFrag
        26.02.2018 03:01

        Например, строки против строковых слайсов.


        1. WFrag
          26.02.2018 20:28

          Не очень понимаю, откуда такая резкая реакция, но с точки зрения прикладного программиста разница между &str, String и Cow имеет малое значение. И то, и то — «строки». Разница в основном в способе владения (и в изменяемости, конечно, но в прикладном коде строка после создания изменяется редко [1]).

          Те, кто всё ещё не верят, предлагаю прочитать статью (ну или попробовать что-то большое написать, впрочем YMMV [2]).

          Это проявляется везде. Конвертация String в &str (обычно достаточно &my_string, но в каких-то случаях — нет, надо делать .as_str()). Конвертация Option в Option<&str> (ну-ка, быстро, как это делается?). Конвертация &str и String в Cow (и обратно). Создание String из литералов (при том, что это ещё и лишнее копирование — но вроде оптимизация на подходе).

          Возможно, конечно, мы просто сильно заморачиваемся и можно было бы просто фигачить String.

          [1]. YMMV, в принципе, в Rust можно более безопасно изменять String благодаря строгому borrow checker-у.
          [2]. Можно, например, вообще не заморачиваться и просто орудовать String, зависит, от задачи.


          1. ozkriff
            27.02.2018 09:29

            Про приведения типов — хз, я порядочно пишу на расте и по ощущениям большая часть преобразований это вообще просто & или .into().


            Ну и кстати, компилятор или IDE частенько по делу подсказывают, если что :)


            1. WFrag
              27.02.2018 09:43

              Тем не менее, это постоянно вылезает, о чём и был мой комментарий. Компилятор, конечно же, помогает, но это не убирает тот факт, что такие низкоуровневые моменты (потому что к бизнес логике они имеют слабое отношение) нужно указывать постоянно.

              Даже если забить болт на оптимальность, всё равно, в применении к строкам, будут постоянные to_string/clone и довольно неуклюжие операции со строками (впрочем, тут format! сильно помогает).


              1. ozkriff
                27.02.2018 09:56

                Я все равно не вижу в этом большей проблемы чем в, например, необходимости явно приводить i32 через as к f32 или usize, что уж я точно считаю плюсом языка в большинстве применений.


                1. WFrag
                  27.02.2018 10:02

                  Да я в общем-то и не считаю, что это проблема. Я на автомате такое пишу, новичкам в большинстве случаев компилятор внятно подскажет, а где не подскажет компилятор, там я помогу :)

                  Но если уж быть честным, то надо признать, что в Rust довольно много вот таких «ритуальных» действий (хотя их количество и сокращают — например, RFC 2005).


                  1. ozkriff
                    27.02.2018 10:08

                    Но если уж быть честным, то надо признать, что в Rust довольно много вот таких «ритуальных» действий

                    Что значит "надо признать"? Это же наоборот одно из достоинств языка — "явность", продуманная "синтаксическая соль" и все такое :)


                    хотя их количество и сокращают — например, RFC 2005

                    Эх, Я до сих пор с сомнением к этой инициативе отношусь — как бы не усложнили все этими упрощениями. Ну да посмотрим, может потом проникнусь все ж таки.


        1. WFrag
          26.02.2018 20:58

          Ну и до кучи, маленькая задачка. Хочу иметь ключ в хэш-таблице из пары строк. Ключ хранит строки (т.е использует String). При поиске у меня есть пара строковый слайсов.

          Поехали, три варианта, выбирайте на свой вкус (предлагайте свой, лучше!):

          use std::mem;
          use std::borrow::{Borrow, Cow};
          use std::collections::HashSet;
          use std::hash::{Hash, Hasher};
          
          fn size_of_key<T>(_set: &HashSet<T>) -> usize {
            mem::size_of::<T>()
          }
          
          fn main() {
            // Extra string copying on lookups :(
            let mut set = HashSet::new();
            set.insert(("hello".to_string(), "bye".to_string()));
            let flag = set.contains(&("hello".to_string(), "bye".to_string()));
            println!("{}, key size {}", flag, size_of_key(&set));
          
          
            // Extra memory used for Cow :(
            let mut set = HashSet::new();
            set.insert((Cow::Owned("hello".to_string()), Cow::Owned("bye".to_string())));
            let flag = set.contains(&(Cow::Borrowed("hello"), Cow::Borrowed("bye")));
            println!("{}, key size {}", flag, size_of_key(&set));
          
            // Whaaat? BUT:
            // No string copying! Key is small! Dynamic dispatch, though :(
            #[derive(PartialEq, Eq, Hash)]
            struct OwnedPair(String, String);
          
            #[derive(PartialEq, Eq, Hash)]
            struct BorrowedPair<'a, 'b>(&'a str, &'b str);
          
            trait KeyPair {
              fn pair(&self) -> (&str, &str);
            }
          
            impl KeyPair for OwnedPair {
              fn pair(&self) -> (&str, &str) {
                (&self.0, &self.1)
              }
            }
          
            impl<'a, 'b> KeyPair for BorrowedPair<'a, 'b> {
              fn pair(&self) -> (&str, &str) {
                (self.0, self.1)
              }
            }
          
            impl<'a> Borrow<KeyPair + 'a> for OwnedPair {
              fn borrow(&self) -> &(KeyPair + 'a) {
                self
              }
            }
          
            impl<'a> Hash for (KeyPair + 'a) {
              fn hash<H: Hasher>(&self, state: &mut H) {
                self.pair().hash(state);
              }
            }
          
            impl<'a> PartialEq for (KeyPair + 'a) {
              fn eq(&self, other: &Self) -> bool {
                self.pair() == other.pair()
              }
            }
          
            impl<'a> Eq for (KeyPair + 'a) {}
          
            let mut set = HashSet::new();
            set.insert(OwnedPair("hello".to_string(), "bye".to_string()));
            let flag = set.contains(&BorrowedPair("hello", "bye") as &KeyPair);
            println!("{}, key size {}", flag, size_of_key(&set));
          }
          


          1. ozkriff
            27.02.2018 09:17

            Ну такое, довольно специфическая задача, кмк. Да и первый вариант, если мы не хотим лезть в "низкоуровневые детали" чем плох? Да, выделения памяти, но мы же хотим высокоуровнево, значит нам не особо и важно.


            В целом про "String vs &str" — мне это вообще не видится "низкоуровневой деталью", это часть общего фокуса ржавчины со строгим отслеживанием владения и в моей голове оно все скорее как раз высокоуровневая штука про организацию программы и поток данных, а не про байтики в куче и стеке. И все это разделение на значения, изменяемые и неизменяемые ссылки в целом делает программу более поддерживаемой и понимаемой (при правильном применении).


            1. WFrag
              27.02.2018 17:51

              Да, но почему тебе интересно владение само по себе?

              Если бы был некий магический оракул, который бы убивал объекты моментально с уходом последней ссылки и не имел бы всех недостатков GC или подсчёта ссылок (таких как расход памяти на метаданные, давления на кеш в случае GC), ты бы стал заморачиваться с владением?

              Или бы просто сделал так, что String — это изменяемая строка, а &str — неизменяемая, которую можно передавать куда угодно и как угодно хранить (считай, аналог Rc но без расходов на подсчет ссылок).


          1. red75prim
            27.02.2018 13:01

            HashMap<String, HashSet<String>> не пробовали использовать? Дописки для удобной работы с таким типом не слишком большие: playground.


            Если без HashSet<(String, String)> совсем никак и хочется выжать последние байты и циклы работы процессора, то можно залезть и в unsafe. Предоставив безопасный интерфейс, конечно. Очень страшный playground


            1. WFrag
              27.02.2018 17:46

              Всё было бы гораздо проще, если бы std::borrow::Borrow borrow() возвращал бы Borrowed, а не &Borrowed.

              У нас сейчас вариант с Cow, на самом деле, потому что плюс-минус пофиг.

              Просто человек вот удивлялся, когда это дескать в Rust низкоуровневые вещи постоянно приходится указывать — я говорю, что постоянно, особенно со строками. Я считаю, что с точки зрения логики прикладной программы все эти жонглирования особо смысла не имеют. С точки зрения корректности программы на Rust — разумеется, с точки зрения производительности — да, конечно.


    1. tgz
      25.02.2018 22:24

      Некоторые не хотят потом 10 лет править сегфолты в коде. И для них экономически поравдано писать на расте. Если же у вас ХХивП, то вам конечно раст не нужен.
      Ну и потом у некоторых говнокодеров реально бомбит, когда компилятор умнее их.


      1. RPG18
        26.02.2018 09:06
        -2

        Базы данных, ядра ОС написаны на Си. Как часто встречается в них сегфолт? Наверное дело не в языке, а в людях. И в rust есть null, а значит «классика»(обращение к null) никуда не уходит.


        1. tgz
          26.02.2018 09:36
          +2

          Проектов на си, где ничего не падает можно пересчитать на пальцах одной руки. Ядро linux вних не входит, если что.


        1. Tanriol
          26.02.2018 11:43
          +1

          null в Rust есть только на уровне небезопасных абстракций ("сырые" указатели и им подобное). Да, код, работающий с ними напрямую, должен об этом беспокоиться — но это в худшем случае несколько абстракций, предоставляющих внешнему коду безопасный интрефейс, а не весь объём кода приложения.


          1. RPG18
            26.02.2018 11:57

            Если там так все безопасно, то откуда креши в servo?


            1. ozkriff
              26.02.2018 12:11
              +2

              Насколько я вижу, это именно что паники/аборты, а не сегфолты. Они происходят из-за логических ошибок в коде — все логические ошибки еще ни один язык не научился убирать, к сожалению, для этого нужен какой-нибудь фантастический сильный ИИ :)


            1. Tanriol
              26.02.2018 12:29

              В servo есть минимум одна большая и сложная абстракция (интеграция с JavaScript-движком mozjs, вариантом SpiderMonkey, который написан на C++), плюс логические ошибки, которые ловят ручные или автоматические assert-ы разных видов, в некоторых случаях недостаточно оптимизированное потребление ресурсов на особо весёлых страницах (например, slither, создающий более 2000 canvas-ов). Иногда ещё драйверы GPU вылетают.


              1. RPG18
                26.02.2018 12:50
                -1

                Как бы там не только проблема в JS. Особенно доставляет комментарии типа


                I have not been able to reproduce this in a local debug build following those steps.

                Все точно так же как на C++


    1. VulvarisMagistralis
      26.02.2018 06:21

      Однако это капля в море разрабатываемого софта.


      Для остальных вещей есть другие языки.
      Нет универсального языка, иначе он давно бы покорил мир.


    1. Falstaff
      26.02.2018 13:16

      Обидно что при этом как раз на embedded они при этом и не ориентируются — во всяком случае для контроллеров тулчейн вроде бы ещё в детском состоянии и обложен third-party костылями разной степени допиленности, и создаётся впечатление, что для разработчиков это не приоритет.


      1. Halt
        26.02.2018 13:25
        +1

        Вы не правы. Очень даже приоритет.


        1. Falstaff
          26.02.2018 13:45

          Embedded devices. A domain with a great deal of potential that is not yet first-class.
          While we cannot hope to stabilize everything needed for embedded development in 2018, we can step up our game and begin to treat the market as more mainstream.

          То есть намерение начать трактовать embedded как равноправную область есть, но в 2018 году надежды на что-то стабильное ещё нет. За намерение тоже спасибо, конечно, раньше и этого не было. Но пока очень расплывчато и без ясных планов, так что ещё на год в долгий ящик, во всяком случае с прицелом что-то в боевых условиях попробовать.


          1. khim
            26.02.2018 14:31

            У них есть беда: rust пока что живёт поверх clang, а не GCC, а для clang'а embedded — не приоритет.

            Так что либо менять направление развития clang'а, либо переходить на GCC. И то и другое — мягко говоря, непросто.


            1. nexmean
              26.02.2018 15:00

              Rust живёт поверх LLVM, и это совсем не одно и то же, что и Clang.


              1. khim
                26.02.2018 16:58

                Я бы сказал что это «не совсем» то же, что clang. Говорить всё-таки, что это «совсем не одно и то же» нельзя — они слишком тесно связаны. Но да, извиняюсь, моя ошибка.


          1. VulvarisMagistralis
            26.02.2018 15:21

            но в 2018 году надежды на что-то стабильное ещё нет.

            Сам Rust как язык еще только-только стабилизировался.
            А вы уже хотите стабильность по платформам.


            1. Falstaff
              26.02.2018 15:36

              Ну, 1.0 вроде в мае 2015 появился, без малого три года уже. И я скорее хочу чтобы они с позиционированием определились — язык вроде как системный, но в сторону embedded (где он был бы прямо подарком) не смотрит, а смотрит, судя по статьям, в сторону, например, бэкенда — уже прочно оккупированного языками со сборкой мусора.


              1. Halt
                26.02.2018 16:37
                +1

                Если вы действительно хотите получить представление о положении дел в embedded, то могу посоветовать вот этот пост.

                Плюс блог небезызвестного japaric, который стоит на острие прогресса в этой области.

                И еще момент: не надо воспринимать авторов языка, как разработчиков проприетарного софта. Да, многие работают в Мозилле и получают за это деньги. Но развитие языка во многом определяется именно сообществом.

                В отличие от питона, перла или других языков где правит «тиран», решения по развитию Rust принимаются сообща и полностью в открытую.

                Таким образом, язык такой, каким его хочет видеть активная часть сообщества. И только.


                1. Falstaff
                  26.02.2018 17:34

                  Спасибо за ссылку, хороший доклад. И, да, мне действительно интересно, в том числе с практической точки зрения. Я уже пробовал нырнуть в embedded rust, но выныривал с ощущением, что пока всё хрупко, неофициально и в постоянном движении.


                  И я понимаю, конечно, что разработчики и сообщество никому ничего не должны. Но и потенциальных разработчиков на Rust не стоит лишать права голоса. Активная часть сообщества — это не только те, кто послал туда патч. Это ещё и те, кто будет его использовать как только он будет более или менее годен к применению в их области (и тогда, возможно, посылать патчи, делать библиотеки, и прочая и прочая). А пока не могут, высказывают своё огорчение, вот как я сейчас. :)


                  1. Halt
                    26.02.2018 17:57

                    Но и потенциальных разработчиков на Rust не стоит лишать права голоса.

                    Именно поэтому была выдвинута инициатива #Rust2018, в рамках которой сообщество писало посты со своим видением ориентиров развития на ближайший год со своими пожеланиями и обозначением собственных проблем.

                    Было написано больше сотни постов, которые потом анализировались и упомянутый выше roadmap как раз был основан на компиляции озвученных идей.

                    В противном случае, это как раз было бы решение вида «я так сказал», без учета мнения большинства.


                1. VulvarisMagistralis
                  26.02.2018 18:33

                  Таким образом, язык такой, каким его хочет видеть активная часть сообщества. И только.


                  Это плохо.
                  Сообщество желает видеть язык для своей цели.
                  А целей у людей в сообществе — не счесть.
                  Тянуть язык в разные стороны — это не гуд.
                  Надесь, что вы все же заблуждаетесь насчет роли сообщества.


                  1. Halt
                    26.02.2018 18:38

                    Не путайте, пожалуйста, демократию и анархию. Если вам интересно, как все устроено, почитайте про процесс RFC и рабочие группы языка.


                    1. VulvarisMagistralis
                      26.02.2018 19:23

                      Не путайте, пожалуйста, демократию и анархию.


                      Что вы, я никак не подозревал сообщество Rust в анархии. Это попросту невозможно в пределах одного языка. Вопрос о стройности, единообразии. Это проблемы любого достаточно большого сообщества. У демократии есть недостатки, органически связанные с ее достоинствами. Когда отвечают за систему «все», — значит отвечает «никто». На самом деле система, конечно же, продолжит работать, потому как все заинтересованы в том, чтобы она работала. Но вот отдельные куски — могут быть даже противоречивы. Когда нет в языкостроительстве «тирана» — стройности языка достичь трудно, если вообще возможно. Как пример, наше обсуждение языков тут в комментариях.


                      1. ozkriff
                        26.02.2018 19:52
                        +1

                        Роль тирана в принятии или убийстве RFC выполняет команда ядра — https://www.rust-lang.org/en-US/team.html — все под контролем :)


              1. Halt
                27.02.2018 11:30
                +1

                Вот еще, могу посоветовать книгу с введением в микроконтроллеры с точки зрения Rust от все того же Japaric.


              1. Halt
                28.02.2018 17:06

                Как по заказу, специально для вас :) Анонс Embedded Devices Working Group.


  1. amarao
    25.02.2018 20:24

    Спасибо. Очень хороший обзор, особенно раннего этапа (я про него вообще не знал).


  1. Pavel1114
    26.02.2018 06:25

    Можно ссылку на «самый популярный ЯП по данный SO»? Это в какой-то подкатегории? Например среди ЯП с названием начинающимся на «Ru» и заканчивающимся на «st»?


    1. Googolplex
      26.02.2018 07:17

      Вероятно, имеется в виду Stackoverflow developer survey, в котором уже второй год подряд Rust занимает первую строчку в номинации Most loved language. Согласен, что перевод несколько некорректен.


      1. JekaMas
        26.02.2018 09:39

        Может, я не прав, но loved != популярный


    1. fukkit
      26.02.2018 08:09

      Не иначе как по тэгу «Какого черта?!»


  1. Foror
    26.02.2018 07:36

    Так вот она какая каша из топора...


  1. KirEv
    26.02.2018 09:51
    +1

    Rust используется и в Dropbox — на этом ЯП написано ядро их продукта.


    это для меня стало новостью, летом видел здесь статью о том, что dropbox переписали на Go =) про Rust было ни слова…

    последнее время делаю в основном на Go, но все чаще обращаю внимание на Rust, чертовски привлекательный. спасибо.


  1. eao197
    26.02.2018 10:30
    +1

    Изначально оно было реализовано на языке Go, но при больших нагрузках проблемой становилось высокое потребление памяти. Поэтому хранилище переписали на Rust, и проблема с памятью решилась.

    Можно ли попросить пруфов для этой истории?

    Ибо когда информация об использовании Rust в Magic Pocket появилась пару лет назад, то речь шла о том, что Dropbox уходил с Python-а на Go и написал свою Magic Pocket на Go. Очень сильно выиграв при этом и в производительности, и в ресурсоемкости. И только в одном месте обнаружилась проблема с предсказуемостью поведения кода на Go (из-за GC). Это место переписали на Rust-е. И в итоге вышло что-то порядка 30 или 60 KLOC кода на Rust-е в продукте объемом 1.3 MLOC на Go.

    За прошедшие пару лет что-то изменилось?


    1. fafhrd91
      26.02.2018 12:11

      Вот видео в митапа, в котором про то что dropbox делает. Потом та же команда искала rust разработчика


      https://air.mozilla.org/rust-meetup-may-2017/


      1. eao197
        26.02.2018 12:33

        Для меня английский сильно не родной, но разве где-то в районе 7:35-7:45 докладчик не говорит что-то вроде: «Magic Pocket был изначально написан на Go. И сейчас он все еще большей частью на Go. Может быть 30-40% на Rust-е»?


        1. VulvarisMagistralis
          26.02.2018 13:08

          Для меня английский сильно не родной, но разве где-то в районе 7:35-7:45 докладчик не говорит что-то вроде: «Magic Pocket был изначально написан на Go. И сейчас он все еще большей частью на Go. Может быть 30-40% на Rust-е»?


          Это быть не может физически.
          Они с Python на Go переходили несколько лет, там большой объем.
          Первые эксперименты с Rust начались 2 лет назад.
          К настоящему времени не может быть 40% даже если они и решили мигрировать на Rust


          1. Falstaff
            26.02.2018 13:12

            https://news.ycombinator.com/item?id=11283758


            Actually, full disclosure, we really just rewrote a couple of components in Rust.

            То есть, по их собственным словам, пару компонентов переписали — остальное все ещё на Go.


          1. eao197
            26.02.2018 13:17

            Я-то это понимаю, но в статье сказано буквально «Поэтому хранилище переписали на Rust, и проблема с памятью решила». Отсюда и первоначальный комментарий.

            На счет первых экспериментов. В 2016-ом была информация о том, что код на Rust уже работает в Magic Packet. Все это обсуждалось в двух местах:
            news.ycombinator.com/item?id=11282948
            www.reddit.com/r/rust/comments/4adabk/the_epic_story_of_dropboxs_exodus_from_the_amazon
            В разных комментариях этих обсуждений.


            1. VulvarisMagistralis
              26.02.2018 15:27

              На счет первых экспериментов. В 2016-ом была информация о том, что код на Rust уже работает в Magic Packet.

              Да, как раз 2 года назад, в 2016 и были эти первые эксперименты. О них и речь.
              Эксперименты были полноценными, с внедрением в production, да. И успешными, да. Но с тех пор, как видим, необходимости что-то переписывать на Rust, кроме пары этих критичных компонент и нет.


              1. eao197
                26.02.2018 15:31

                Простите мне мою дотошность, но если в 2016-ом году было заявлено об успешном использовании Rust-а в продакшене, то эксперименты должны были начаться сильно раньше. С учетом того, что Rust использовала совсем небольшая команда и было написано 60KLOC, то процесс этот стартовал уж не как не позже 2015-го года.

                Но с тех пор, как видим, необходимости что-то переписывать на Rust, кроме пары этих критичных компонент и нет.
                Ну вот как раз никто еще не смог толком сказать о том, что же было «с тех пор». Может там серьезное переписывание MagicPocket с Go на Rust идет.


                1. VulvarisMagistralis
                  26.02.2018 16:21

                  Может там серьезное переписывание MagicPocket с Go на Rust идет

                  Наш человек в Дропбоксе Slava Bakhmutov ( Dropbox SRE, twitter.com/M0sth8 ) утверждает, что так и есть до сих пор: буквально пара самых высоконагруженных мааааленьких компонентов на Rust, большая часть на Go и небольшие остатки от предыдущей реинкарнации Дропбокса на Python.


  1. VulvarisMagistralis
    26.02.2018 10:44

    Rust используется и в Dropbox — на этом ЯП написано ядро их продукта.


    Написан чрезвычайно маленький кусочек… да, это один из самых высоконагруженных компонентов. Но это не ядро.


  1. worldmind
    27.02.2018 20:57

    Как я понял раст скорее язык системного программирования, это ниша си и плюсов, даже с го его не совсем корректно сравнивать, го где-то в промежутке между системным и прикладным т.к. в го вроде нет управления памятью.
    Поэтому думая про раст надо понимать зачем вам системный язык — у вас должны быть или системные задачи или предельная нагрузка.


    1. WFrag
      27.02.2018 21:51

      Я, кстати, не совсем согласен с этой точкой зрения. У Rust довольно большой потенциал в прикладных задачах. Он безопасный, с адекватной эргономикой и достаточно большими возможностями в плане построения абстракций (товарищи хаскеллисты, не бейте, пожалуйста!).

      При этом по законам материалистической диалектики, возможен переход от количества к качеству.

      Наприер, когда твое приложение «само по себе» работает в N раз «быстрее» аналогичного на Java, это открывает дополнительные возможности. Там, где была bulk обработка вдруг оказывается целесообразной реалтайм обработка, там где нужен был кластер, можно обойтись одним узлом. Я знаю компании, которых разорили счета с AWS. Можно невооруженным взглядом наблюдать проблемы производительности, например, на мобильных устройствах. Я наблюдал постепенное угасание производительности систем на Java.

      Спасёт ли Rust от этого? Не знаю, но у него хороший задел.

      При этом традиционный аргумент против таких языков был «дорого обходится разработка», из-за безопасности, из-за большей сложности управления памятью, и.т.д. Rust, на мой взгляд, довольно хорошо поднимает планку эргономичности разработки и при этом всё-равно оставляет возможность залезть поглубже и применить суперспособности типа (таких).

      Значит ли это, что надо RIIR? Нет. Но совсем откидывать Rust, как «системный язык» тоже не стоит.

      Как-то так.