Комментарии 116
Это смотря какие части имеются в виду :) Типажи, итераторы и подобное — вполне себе. Более высокие материи в ржавчине, да, не так красиво выглядят, конечно, но без толстого рантайма и не понятно как их органично реализовать можно.
Сравните ради интереса пару типовых приложений. К примеру word-count и убедитесь в том, что на Rust потребуется в 2-3 раза больше кода, чем на многих других языках.
Но Rust в итоге это можно простить, потому что на нем сказывается его специализация на thread-safety и те жертвы, на которые он идет ради этого. Только все это делает его несколько узкоспециализированным, и сложно его представить как полноценную drop-in замену тому же C++. Он способен его заменить разве что по мощности синтаксиса и скорости выполнения.
Приходится больше думать, например, о владении объектов (в Java можно практически вообще не думать), но в целом чувствую себя вполне продуктивным. И уж Java-то по количеству кода грех не уделать — в Rust более мощная система построения абстракций (типажи, макросы, аттрибуты, более мощные параметры типов).
Но синтаксиса разного много, это да. Не вижу серьёзной проблемы с точки зрения долгосрочной коммерческой разработки — надо три месяца, будут у тебя три месяца на освоение. Это марафон, а не спринт.
Stackoverflow не показатель ничего в этом плане.
Мне кажется, это как раз показатель. Показатель того, что с ним возникает очень много вопросов.
То, что по Rust задают вопросы не означает ничего плохого. Во-первых там действительно есть некоторые концепции, которые непривычны неподготовленному человеку. Уверен, какие-нибудь темплейты после чистого С казались странной конструкцией. Во-вторых я не припомню, чтобы по какому-то «простому» языку на SO не задавали бы вопросы. Блин, там есть вопрос «как сложить 2 числа с помощью jQuery» с 7000 апвотами. Означает ли это, что сложить 2 числа в JS сложная задача, с которой у многих проблема?
Мы пишем на Rust систему, которую традиционно бы писали на Java (условный «кровавый энтерпрайз»).
Странный выбор.
Хотя… Селектел тоже писал на Haskell свой «кровавый энтерпрайз». Даже получилось. Потом переписали. Почему-то.
Если обьем кода одинаков, а возможностей намного больше
Возможностей выполнить конечную задачу у языков этого типа — поровну совершенно.
Потенциальный путей (вы видимо это обозначаете словом возможности) больше — код лучше не становится, код становится путанее.
Не согласен. Дженерики и макросы очень сильно упрощают код. Да и обработка ошибок в Расте мне сильно приятнее.
Макросы — создают уж больно много головняков. На фоне пользы от макросов, — не стоит оно того.
Обработка ошибок — вкусовщина. В go приняли такую схему не потому что авторы не знали о других способах
К примеру word-count и убедитесь в том, что на Rust потребуется в 2-3 раза больше кода, чем на многих других языках.Лаконичность — далеко не всегда достоинство. Перерлюнуть Forth в этом отношении тяжело, но много вы видели программистов на Forth?
Ручное управление памятью и пресловутое Memory safety тоже нужно дай бог в нескольких процентах реальных проектов.
Ручное управление памятью и пресловутое Memory safety тоже нужно дай бог в нескольких процентах реальных проектов.
Вот для таких проектов он и создан.
А для прочих — есть более удобные Go, Python и пр.
Если с памятью GC кое-как справляется, то вовремя закрывать файлы/сокеты он не умеет. Поэтому у нас в расте всякие Disposable и существуют. В GO полагаю тоже есть какие-то способы полу-автоматически Close вызывать на ненужных объектах. Но когда компилятор не заставляет их закрывать, начинается беда.
Кстати, типовой ответ на это — «так никто не пишет»
Это вы ещё APL не изучали.Изучал как раз. Я ж по специальности математик, не программист.
Но в APL есть проблема: многие математические алгоритмы записываются коротко и просто, но многие другие, не ложащиеся на матрицы — просто ужасно.
Зато APL — в обычном ASCII не записывается. Слишком уж много там спецсимволов.Для таких случаев есть J и его потомки.
В любом случае реальную операционную систему на этом сделать нельзя, на rust или forth — можно. Так что это языки для совсем разных ниш.
в 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) достаточно часто пользуются.
Ну вот вам в довесок для рассуждений еще (на таком аналитическом примере можно разных языков притащить).
{-# 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)
Предлагайте более актуальные примеры, мы с удовольствием их обсудим и, возможно, это станет началом улучшения языка. Rust — развивается не в последнюю очередь в ответ на потребности сообщества. Я же лишь ответил на конкретный комментарий выше, с утверждением "реализации на Rust требуют в 2-3 раза больше кода, чем на других языках", что "несколько преувеличено" ©.
О комментаторе же, подробнее:
Комментатор говорит за лаконичность кода и для примера используют внешнюю либу в своем примере. Понятно что любой код можно завернуть в вызов функции, только это о самом языке говорит ничего.
`println` — это не картина мира о вводе выводе. Даже не картина о выводе. Потому что под капотом забит конкретный кейс вывода в стдаут (в любом языке).
Rust принуждает обрабатывать ошибки — если мы пишем качественный код, им придётся уделять внимание в любом случае, но с Rust — все ошибки явные и их обработка входит в привычку.И вот всплывают действительные различия на уровне семантики языков, а комментатор бодро их игнорит в примере.
Коммуникация — часть процесса управления.О чем это вообще? Вроде ни акторы ни каналы не присутствовали в контексте.
Ну и так далее. Конкретика попыталась появится, но комментатор не ухватил.
Ок, давайте о комментаторе подробней, комментатор не против ;-)
Комментатор говорит за лаконичность кода и для примера используют внешнюю либу в своем примере.
Комментатор пытает честно сравнить объём кода, который потребовался для решения задачи на двух разных языках. Объём кода растёт из всего, в том числе и из подключения внешних модулей, и необходимости создавать служебные объекты, и из необходимости обрабатывать ошибки, что мы и видим на примере Regex.
При этом использованная внешняя либа — находится в так называемом "nursery", который отделён от стандартной либы очень тонкой (сходящей на нет) гранью. Это сравнивается с тем, что в Java аналогичная функциональность закопана в stdlib.
println!
и иже с ним всякие write!
, format!
в Rust доступны программисту без дополнительных телодвижений (если он не делает странного), в Java аналогичные вещи нужно либо импортировать, либо вызывать полностью прописав весь путь к соответствующим классам и это тоже видно на примере кода.
И вот всплывают действительные различия на уровне семантики языков, а комментатор бодро их игнорит в примере.
Эмм, мы можем развить эту тему, наверняка Вы знаете экстремальные примеры, где обработка ошибок — это бессмысленно, больно и много кода? На синтетическом примере с wordcount — здесь негде развернуться.
О чем это вообще? Вроде ни акторы ни каналы не присутствовали в контексте.
То есть, на самом деле Вы просто не поняли о чём речь и из этого преждевременно сделали вывод, что комментатор говорил без конкретики, вместо того, чтобы прямо сообщить комментатору, что он как-то непонятно выразился?
Язык программирования — это таки язык — средство коммуникации, в данном случае человека с машиной. Акторы и каналы здесь ни при чём. Язык должен позволять человеку описывать то, что он хочет получить от машины.
На синтетическом примере с wordcount — здесь негде развернуться.В этом и основной мой посыл был. Пример показывает ровным счетом ничего, но выводов сделано прям как при сравнении тысячи строк.
println! и иже с ним всякие write!, format! в Rust доступны программисту без дополнительных телодвижений (если он не делает странного), в Java аналогичные вещи нужно либо импортироватьТ.е. притащить либу это ни о чем, а импорт целая катастрофа. Это я ёрничаю над объективностью оценки, на самом деле мне лично пофиг и на то и на то (ну кроме идиотского формата в принтлне с перечислением аргументов, вместо использования плейсхолдеров). В плане ио гораздо больше имеет значение работа с файлами. doc.rust-lang.org/1.22.1/std/fs/struct.File.html и что-то я опять не вижу особых различий по примеру, телодвижения ровно такие же как в любом другом языке. Можно рыть глубже и смотреть работу с буфферами для записи/чтения. Зато здесь есть куда более интересный момент с тем, что возвращаемые значения врапнуты (Result), что есть уже далеко не везде. Почему не сравнить это? Вполне практическая вещь, показывающая плюсы (можно спорить насколько жирный плюс, но уж не минус точно).
Про коммуникацию не буду обсуждать, у вас своя волна каких-то теплых человеческих чувств к машине.
Вы напали на бредовый вброс про многословность раста, но сами при этом ответили не особо более качественно.
Пример был лишь конкретным ответом на вброс. Вы с этим ответом очевидно не согласны, но углубляться в детали чего-то более объективного не стремитесь. Ну ок.
Т.е. притащить либу это ни о чем, а импорт целая катастрофа. Это я ёрничаю над объективностью оценки.
Нападка была на многословность и именно она оценивалась, не что-то другое. При этом "притащить целую либу" — тоже было оценено: в случае Java эта "целая либа" — уже притащена в комплекте стандартной, а в случае Rust, хоть и оформлена отдельной либой, но по статусу близка к стандартной.
Точно так же упоминался и особый стиль работы Rust с ошибками. Но ок, пример с io тоже хорош.
Про коммуникацию не буду обсуждать, у вас своя волна каких-то теплых человеческих чувств к машине.
Вам не кажется, что отрицать существование коммуникации "человек-машина", в качестве аргумента используя при этом язвительные эмоциональные ярлыки — несколько… гм… неконструктивно?
же лишь ответил на конкретный комментарий выше, с утверждением «реализации на Rust требуют в 2-3 раза больше кода, чем на других языках», что «несколько преувеличено»
Плюньте. Это ж beduin01. У него все что не D-lang ( RIP праху его ) — то говно.
D — 17 строк кода
Rust — 83 строки
Вопрос. Нафига в 4 раза больше кода писать? Вашу работу по количеству строк кода оценивают? Или для вас самоцель не решение задачи, а графоманство?
Вопрос. Нафига в 4 раза больше кода писать?
Думаю, для каждой пары достаточно различных языков можно найти различные искусственные ситуации, где у одного языка одно выпячивается, а у другого языка — прямо противоположенное.
Спасибо, что практически «Hello, World» предлагаете рассмотреть в качестве примера. То, что вы привели — весьма полезно для студенческих тренировок, согласен.
Но в реальной жизни программы… как бы вам сказать, побольше и посложнее и там вперед выступают иные качества.
Например, в сравнении мелких же примеров применения типа вашего Java тоже здорово сольет. А еще JVM долго стартует. И на этом основании можно сказать, что, к примеру, Perl лучше для «кровавого энтерпрайза» или для Android. Но ведь ПО для Android хорошо управляется Ява-машиной.
Это решение на Rust можно чуть ли не один в один переписать. Разница будет максимум в 10-15 строк (объявлять переменные и писать импорты в одну строку это конечно круто, но нет).
fn word_count(string: &str) -> usize {
line.split_whitespace().count()
}
И действительно, какая же длинная функция получается.
Плюсы вот мейнстрим, а там намного внимательнее нужно быть. И плюс тулзы очень слабо развиты.
Но все равно очень много вещей на них пишут.
Лайфтаймы уж явно проще какого нибудь sfinae для восприятия. А главное раст реально не дает сделать множество видов ошибок просто по недосмотру
И плюс тулзы очень слабо развиты.
Вы об инструментах для С++, которых чуть ли не больше чем для всех прочих языков?
Я бы очень хотел, что бы у плюсов появился более-менее стандартный языковой пакетный менеджер, например. Пока к этому ближе всего https://conan.io, но даже он на практике ооочень далек от совершенства и тем более от общепринятости. Мало того что задача сложная из-за специфики языка и уже существующей инфраструктуры, еще и не так много кто понимает что это вообще нужная штука. :(
еще и не так много кто понимает что это вообще нужная штукаПонимают-то как раз многие, отсюда и такая движуха в развитии менеджеров зависимостей для C++.
Другое дело, что кроме отсутствия явного лидера, есть еще и такой фактор: разработчики в массе своей уже приспособились и каждый коллектив научился решать эту проблему по-своему. Кто-то использует только системы пакетов из своих дистрибутивов. Кто-то применяет git submodules. Кто-то CMake-овские ExternalProject_Add. У кого-то свой велосипед.
Т.е. для большого количества C++ных команд эта проблема тем или иным образом уже решена. И пока нет явного лидера менять что-то работающее на что-то новое готовы не только лишь все :)
У Rust-а в этом плане все гораздо привлекательнее.
Я бы еще сказал, что в плюсах например нет встроенных тулзов для автотестов и приходится заниматься подчас странными шаманствами, чтобы тесты подключить к проекту.
Угу. Сколько крови у меня попил GTest, ужас. https://github.com/0x7CFE/llst/blob/master/cmake/GTest.cmake
Те, кто всё ещё не верят, предлагаю прочитать статью (ну или попробовать что-то большое написать, впрочем YMMV [2]).
Это проявляется везде. Конвертация String в &str (обычно достаточно &my_string, но в каких-то случаях — нет, надо делать .as_str()). Конвертация Option в Option<&str> (ну-ка, быстро, как это делается?). Конвертация &str и String в Cow (и обратно). Создание String из литералов (при том, что это ещё и лишнее копирование — но вроде оптимизация на подходе).
Возможно, конечно, мы просто сильно заморачиваемся и можно было бы просто фигачить String.
[1]. YMMV, в принципе, в Rust можно более безопасно изменять String благодаря строгому borrow checker-у.
[2]. Можно, например, вообще не заморачиваться и просто орудовать String, зависит, от задачи.
Про приведения типов — хз, я порядочно пишу на расте и по ощущениям большая часть преобразований это вообще просто &
или .into()
.
Ну и кстати, компилятор или IDE частенько по делу подсказывают, если что :)
Даже если забить болт на оптимальность, всё равно, в применении к строкам, будут постоянные to_string/clone и довольно неуклюжие операции со строками (впрочем, тут format! сильно помогает).
Я все равно не вижу в этом большей проблемы чем в, например, необходимости явно приводить i32
через as
к f32
или usize
, что уж я точно считаю плюсом языка в большинстве применений.
Но если уж быть честным, то надо признать, что в Rust довольно много вот таких «ритуальных» действий (хотя их количество и сокращают — например, RFC 2005).
Но если уж быть честным, то надо признать, что в Rust довольно много вот таких «ритуальных» действий
Что значит "надо признать"? Это же наоборот одно из достоинств языка — "явность", продуманная "синтаксическая соль" и все такое :)
хотя их количество и сокращают — например, RFC 2005
Эх, Я до сих пор с сомнением к этой инициативе отношусь — как бы не усложнили все этими упрощениями. Ну да посмотрим, может потом проникнусь все ж таки.
Поехали, три варианта, выбирайте на свой вкус (предлагайте свой, лучше!):
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));
}
Ну такое, довольно специфическая задача, кмк. Да и первый вариант, если мы не хотим лезть в "низкоуровневые детали" чем плох? Да, выделения памяти, но мы же хотим высокоуровнево, значит нам не особо и важно.
В целом про "String
vs &str
" — мне это вообще не видится "низкоуровневой деталью", это часть общего фокуса ржавчины со строгим отслеживанием владения и в моей голове оно все скорее как раз высокоуровневая штука про организацию программы и поток данных, а не про байтики в куче и стеке. И все это разделение на значения, изменяемые и неизменяемые ссылки в целом делает программу более поддерживаемой и понимаемой (при правильном применении).
Если бы был некий магический оракул, который бы убивал объекты моментально с уходом последней ссылки и не имел бы всех недостатков GC или подсчёта ссылок (таких как расход памяти на метаданные, давления на кеш в случае GC), ты бы стал заморачиваться с владением?
Или бы просто сделал так, что String — это изменяемая строка, а &str — неизменяемая, которую можно передавать куда угодно и как угодно хранить (считай, аналог Rc но без расходов на подсчет ссылок).
Если бы была такая магическая штука, я бы, конечно, сильно призадумался, но и в таких условиях мне представляется что у ржавого владения-одалживания были бы свои плюсы: по мне, четкое владение ресурсами приводит к более аккуратной и продуманной архитектуре приложений и оно же является уникальным для ржавчины средством в борьбе с извечной проблемой разделяемого бщего состояния.
Или бы просто сделал так, что String — это изменяемая строка, а &str — неизменяемая, которую можно передавать куда угодно и как угодно хранить (считай, аналог Rc но без расходов на подсчет ссылок).
Опять же, да, это бы подняло удобство работы с языком во многих случаях, но и вернуло бы в него целый класс ошибок, связанных с общим имзеняемым состоянием.
В общем, нет, я не считаю разделение значений, изменяющих и неизменяющих ссылок низкоуровневой деталью, а String
(~str
)/&str
разделение является просто одним из продолжений этого подхода.
Во-первых, разделяемое владение и исключительное владение я убирать не предлагаю. Это, разумеется, семантика, а не низкоуровневая деталь.
В-вторых, RAII я тоже убирать не предлагаю — это тоже семантика.
Но конкретно для строк, оба этих пункта неприменимы. Ресурсов никаких за ними нет, кроме памяти, которая по условиям мысленного эксперимента освобождаться будет моментально с уходом последней ссылки. Разделяемые изменяемые строки я тоже не предлагаю.
То есть, никаких новых ошибок бы не было.
Проблема только в том, что такого «оракула» не существует — и именно поэтому мы и имеем некоторое постоянное неудобство при работе со строками (но получаем и преимущества).
Вот, кстати, ещё пример неудобства: users.rust-lang.org/t/extending-lifetime-to-the-whole-function-body/15440
Тоже не особо редкий случай, в общем-то.
HashMap<String, HashSet<String>>
не пробовали использовать? Дописки для удобной работы с таким типом не слишком большие: playground.
Если без HashSet<(String, String)>
совсем никак и хочется выжать последние байты и циклы работы процессора, то можно залезть и в unsafe. Предоставив безопасный интерфейс, конечно. Очень страшный playground
У нас сейчас вариант с Cow, на самом деле, потому что плюс-минус пофиг.
Просто человек вот удивлялся, когда это дескать в Rust низкоуровневые вещи постоянно приходится указывать — я говорю, что постоянно, особенно со строками. Я считаю, что с точки зрения логики прикладной программы все эти жонглирования особо смысла не имеют. С точки зрения корректности программы на Rust — разумеется, с точки зрения производительности — да, конечно.
Ну и потом у некоторых говнокодеров реально бомбит, когда компилятор умнее их.
null
в Rust есть только на уровне небезопасных абстракций ("сырые" указатели и им подобное). Да, код, работающий с ними напрямую, должен об этом беспокоиться — но это в худшем случае несколько абстракций, предоставляющих внешнему коду безопасный интрефейс, а не весь объём кода приложения.
Насколько я вижу, это именно что паники/аборты, а не сегфолты. Они происходят из-за логических ошибок в коде — все логические ошибки еще ни один язык не научился убирать, к сожалению, для этого нужен какой-нибудь фантастический сильный ИИ :)
В servo есть минимум одна большая и сложная абстракция (интеграция с JavaScript-движком mozjs, вариантом SpiderMonkey, который написан на C++), плюс логические ошибки, которые ловят ручные или автоматические assert-ы разных видов, в некоторых случаях недостаточно оптимизированное потребление ресурсов на особо весёлых страницах (например, slither, создающий более 2000 canvas
-ов). Иногда ещё драйверы GPU вылетают.
Однако это капля в море разрабатываемого софта.
Для остальных вещей есть другие языки.
Нет универсального языка, иначе он давно бы покорил мир.
Обидно что при этом как раз на embedded они при этом и не ориентируются — во всяком случае для контроллеров тулчейн вроде бы ещё в детском состоянии и обложен third-party костылями разной степени допиленности, и создаётся впечатление, что для разработчиков это не приоритет.
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 году надежды на что-то стабильное ещё нет. За намерение тоже спасибо, конечно, раньше и этого не было. Но пока очень расплывчато и без ясных планов, так что ещё на год в долгий ящик, во всяком случае с прицелом что-то в боевых условиях попробовать.
Так что либо менять направление развития clang'а, либо переходить на GCC. И то и другое — мягко говоря, непросто.
но в 2018 году надежды на что-то стабильное ещё нет.
Сам Rust как язык еще только-только стабилизировался.
А вы уже хотите стабильность по платформам.
Ну, 1.0 вроде в мае 2015 появился, без малого три года уже. И я скорее хочу чтобы они с позиционированием определились — язык вроде как системный, но в сторону embedded (где он был бы прямо подарком) не смотрит, а смотрит, судя по статьям, в сторону, например, бэкенда — уже прочно оккупированного языками со сборкой мусора.
Плюс блог небезызвестного japaric, который стоит на острие прогресса в этой области.
И еще момент: не надо воспринимать авторов языка, как разработчиков проприетарного софта. Да, многие работают в Мозилле и получают за это деньги. Но развитие языка во многом определяется именно сообществом.
В отличие от питона, перла или других языков где правит «тиран», решения по развитию Rust принимаются сообща и полностью в открытую.
Таким образом, язык такой, каким его хочет видеть активная часть сообщества. И только.
Спасибо за ссылку, хороший доклад. И, да, мне действительно интересно, в том числе с практической точки зрения. Я уже пробовал нырнуть в embedded rust, но выныривал с ощущением, что пока всё хрупко, неофициально и в постоянном движении.
И я понимаю, конечно, что разработчики и сообщество никому ничего не должны. Но и потенциальных разработчиков на Rust не стоит лишать права голоса. Активная часть сообщества — это не только те, кто послал туда патч. Это ещё и те, кто будет его использовать как только он будет более или менее годен к применению в их области (и тогда, возможно, посылать патчи, делать библиотеки, и прочая и прочая). А пока не могут, высказывают своё огорчение, вот как я сейчас. :)
Но и потенциальных разработчиков на Rust не стоит лишать права голоса.
Именно поэтому была выдвинута инициатива #Rust2018, в рамках которой сообщество писало посты со своим видением ориентиров развития на ближайший год со своими пожеланиями и обозначением собственных проблем.
Было написано больше сотни постов, которые потом анализировались и упомянутый выше roadmap как раз был основан на компиляции озвученных идей.
В противном случае, это как раз было бы решение вида «я так сказал», без учета мнения большинства.
Таким образом, язык такой, каким его хочет видеть активная часть сообщества. И только.
Это плохо.
Сообщество желает видеть язык для своей цели.
А целей у людей в сообществе — не счесть.
Тянуть язык в разные стороны — это не гуд.
Надесь, что вы все же заблуждаетесь насчет роли сообщества.
Не путайте, пожалуйста, демократию и анархию.
Что вы, я никак не подозревал сообщество Rust в анархии. Это попросту невозможно в пределах одного языка. Вопрос о стройности, единообразии. Это проблемы любого достаточно большого сообщества. У демократии есть недостатки, органически связанные с ее достоинствами. Когда отвечают за систему «все», — значит отвечает «никто». На самом деле система, конечно же, продолжит работать, потому как все заинтересованы в том, чтобы она работала. Но вот отдельные куски — могут быть даже противоречивы. Когда нет в языкостроительстве «тирана» — стройности языка достичь трудно, если вообще возможно. Как пример, наше обсуждение языков тут в комментариях.
Роль тирана в принятии или убийстве RFC выполняет команда ядра — https://www.rust-lang.org/en-US/team.html — все под контролем :)
Вероятно, имеется в виду Stackoverflow developer survey, в котором уже второй год подряд Rust занимает первую строчку в номинации Most loved language. Согласен, что перевод несколько некорректен.
Так вот она какая каша из топора...
Rust используется и в Dropbox — на этом ЯП написано ядро их продукта.
это для меня стало новостью, летом видел здесь статью о том, что dropbox переписали на Go =) про Rust было ни слова…
последнее время делаю в основном на Go, но все чаще обращаю внимание на Rust, чертовски привлекательный. спасибо.
Изначально оно было реализовано на языке Go, но при больших нагрузках проблемой становилось высокое потребление памяти. Поэтому хранилище переписали на Rust, и проблема с памятью решилась.
Можно ли попросить пруфов для этой истории?
Ибо когда информация об использовании Rust в Magic Pocket появилась пару лет назад, то речь шла о том, что Dropbox уходил с Python-а на Go и написал свою Magic Pocket на Go. Очень сильно выиграв при этом и в производительности, и в ресурсоемкости. И только в одном месте обнаружилась проблема с предсказуемостью поведения кода на Go (из-за GC). Это место переписали на Rust-е. И в итоге вышло что-то порядка 30 или 60 KLOC кода на Rust-е в продукте объемом 1.3 MLOC на Go.
За прошедшие пару лет что-то изменилось?
Вот видео в митапа, в котором про то что dropbox делает. Потом та же команда искала rust разработчика
Для меня английский сильно не родной, но разве где-то в районе 7:35-7:45 докладчик не говорит что-то вроде: «Magic Pocket был изначально написан на Go. И сейчас он все еще большей частью на Go. Может быть 30-40% на Rust-е»?
Это быть не может физически.
Они с Python на Go переходили несколько лет, там большой объем.
Первые эксперименты с Rust начались 2 лет назад.
К настоящему времени не может быть 40% даже если они и решили мигрировать на Rust
https://news.ycombinator.com/item?id=11283758
Actually, full disclosure, we really just rewrote a couple of components in Rust.
То есть, по их собственным словам, пару компонентов переписали — остальное все ещё на Go.
На счет первых экспериментов. В 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
В разных комментариях этих обсуждений.
На счет первых экспериментов. В 2016-ом была информация о том, что код на Rust уже работает в Magic Packet.
Да, как раз 2 года назад, в 2016 и были эти первые эксперименты. О них и речь.
Эксперименты были полноценными, с внедрением в production, да. И успешными, да. Но с тех пор, как видим, необходимости что-то переписывать на Rust, кроме пары этих критичных компонент и нет.
Но с тех пор, как видим, необходимости что-то переписывать на Rust, кроме пары этих критичных компонент и нет.Ну вот как раз никто еще не смог толком сказать о том, что же было «с тех пор». Может там серьезное переписывание MagicPocket с Go на Rust идет.
Может там серьезное переписывание MagicPocket с Go на Rust идет
Наш человек в Дропбоксе Slava Bakhmutov ( Dropbox SRE, twitter.com/M0sth8 ) утверждает, что так и есть до сих пор: буквально пара самых высоконагруженных мааааленьких компонентов на Rust, большая часть на Go и небольшие остатки от предыдущей реинкарнации Дропбокса на Python.
Rust используется и в Dropbox — на этом ЯП написано ядро их продукта.
Написан чрезвычайно маленький кусочек… да, это один из самых высоконагруженных компонентов. Но это не ядро.
Поэтому думая про раст надо понимать зачем вам системный язык — у вас должны быть или системные задачи или предельная нагрузка.
При этом по законам материалистической диалектики, возможен переход от количества к качеству.
Наприер, когда твое приложение «само по себе» работает в N раз «быстрее» аналогичного на Java, это открывает дополнительные возможности. Там, где была bulk обработка вдруг оказывается целесообразной реалтайм обработка, там где нужен был кластер, можно обойтись одним узлом. Я знаю компании, которых разорили счета с AWS. Можно невооруженным взглядом наблюдать проблемы производительности, например, на мобильных устройствах. Я наблюдал постепенное угасание производительности систем на Java.
Спасёт ли Rust от этого? Не знаю, но у него хороший задел.
При этом традиционный аргумент против таких языков был «дорого обходится разработка», из-за безопасности, из-за большей сложности управления памятью, и.т.д. Rust, на мой взгляд, довольно хорошо поднимает планку эргономичности разработки и при этом всё-равно оставляет возможность залезть поглубже и применить суперспособности типа (таких).
Значит ли это, что надо RIIR? Нет. Но совсем откидывать Rust, как «системный язык» тоже не стоит.
Как-то так.
Краткая история Rust: от хобби до самого популярного ЯП по данным StackOverflow