LINUX.ORG.RU
Форум — Talks  

Rust 1.21

 ,


1

4

Так как никто не хочет писать новость, то просто закину сюда.

https://blog.rust-lang.org/2017/10/12/Rust-1.21.html

The Rust team is happy to announce the latest version of Rust, 1.21.0. Rust is a systems programming language focused on safety, speed, and concurrency.

Главное

Изменено поведение литерала & в некоторых случаях:

use std::thread;

fn main() {
    let x = &5;
    
    thread::spawn(move || {
        println!("{}", x);
    }); 
    
}
Данный код не скомпилируется на предыдущих версиях из-за 'borrowed value doesn't live long enough'. Но в новой версии код успешно компилируется, потому что добавили еще немного сахара. Теперь код let x = &5 будет эквивалентен этому:
static FIVE: i32 = 5;

let x = &FIVE;

for_each теперь stable

// old
for i in 0..10 {
    println!("{}", i);
}

// new
(0..10).for_each(|i| println!("{}", i));

Шо, опять? Еще старый срач не остыл.

bread ☆
()

(0..10).for_each(|i| println!(«{}», i));

Ну пипец, кто-то обкололся рубями.

bread ☆
()

Лол. Нахуа в языке системного программирования говно вроде этого for_each, а также всяких map, filter и иже с ними? Чтобы задавать побольше тупых вопросов об аллокациях при использовании этого шлака на собеседованиях?

Joe_Bishop ★
()

let x = &5;

rvalue-ссылки из c++?

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

Почему в прошедшем времени?

Плохо построил предложение.

kirk_johnson ★☆
()

Мне это почему-то напоминает перл, с его чудными

die("we are so fucking dead oh noes fatal errors herp derp") unless ($everything_is_ok);
kirk_johnson ★☆
()
Ответ на: комментарий от Joe_Bishop

Нахуа в языке системного программирования говно вроде этого for_each, а также всяких map, filter и иже с ними? Чтобы задавать побольше тупых вопросов об аллокациях при использовании этого шлака на собеседованиях?

У них «ненастоящий» map, если под настоящим понимать map из функциональных языков (откуда он и пришёл).

Rust-овский map это mapM из хаскеля. А новый for_each это mapM_.

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

Crocodoom ★★★★★
()

Я только закончил 1.20 собирать.

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

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

https://www.ncameron.org/blog/how-fast-can-i-build-rust/

There is a disadvantage, however: using multiple codegen units means the program will not be optimised as well as if a single unit were used. This is analogous to turning off LTO in a C program.

The compilation unit in Rust is a crate; that is, the Rust compiler analyses and compiles a single crate at a time.

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

7 лет - это в спешке? ~50% времени все равно отжирает llvm.

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

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

Да. Но мне не стыдно, я ж не пишу на нём ;) А что ты имел ввиду?

То, что от руби этот язык далек настолько, насколько это вообще возможно.

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

Обычно пишут, что смысла от распараллеливания мало. Мол проще не заморачиваться.

Они пытаются выехать на инкрементальной сборке.

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

Обычно пишут, что смысла от распараллеливания мало. Мол проще не заморачиваться.

Не работает — не нужно :D С другой стороны, если не быть ослом и разбивать на мелкие crate'ы (а не как в C++), то действительно пофиг.

Они пытаются выехать на инкрементальной сборке.

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

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

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

Не работает — не нужно

Эксперименты были, профита - нет.

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

Он видит похожий (на самом деле нет) синтаксис

А на самом деле что? Вот это говно

(0..10).for_each(|i| println!("{}", i));
особенно. Авторы хоть не скрывают свои девиации, а фанбои стесняются, бгг.

bread ☆
()
Ответ на: комментарий от theNamelessOne

О, вспомнил, на самом деле раст это окамл. Так сказал ребе тылганер. Веруйте!

bread ☆
()
Ответ на: комментарий от lochness

А на Руби похоже такой записью:

Как будто синтаксис Руби — это что-то плохое.

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

Лол. Нахуа в языке системного программирования говно вроде этого for_each, а также всяких map, filter и иже с ними?

Ты забыл объяснить, почему все эти комбинаторы — говно.
Нужны они (и остальные замечательные и полезные комбинаторы) чтобы работать с итераторами. Итератор выдаёт итемы типа Option<T>: или Some(T), или None. Чтобы не пердолиться в цикле (псевдокод):

let mut v = Vec::new();
for i in <Iterator> {
    match i {
        Some(T) => v.push(func(i)),
        None => break
    }
}

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

let v: Vec<T> = <Iterator>.map(|i| func(i)).collect(); // здесь вдобавок вектор `v` можно создать неизменяемым, в отличие от ручного пердолинга в первом варианте
Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 2)

Теперь код let x = &5 будет эквивалентен этому:

static FIVE: i32 = 5;
let x = &FIVE;

Хорошо хоть этот код не запускает ядерную бомбу. Локальная привязка создает глобальную, мда.

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

Ты забыл объяснить, почему все эти комбинаторы — говно.

А хотя бы возьми свой «элегантный» пример, но не тупо пропускай None-ы, а считай их число. Цикл останется почти неизменным, а комбинатор твой?

Потому что вы, функциональщики, не особо понимаете, что такое программирование, а вместо этого считаете строчки. Только это как спички, один в один. В реальном мире мы просто пишем компоненты с фиксированными интерфейсами и потом соединяем их.

А когда функциональщики добираются до реальных задач, получается Spark, в котором даже нельзя в один проход раскидать разные данные по разным приёмникам, как раз из-за вашего (прямого аналога) map.

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

Ты забыл объяснить, почему все эти комбинаторы — говно.

А хотя бы возьми свой «элегантный» пример, но не тупо пропускай None-ы, а считай их число. Цикл останется почти неизменным, а комбинатор твой?

Извини, я забыл, что критиканы хаят Rust, не зная его. None сигнализирует о том, что итерация закончилась, поэтому кол-во None всегда равняется 1.

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

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

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

Знаю. Кажется диапазон захватывает значения от -5 до 255. Но тот факт, что на Филиппинах еще 50 лет назад кушали людей, не оправдывает людоедства вообще, к примеру. В Питоне так сделали оптимизации ради, уменьшить накладные расходы для наиболее используемых чисел, в качестве, например, индексов.

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

А хотя бы возьми свой «элегантный» пример, но не тупо пропускай None-ы, а считай их число.

А когда функциональщики добираются до реальных задач, получается Spark, в котором даже нельзя в один проход раскидать разные данные по разным приёмникам, как раз из-за вашего (прямого аналога) map.

Давай ты нормально поставишь задачу? Посмотрим, как она будет решаться в функциональном стиле. Только не забудь написать её решение в императивном стиле, чтобы было понятно, о чём же всё-таки речь. Иначе всё это останется необоснованным набросом.

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

using multiple codegen units means the program will not be optimised as well as if a single unit were used.

Т.е. они не осилили whole program optimization. Грустно, что. Надеюсь, это когда-нибудь починят.

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

Языки ассемлера или Фортран - дальше.

Ассемблер — не язык. Это формат записи. В Fortran таки к Ruby поближе будет. В них обоих, в отличии от Rust, есть это ваше ООП из коробки, например.

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

используем элегантный map

Ладно map, это бывает удобно. Но foreach бредовый зачем? Теперь вся хипстота будет именно так писать везде вместо скучного фора, вот увидишь.

bread ☆
()
Ответ на: комментарий от Virtuos86

Кстати, что там с моим любимым перлизмом, не запилили еще такое:

do_this && do_that && do_yet_another_cool_trick || do_something_else unless puk

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

используем элегантный map

Ладно map, это бывает удобно.

Иногда? Угу.

Зачем for_each? Для единообразия:

// old
for i in (0..100).map(|x| x + 1).filter(|x| x % 2 == 0) {
    println!("{}", i);
}

// new
(0..100)
    .map(|x| x + 1)
    .filter(|x| x % 2 == 0)
    .for_each(|i| println!("{}", i));
for_each как map, но map принимает функцию, которую применяет к каждому элементу итератора, а for_each принимает процедуру.

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

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

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

Эти операции нельзя перегрузить в Rust, поскольку они вычисляют правый операнд, только если это необходимо. Например, если в do_this && do_that do_this не является истиной, то do_that вычисляться не будет. Поскольку на это поведение нельзя повлиять, то и перегружать их нет смысла, а значит нельзя.

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

Дошло, что ерунду написал :). В for на самом деле никакого match тоже не будет. Но ручное заполнение вектора останется,от этого map освобождает действительно.

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

Там сначала хвостовой unless вычисляется, и если никто не пукнул, то мегаоднострочник вообще не исполнится. Такая кулфича.

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

С 98 года разлагают C++, но он выстоит!

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

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

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

Давай конструктив. Пили пример «усложнённой логики» в императивном стиле, а мы тебе постараемся в функциональном стиле это переписать. Иначе останется набросом.

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

Чоо

Серьёзно, вместо того, чтобы заканчивать итерацию, когда закончилась итерация, они каждый раз возвращают Option?

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

вместо того, чтобы заканчивать итерацию, когда закончилась итерация

А когда закончилась итерация? Как итератору подать сигнал, что всё, хватит меня дергать, я всё отдал, что было? Option это как раз удобный способ подавать сигнал конца итерации.

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