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 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.