That'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/m...My suspicion is the people do this to avoid "variable does not live long enough" type errors.
Re:Falling in love with Rust
by gamegoblin on Wednesday September 19, 2018 @03:36AM
(#18022473)
I 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.
The 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=7ea1a39971399d0429f0369cb9e...
This is called the 'pyramid of doom' in the nodejs circles
Well, 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.
Doesn'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?
Re:Falling in love with Rust
by gamegoblin on Wednesday September 19, 2018 @05:06PM
(#18027712)
No, 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.
Consider the imperative code:
I think the chained combinator approach is much easier to see exactly what's happening (and is often higher performance!)