4 ms·
It's idiomatically done with newline separators, e.g: let sum = vec_of_ints .iter() .filter(|x| x > 5) .map(|x| x.pow(2)) .
by gamegoblin 8y ago
It's idiomatically done with newline separators, e.g:
let sum = vec_of_ints
.iter()
.filter(|x| x > 5)
.map(|x| x.pow(2))
.take(3)
.sum()
That is, iterate my vec, only consider values > 5, square them, take the first 3, them sum them.
Consider the imperative code:
let mut sum = 0;
let mut n = 0;
for x in vec_of_ints {
if x > 5 {
sum += x.pow(2);
n += 1;
if n == 3 {
break;
}
}
}
I think the chained combinator approach is much easier to see exactly what's happening (and is often higher performance!)
- zinid 8y agoWell, dunno, in my opinion both are equally obscure. I personally don't like "dot notation" and that's one of the reason I don't like Rust. The main problem I see with dot notation is the Pigeon hole problem: why sometimes you write x(y) and sometimes y.x()? While the functions in the above example are trivial, there exist not so obvious cases.
- Spiritus 8y agoThat's nice and all. But then you have abominations like this: state .db .send(Queries::GetTopTenHottestYears) .from_err() .and_then(move |res| { result.push(res.unwrap()); state .db .send(Queries::GetTopTenColdestYears) .from_err() .and_then(move |res| { result.push(res.unwrap()); state .db .send(Queries::GetTopTenHottestMonths) .from_err() .and_then(move |res| { result.push(res.unwrap()); state .db .send(Queries::GetTopTenColdestMonths) .from_err() .and_then(move |res| { result.push(res.unwrap()); fut_ok(result) }) }) }) }) .and_then(|res| Ok(HttpResponse::Ok().json(res))) .responder() https://github.com/actix/examples/blob/master/async_db/src/main.rs#L46-L76 https://github.com/actix/examples/blob/master/async_db/src/m... My suspicion is the people do this to avoid "variable does not live long enough" type errors.
- gamegoblin 8y agoI believe that is written that way because it's using futures. Once async/await lands this year, all of the futures combinator madness goes away.
- thibran 8y agoThe code could use closures to split the expression or define local functions on the bottom of the surrounding function (a.k.a Haskell style). This would increase readability a lot. Example: https://play.rust-lang.org/?gist=7ea1a39971399d0429f0369cb9ef1382&version=stable&mode=debug&edition=2015 https://play.rust-lang.org/?gist=7ea1a39971399d0429f0369cb9e...
- drudru11 8y agoThis is called the 'pyramid of doom' in the nodejs circles
- settler4 8y agoDoesn't the chained version still iterate over all the elements and squares them before taking the first 3 bigger than 5? the second version only goes over the minimum necessary elements and then breaks. How can the first be higher performance?
- gamegoblin 8y agoNo, the iterators are "lazy" (pull-based). Both implementations will perform the same amount of work. Oftentimes the iterator will be faster, though, because the compiler can reason about what you're doing easier with an iterator vs. iterating via manual sequential indexing.
- deleted 8y ago[deleted]