News for hackers. Stuff that matters.
Re:Falling in love with Rust by brian-armstrong on Tuesday September 18, 2018 @09:32PM (#18020941)
One of the things that's turned me off about Rust is that a lot of code seems().to().chain().lots().of().operators()

Is this idiomatic? It seems powerfully indecipherable/illegible

Re:Falling in love with Rust by gamegoblin on Tuesday September 18, 2018 @11:13PM (#18021390)
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!)
Re:Falling in love with Rust by Spiritus on Wednesday September 19, 2018 @03:14AM (#18022377)
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.
Re:Falling in love with Rust by thibran on Wednesday September 19, 2018 @04:30AM (#18022739)
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...

Re:Falling in love with Rust by drudru11 on Sunday September 23, 2018 @04:01AM (#18049974)
This is called the 'pyramid of doom' in the nodejs circles
Re:Falling in love with Rust by zinid on Wednesday September 19, 2018 @02:51AM (#18022276)
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.
Re:Falling in love with Rust by settler4 on Wednesday September 19, 2018 @04:42PM (#18027535)
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.

Re:Falling in love with Rust by staticassertion on Tuesday September 18, 2018 @09:38PM (#18020963)
It's often idiomatic. I've never found it to be indecipherable at all. I actually find it to be quite readable in most contexts where intermediate variables are just noise.

Iterators are a typical example of this.

vec![0, 1, 2, 3].into_iter() .filter(|x| x % 2 == 0) // Keep the evens .map(|y| y + 1 ) // Add 1 to elements .rev(); // Reverse the iterator

Adding intermediates would just add noise for code like this.

Re:Falling in love with Rust by smittywerben on Tuesday September 18, 2018 @11:40PM (#18021510)
It helps me with autocomplete. In Python at least, I find

  int.__add__(a, b)
is less idiomatic than

  a.add(b)
which removes the global abstract. Though I see it looks less symmetric.

I'm not a Rustacean - I only speak to the syntax difference.