172 похожих чатов

А был где-нибудь рфц/обсуждение про то, чтобы сделать expression из

for/while?

66 ответов

22 просмотра

А зачем?

они и так выражения, только ничего полезного (в отличие от loop) не могут вернуть https://doc.rust-lang.org/reference/expressions/loop-expr.html

kitsu- Автор вопроса
Alexander Chichigin
А зачем?

удобненько же, вместо let mut val = None; while .. { ... if cond { val = Some(kek); break; } ... } let val = val; писать просто let val = while .. { ... if cond { break kek; } ... };

kitsu
удобненько же, вместо let mut val = None; while ....

И прибить циклы гвоздями к Option? Ну такое...

kitsu- Автор вопроса
Alexander Chichigin
И прибить циклы гвоздями к Option? Ну такое...

Почему бы и нет? Вроде вполне себе тип для большинства случаев

kitsu
Почему бы и нет? Вроде вполне себе тип для большин...

В принципе, вариант, но слишком opinionated для Rust IMO.

kitsu- Автор вопроса
kitsu- Автор вопроса
kitsu
ну да, выходит такой рфц это breaking-change

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e089da8e17b81b75745f63d888bbcdb9 ну вот зачем так делать :\

kitsu
ну да, выходит такой рфц это breaking-change

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

kitsu
удобненько же, вместо let mut val = None; while ....

на самом деле там просто else должен быть, даже вроде был рфц

kitsu
см пример выше

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

kitsu- Автор вопроса
вафля'
на самом деле там просто else должен быть, даже вр...

let val = while .. { ... } else { // executed if no break occurred };

kitsu- Автор вопроса
kitsu
Во, точно, такой даже видел да

https://github.com/rust-lang/rfcs/blob/master/text/3137-let-else.md вот такой только нашел, для циклов не вижу

вафля'
let val = while .. { ... } else { // execu...

else ветка должна выполняться, если цикл ни разу не выполнялся.

kitsu
https://github.com/rust-lang/rfcs/blob/master/text...

https://internals.rust-lang.org/t/pre-rfc-break-with-value-in-for-while-loops/11208 там ссылки есть на другие дискуссии

вафля'
на самом деле там просто else должен быть, даже вр...

полноценного рфц, вроде, про это так и не завели же,да?

Alexander Chichigin
else ветка должна выполняться, если цикл ни разу н...

почему? let mut x = true; let val = while x { x = false; } else { 0 }; не сможет вернуть значение, в твоём случае

kitsu- Автор вопроса
kitsu
https://github.com/rust-lang/rfcs/blob/master/text...

https://github.com/rust-lang/rfcs/pull/3163 вот нашел свеженько закрытый

вафля'
почему? let mut x = true; let val = while x { ...

Он просто не типизируется. Тело цикла должно "возвращать" значение того же типа, что и else ветка. Я вообще не понимаю, зачем нужны циклы, которые возвращают единственное значение. Циклы нужны чтобы накапливать значения — т.е. они должны работать с моноидальными типами.

Alexander Chichigin
Он просто не типизируется. Тело цикла должно "возв...

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

Traveller Kolsky
Ерунда, break может быть недостижим, иначе цикл не...

Цикл и вообще может не завершаться — я не понимаю, чего вы на break завязываетесь. Для Rust-style логично было бы ориентироваться на последнее выражение в теле цикла, так же как для функций.

kitsu- Автор вопроса
Alexander Chichigin
Цикл и вообще может не завершаться — я не понимаю,...

исполнение тогда совсем не очевидным выходит имхо

kitsu
исполнение тогда совсем не очевидным выходит имхо

Именно поэтому это не очень хорошая идея в принципе. Особенно, в отсутствии явных моноидов. Хотите посмотреть на "крутые" "циклы как выражения" — посмотрите на loop macro в Common Lisp или на Ruby. Я не фанат ни первого, ни второго решения.

kitsu- Автор вопроса
Alexander Chichigin
Именно поэтому это не очень хорошая идея в принцип...

да, в рфц выше уже привели кейсы с питона и еще чего-то, там опыт вышел так себе

kitsu
да, в рфц выше уже привели кейсы с питона и еще че...

Ну, Лисперы-то любят свои сверхмощные циклы, а вот Рубисты действительно не пользуюся, да большинство и не знает про такое. 😊

Alexander Chichigin
Он просто не типизируется. Тело цикла должно "возв...

let mut x = true; let val = while x { if false { break 1; } x = false; } else { 0 }; ? Циклы могут, например, искать или акомулировать значение. Тот-же find это for x in xs { if x == v { break Some(x) } } else { None }

вафля'
let mut x = true; let val = while x { if false...

В питоне кстати есть else для циклов, который выполняется когда break не было: https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops

вафля'
let mut x = true; let val = while x { if false...

К break привязка идёт потому что break это return для лупов, по сути. И потому что та же привязка есть для loop{} else же нужен, потому что в отличии от loop{} другие циклы могут завершиться до достижения break, вроде всё логично

вафля'
let mut x = true; let val = while x { if false...

Смотрите, у нас есть кучка вариантов, не все из которых исключают остальные: 1. бесконечный цикл 2. цикл выполнился 0 раз 3. цикл выполнился N раз 4. в процессе выполнения дошли до break 5. до break выполнение никогда не доходило И нам нужно ответить на 2 вопроса по каждому случаю: а) какая семантика у этого случая, б) как мы этот случай типизируем. В частности, мне непонятно как Вы хотите типизировать случай 5, особенно если никаких break внутри цикла вообще нет?

вафля'
К break привязка идёт потому что break это return ...

И вот как в функции можно дойти до конца функции без явного return — так и в цикле, если это не loop. Значит, и типизировать их нужно аналогичным образом.

вафля'
let mut x = true; let val = while x { if false...

Десахаринг вроде тоже тривиальный, можно хоть макросом сделать: while cond { if false { break 0; } } else { 1 } <=> loop { if cond { if false { break 0; } } else { break 1; } }

вафля'
Десахаринг вроде тоже тривиальный, можно хоть макр...

Срабатывание else ветки всегда при нормальном завершении цикла? Несколько контринтуитивная семантика. 🤷‍♀️

Alexander Chichigin
Смотрите, у нас есть кучка вариантов, не все из ко...

случай 5 типизируется else'ом. while cond {} else { x } всегда "возвращает" x, если цикл не бесконечный

вафля'
случай 5 типизируется else'ом. while cond {} else...

А откуда мы должны знать, бесконечный он или нет? 😉

Alexander Chichigin
И вот как в функции можно дойти до конца функции б...

Нет. Доход до конца функции её завершает, а доход до конца цикла — нет. loop {} и так бесконечный, нем не нужно писать loop { continue }, чтобы он не завершился на первой итерации и не "вернул" ()

Alexander Chichigin
А откуда мы должны знать, бесконечный он или нет? ...

А какая нам разница? Мы всегда предполагаем что в данном случае после завершения цикла, возвращается x. Если цикл бесконечный, то мы просто никогда не дойдём до этого

Alexander Chichigin
Срабатывание else ветки всегда при нормальном заве...

Это принцип работы ops::ControlFlow и вообще всего, связанного с траем.

вафля'
Нет. Доход до конца функции её завершает, а доход ...

> Доход до конца функции её завершает, а доход до конца цикла — нет. Вот иногда доход до конца цикла его завершает, а иногда — нет. Поэтому и нужен моноид. 😊 А с loop всё понятно, да.

вафля'
А какая нам разница? Мы всегда предполагаем что в ...

ОК, я понял какую семантику Вы предлагаете. Она даже непротиворечивая, скорее всего. Но мне кажется контринтуитивной, я бы так не стал делать, и пользоваться тоже не стал. 🤷‍♀️

Alexander Chichigin
Смотрите, у нас есть кучка вариантов, не все из ко...

1. Ничего не возвращает, типизация else. 2. Вернёт то, что в else. 3+4. Вернёт то, что в break, типизируется либо else, либо break с инфером else, либо указанием типа с инфером обоих. 3+5. Вернёт то, что в else, прочее эквивалентно п.п. Какой есть другой вариант?

Traveller Kolsky
1. Ничего не возвращает, типизация else. 2. Вернёт...

Другой вариант, очевидно, типизировать как функции — по последнему выражению. break — полнотью аналогично early return. На случай если цикл — в отличие от функции — выполнился 0 раз — блок else, значение в котором должно иметь тот же тип. Семантически — снова как для функции, возвращаем значение последнего выражения с последней итерации или break, если он выполнился. Либо else, если в цикл вообще не заходили. По-моему, это самый прямолинейный вариант, и такой же ограниченный как предложенный Вами с @wafflelapkin потому что нельзя накапливать значения в моноиде. Только руками это делать, но так можно и в обычном цикле уже сейчас. Так что я толку не вижу ни от одного варианта, ни от второго. 🤷‍♀️

Alexander Chichigin
Другой вариант, очевидно, типизировать как функции...

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

вафля'
Такой вариант сильно более ограниченный, т.к. треб...

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

Alexander Chichigin
С чего это он требует? В моём примере вон не созда...

В твоём примере создаётся копия i. Если бы хотелось вернуть условный String, или impl Trait это было бы проблемой. > зачем крутить цикл N раз, чтобы создать одно новое значение? Потому что у нас императивный язык с состояние может меняться между итерациями

вафля'
В твоём примере создаётся копия i. Если бы хотелос...

Вот поскольку язык императивный, мы сравнительно редко создаём новые значения, и часто переиспользуем уже существующие, в особенности — в циклах. 😊

Alexander Chichigin
Вот поскольку язык императивный, мы сравнительно р...

?... Предлагаемый вами вариант while/else требует move возвращаемого значения каждую итерацию

вафля'
?... Предлагаемый вами вариант while/else требует...

Это ж смотря что возвращается. 🤷‍♀️ Можно же и ссылки возвращать. Хотя как на это посмотрит borrow checker — вопрос интересный! 😃

Alexander Chichigin
Он бесплатный. 😊

Да, но не всегда можно вернуть ссылку. Может быть нужно вернуть владение объектом созданным в цикле, например. А если ссылку возвращать, то она объект блокирует, что в цикле может вызывать проблемы.

вафля'
Да, но не всегда можно вернуть ссылку. Может быть ...

Так это всё работает так же как сейчас, нет? 😊

Alexander Chichigin
Так это всё работает так же как сейчас, нет? 😊

Мы обсуждаем не реализованную фичу, сейчас её вообще нет

вафля'
Мы обсуждаем не реализованную фичу, сейчас её вооб...

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

вафля'
В питоне кстати есть else для циклов, который выпо...

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

вафля'
Мы обсуждаем не реализованную фичу, сейчас её вооб...

В итоге зря спорили, походу, label_break_value вполне покрывает все требуемые удобства.

Traveller Kolsky
В итоге зря спорили, походу, label_break_value впо...

ы, всегда забываю что это существует

kitsu
https://github.com/rust-lang/rfcs/pull/3163 вот на...

в целом правильно написали. Используйте итераторы. И ждите негативных гвардов

Alexander Chichigin
Он просто не типизируется. Тело цикла должно "возв...

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

Αλεχ Zhukovsky
в целом правильно написали. Используйте итераторы....

Итераторы частный случай, сообщению сто лет, label_break_value - прекрасная, почти готовая альтернатива

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта