Why is rust's for loop not an expression

#1

Newbie here…

We have if expressions:

let x = if z { e1 } else { e2 };

and loop expressions

let x = loop {
break b;
};

but there is no for expression:

let z = for f in it {
    e
};

I expected this to be sugar for let z = it.iter().map(|f| e);
and was surprised when this didn’t parse (or gave () as the type).

Is there some devious reason for this?

0 Likes

Write map as for? have for return iterator?
#2

The for loop can’t return an Iterator. it.iter().map(|f| e) doesn’t do anything. If you had let z = it.iter().map(|f| println!("{}", f)), it would not print anything at all. The iterator doesn’t run until something starts calling next() on it.

The for loop takes an iterator, and then keeps calling its next() until it’s used up. After the for loop is done with the iterator, there’s nothing more in it — it’s consumed entirely. Rust’s iterators are one-time-use only, so there’s nothing left to return.

1 Like

#3

The problem is: what value should z take if iterator is empty? See this thread for one of the proposals:

5 Likes

#4

Thank you ppl! Obvious when you think about it. I just wanted to express this
sentiment because I know when one becomes more versed in any subject one’s original perplexity is hard to remember.

Also it seems (to me!) that, because of this, the for loop is a lonely orphan to all the iterator chaining goodness in rust.

0 Likes

#5

I’d say he’s the elder in this family. One of those who can finish every dispute by listening to all involved and deriving the conclusion on every step of the whole chain, without need of the collect's pet (you know who I’m referring to).

4 Likes

TWiR quote of the week
#6

There’s some interesting history here.

For many years, the advice was to just use a for loop if you needed to exhaust iterators. For example, from 2014:

It’s only last year that iterator grew the .for_each() method, due to changing landscapes:

2 Likes