LINUX.ORG.RU

Альфа-версия Rust 1.0

 


2

6

9 января тихо и незаметно вышла альфа-версия Rust 1.0. Этот релиз является этапным в том смысле, что набор возможностей языка зафиксирован и в версиях 1.x значительных несовместимых изменений больше не будет (см. ниже); то же относится и к стандартной библиотеке. Гарантии стабильности означают, что Rust уже можно изучать, не опасаясь скорого устаревания полученных знаний из-за эволюции языка.

Тем не менее, апгрейд в линии от альфа-версии до финальной версии может вызвать мелкие несовместимости (Sync/Send changes, переименование uint/int в usize/isize), но все проблемы планируется решить до выпуска 1.0.

Основные изменения со времени предыдущего релиза:

  • улучшенная поддержка массивов и подобных им контейнеров в языке: DST
  • унификация трейтов и замыканий в виде unboxed closures: теперь замыкания - это просто объекты, реализующие определенные трейты

Полный список изменений с подробным их описанием по ссылке:

>>> Подробности

★★★★★

Проверено: JB ()
Последнее исправление: JB (всего исправлений: 1)

Хорошо. Сам я уже слишком завязан на D, но Rust как язык мне нравится даже больше.

Единственное, что огорчает в алфе 1.0.0 - синтаксис в некоторых местах таки и остался излишне перегруженным спецсимволами, а я надеялся на сокращения для самых типичных ситуаций.

Функции вида from_str в языке с нормальной системой типов выглядят как-то нелепо.

Dicebot
()
Ответ на: комментарий от Dicebot

синтаксис в некоторых местах таки и остался излишне перегруженным спецсимволами

Лямбды? Там планируется доработка вывода, чтобы писать меньше спецсимволов.

tailgunner ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Лямбды? Там планируется доработка вывода, чтобы писать меньше спецсимволов

Лямбды, невозможность использовать макрос вида println!«Hello» для простых строк, уже упомянутый from_str. Когда читал гайд первый раз, обращал внимание на довольно много таких мелочей.

Rust: let i = from_str::<uint>(«5»);

D: auto i = to!uint(«5»);

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

Dicebot
()
Ответ на: комментарий от Dicebot

P.S. для подогрева холивара - Go среди новичков самый бесполезный и годен только для примитивных сервисов (хотя именно в этой нише очень хорош).

Dicebot
()
Ответ на: комментарий от Dicebot
let i: usize = FromStr::from_str("5").unwrap();

Вот пострашнее. :)

numas13
()
Ответ на: комментарий от shty

а как же NSQ?

Надо посмотреть как исходники NSQ и docker будут выглядеть через 5 лет. Написать продукт самое простое, постоянно его поддерживать и улучшать - намного больший вызов для языка.

Dicebot
()
Ответ на: комментарий от umren

ну уже довольно прилично их, и становится все больше, что характерно

shty ★★★★★
()
Ответ на: комментарий от Dicebot

Надо посмотреть как исходники NSQ и docker будут выглядеть через 5 лет

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

shty ★★★★★
()
Ответ на: комментарий от Dicebot

невозможность использовать макрос вида println!«Hello» для простых строк

М? Только что попробовал helloworld в playpen:

fn main() -> () {
  println!("Hello, world!");
}
Hello, world!
Program ended.
tailgunner ★★★★★
() автор топика
Ответ на: комментарий от Dicebot

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

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

Rust: let i = from_str::<uint>(«5»);
D: auto i = to!uint(«5»);

Правильно написали, ты еще обработку Option забыл.

На практике, обычно, ты, когда получаешь этот i, передаешь его в какую-то функцию и компилятор часто сам может вывести тип. Так что очень часто, если где-то рядом есть ... f(i); ..., код можно сократить до let i = from_str("5").expect("err msg"); - уже не так плохо.

От явной обработки ошибок никуда не денешься, да, это часть философии языка. Может, как писал тейлганнер, с монадами чего замутят - но эти экспериметы еще когда будут, нечего пока ванговать.

ozkriff
()
Ответ на: комментарий от Dicebot

сделать изящнее

Примеры?

Deleted
()
Ответ на: комментарий от ozkriff

Правильно написали, ты еще обработку Option забыл

Нет не забыл, меня напрягает именно базовый синтаксис. То, что требуют явную обработку явных вещей - хорошо. Но почему нельзя выводить тип на основе типа аргумента и использовать сигнатуру вида to::<uint>(«5») ? Зачем вообще этот отвратительный синтаксис вида ::<> для обобщённых аргументов?

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

Во всём этом Option как раз таки самое доброе добро.

Dicebot
()
Ответ на: комментарий от Dicebot

Я хочу выбросить скобки для вариантов с одним аргументом, как в D :)

А чо только с одним? Давай как в Хаскеле - без скобок вообще.

tailgunner ★★★★★
() автор топика
Ответ на: комментарий от Dicebot

Но почему нельзя выводить тип на основе типа аргумента

Тип аргумента - строка. Что из него можно вывести?

tailgunner ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

А чо только с одним? Давай как в Хаскеле - без скобок вообще.

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

Тип аргумента - строка. Что из него можно вывести?

Строку? :) Коду конвертера должно быть всё равно по большей части, это &str или String, зачем вообще нужно это явное «_str» в названии функции? Важная информация - целевой тип, а не исходный.

Dicebot
()
Ответ на: комментарий от Dicebot

А чо только с одним? Давай как в Хаскеле - без скобок вообще.

Без скобок вообще читать труднее

...но не вслучае одного аргумента? По-моему, делать syntax sugar имеет случай тогда, когда какой-то вариант использования преобладает, а один аргумент - не такой случай.

Тип аргумента - строка. Что из него можно вывести?

Строку? :)

И как это поможет? Если бы выводился int в from_str::<int>, это было бы полезно.

зачем вообще нужно это явное «_str» в названии функции?

Дело вкуса. Или, например, сразу понятно, что foo - строка: from_str::<int>(foo)

Важная информация - целевой тип, а не исходный.

Не вижу, чем эта целевой тип важнее исходного.

tailgunner ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Дело вкуса. Или, например, сразу понятно, что foo - строка: from_str::<int>(foo)

Не вижу, чем эта целевой тип важнее исходного.

Ну строго формального доказательства важности я предоставить точно не могу :) Это сугубо практические соображние - я пользовался аналогичными инструментами в D (много) и исходный тип не играл значения почти никогда. Более того, его неявный вывод сильно упрощал написание обобщённых функций. Дело вкуса, но я точно знаю, что такой подход со стороны Rust меня будет раздражать очень сильно - а именно такие мелочи и влияют на скорость освоения языка.

Dicebot
()
Ответ на: комментарий от Dicebot

синтаксис в некоторых местах таки и остался излишне перегруженным спецсимволами

Например?

Да и если я правильно понимаю, что такое «токены», то в D не факт, что «лучше». Хотя лично я не вижу в спецсимволах проблемы.

Функции вида from_str в языке с нормальной системой типов выглядят как-то нелепо.

Можно раскрыть мысль? В чём проблема и как должно быть?

DarkEld3r ★★★★★
()
Ответ на: комментарий от Dicebot

невозможность использовать макрос вида println!«Hello» для простых строк,

В смысле? println!(«hello»); вполне работает.

D: auto i = to!uint(«5»);

А что будет, если конвертация невозможна?

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

DarkEld3r ★★★★★
()
Ответ на: комментарий от Dicebot

Я хочу выбросить скобки для вариантов с одним аргументом, как в D :)

Мне эта фичи никогда не нравилась. Однообразие - это неплохо, да и экономия копеечная.

DarkEld3r ★★★★★
()
Ответ на: комментарий от Dicebot

Но почему нельзя выводить тип на основе типа аргумента

Какого аргумента? Если ты про тип переменной куда мы присваиваем, то можно. Если же про «тип в строке», то тоже можно, но другой функцией (parse).

Зачем вообще этот отвратительный синтаксис вида ::<>

Для этот шум не нужен и не используется. А так, наверное, чтобы не было неоднозначностей. Да, не очень изящно, но лучше, чем в С++ с его особыми костылями когда компилятору надо подсказывать, что это шаблонный параметр.

DarkEld3r ★★★★★
()
Ответ на: комментарий от Dicebot

Коду конвертера должно быть всё равно по большей части, это &str или String

Сейчас from_str не умеет работать сo String. Так что для строк «шума» будет ещё немного больше.

А str нужно чтобы показать, что работаем именно со строками, а не с любым типом. «Преобразовывать» любой тип может transmute, правда он делает несколько другое.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Для этот шум не нужен и не используется. А так, наверное, чтобы не было неоднозначностей. Да, не очень изящно, но лучше, чем в С++ с его особыми костылями когда компилятору надо подсказывать, что это шаблонный параметр.

Плохо, если не используется - как раз и возникают странности вида from_str. Сам факт кодирования типа в _название_ функции дурно пахнет в языке с поддержкой шаблонов. А если нужно будет распарсить поток данных, то заводить новую функцию from_byte_stream и делать что-то вроде static if? Чем это лучше StringList?

«лучше, чем в С++» это не слишком большое достижение :)

Мне нравится, когда можно писать типобезопасные обёртки вида castFrom!long.to!int(var) и это читается естественно и без ужаса. Мне нравится, когда для простые и часто используемые случаев есть специальный облегчённый синтаксис. Rust пока что не уделяет этому аспекту вообще никакого внимания.

Кстати, на эту же тему : #[cfg(not(test))] это ещё один синтаксический ужас.

Dicebot
()
Ответ на: комментарий от Dicebot

Плохо, если не используется - как раз и возникают странности вида from_str.

Я немного криво написал: для from_str не нужен дополнительный шум в виде ::<>.

Сам факт кодирования типа в _название_

Не согласен с аргументацией. Тут дело не в типе, а в логике функции. Можно сравнить с to_string из плюсов или других языков. Мы просто явно говорим, что преобразуем тип из строки. Конечно, это не просто «from» ведь мы не можем (этой функцией) выполнять преобразования типов: инты в даблы, инты в строки и т.д.

В языке нет перегрузки функций. Мне это совсем не нравится, но что поделать. Да и не смертельно это. Так что да, будет (если понадобится) и from_byte_stream т.д.

Обобшённость в языке достигается немного иначе. Можно ввести трейт с нужным интерфейсом. Дальше реализовывать его для нужных типов.

castFrom!long.to!int(var) и это читается естественно и без ужаса.

Субъективно.

Ещё раз повторюсь - мне не нравится выкидывание скобок для макросов с одним аргументом. Экономия мизерная, зато однообразие нарушается.

#[cfg(not(test))]

По моему, не смертельно. Выглядит как цепочка вызовов функций, то есть привычно. Не очень элегантно, да. С другой стороны, это сильнее отличается от обычных конструкций языке, чем в D. Возможно, это сочли преимуществом... Кстати, в D вообще есть условная компиляция по произвольному условию? Или только жестко-заданные debug и version?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Кстати, в D вообще есть условная компиляция по произвольному условию?

static if (compile-time-evaluated-condition) { // code here }

Экономия мизерная, зато однообразие нарушается

А соотношение логики к «шуму» - ухудшается :) Однообразие должно быть в семантике, в синтаксисе от него не слишком много пользы.

В языке нет перегрузки функций. Мне это совсем не нравится, но что поделать. Да и не смертельно это. Так что да, будет (если понадобится) и from_byte_stream т.д.

Пока что это кажется очень неприятным. Вот есть задача - привести в рамках обощённой функции аргумент к строковому представлению (точный тип строки тоже задан параметром шаблона). В D я бы написал что-то очень простое:

void foo(S, T)(T arg)
    if (isSomeString!S)
{
    auto s = to!S(arg);
}

И для кода конкретно этой функции не важно, для преобразования вызывать from_str или from_byte_array или from_int. Это не её дело, знать такие вещи.

Как аналогичные вещи предполагается делать на Rust?

Dicebot
()
Ответ на: комментарий от Dicebot

static if (compile-time-evaluated-condition) { // code here }

Про static if знаю, но в С++ можно директивы препроцессора извне передавать. В D есть для этого механизм? Только не дебаг уровень и не версию, а именно условие для такого if.

А соотношение логики к «шуму» - ухудшается :)

Иногда «многословие» не вредит. Скажем, в С++ не надо указывает брейк в свитче, а в D требуется явно писать continue. Многословнее, но спасает от ошибок.

Хотя в данном случае, мне просто!не!нравится!такой!синтаксис.

Кстати, в D правда используются конструкции «>>>=», " !<>=" и т.д.?

Как аналогичные вещи предполагается делать на Rust?

В расте шаблоны (дженерики) работают иначе. Произвольные методы вызывать нельзя. Поначалу это меня тоже раздражало. Делать придётся примерно вот так:


trait ToString {
    fn to_str(&self) -> String;
}

fn foo<T:ToString>(value : T) {
    let a = value.to_str();
}
То есть надо указать, что функция может принимать любой тип, который реализует трейт ToString. Если бы трейт был стандартным, то для стандартных типов уже была бы реализация. Добавлять поддержку для своих типов легко.

Если не хватает гибкости - придётся обратиться к макросам.

Кстати, В С++ шаблоны вынуждены содержаться в хедерах. В D ведь полноценные модули, по идее. Может реализация шаблона быть скрытой?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

В D есть для этого механизм? Только не дебаг уровень и не версию, а именно условие для такого if

Нет, по крайней мере не в формате -DMYDEBUG=43. Обычная практика - иметь модуль вида CTFlags.d который генерируется системой сборки и содержит нужные данные. Вообще WB считает, что если нужно задать что-то круче -version=MyCoolVersion, то у вас проблемы в коде :) У меня нет мнения на этот счёт.

Делать придётся примерно вот так

В моём примере String тоже является параметром шаблона и может быть любым совместимым пользовательским типом. Тут же вроде бы используется жёсткая привязка по типу результата. Меня интересует, можно ли изменить именно это (с системой traits в целом знаком, она ок)

Кстати, в D правда используются конструкции «>>>=», " !<>=" и т.д.?

Никогда не видел в живом коде. Code review в стандартную библиотеку оно бы точно не прошло.

В D ведь полноценные модули, по идее. Может реализация шаблона быть скрытой?

Нет. Неоднократно обсуждалось, можно ли компилировать шаблоны в какую-то промежуточную форму, но они в D слишком мощные для этого, ничего лучше обычных исходников не придумали пока.

(«скрытой» в смысле private может быть, конечно. Но не extern)

Dicebot
()
Ответ на: комментарий от Dicebot

В моём примере String тоже является параметром шаблона и может быть любым совместимым пользовательским типом. Тут же вроде бы используется жёсткая привязка по типу результата. Меня интересует, можно ли изменить именно это (с системой traits в целом знаком, она ок)

trait ToString<S> {
    fn to_string(&self) -> S;
}
fn foo<S, T: ToString<S>>(arg: T) {
    let s = arg.to_string();
}
numas13
()
Ответ на: комментарий от Dicebot

Тут же вроде бы используется жёсткая привязка по типу результата. Меня интересует, можно ли изменить именно это (с системой traits в целом знаком, она ок)

Так?

trait ConvertTo<X: ?Sized> {
    fn to(self: &Self) -> X;
}

impl ConvertTo<String> for i32 {
    fn to(self: &i32) -> String { self.to_string() }
}

impl ConvertTo<f32> for i32 {
    fn to(self: &i32) -> f32 { 0f32 }
}

fn main() {
  let x: String = (123i32).to();
  println!("{}", x);
  let x: f32 = (123i32).to();
  println!("{}", x);
}
tailgunner ★★★★★
() автор топика
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от Dicebot

Обычная практика - иметь модуль вида CTFlags.d который генерируется системой сборки и содержит нужные данные.

То есть, в принципе, можно.

А могут спецификации версии быть вложенными? Как-то так:

version(DigitalMars)
{
    version(full)
    {
        // ...
    }
}

Никогда не видел в живом коде. Code review в стандартную библиотеку оно бы точно не прошло.

Наткнулся на это в списке «токенов» языка. Вот и стало любопытно или это уже реально где-то используется или просто возможно определять свои такие операторы.

но они в D слишком мощные для этого, ничего лучше обычных исходников не придумали пока.

Ну понятно, как в С++. Тогда у растовый дженериков есть и преимущество - так как мы указываем трейт, то реализация не обязана быть в виде сорцов.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от DarkEld3r

А могут спецификации версии быть вложенными?

Да, внутри блока версии может быть любой корректный код.

Тогда у растовый дженериков есть и преимущество - так как мы указываем трейт, то реализация не обязана быть в виде сорцов.

Для этого fat pointer же нужен, считай тот же interface, только неявно. Так себе преимущество, играет роль только там, где важен ABI.

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

Dicebot
()
Ответ на: комментарий от DarkEld3r

А что тут значит знак вопроса? И зачем нам этот трейт?

"?Sized" значит «реализация Sized не обязательна» (по умолчанию она почему-то требуется). Но для приведенного фрагмента это указание не нужно (осталось от попыток сделать преобразование к str).

tailgunner ★★★★★
() автор топика
Ответ на: комментарий от Dicebot

а ABI важен только для публичных библиотек.

Не только. Не все хотят раскрывать исходники.

Да и С благодаря стандартному ABI является «клеем» во всех FFI.

DarkEld3r ★★★★★
()
Ответ на: комментарий от Dicebot

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

http://www.reddit.com/r/programming/comments/2s70mm/thoughts_about_rust_from_...

ozkriff
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.