News for hackers. Stuff that matters.
Re:Rust's 2017 roadmap, six months in by Lerc on Wednesday July 05, 2017 @07:03PM (#14706858)
One of the things that I'd like to see for the Rust Book is some form of "Here's how to use it in a function".

For example, Taking a random piece of code from the Rust Book

    let buffer: &mut [i32];
    let coefficients: [i64; 12];
    let qlp_shift: i16;

    for i in 12..buffer.len() {
        let prediction = coefficients.iter()
                                     .zip(&buffer[i - 12..i])
                                     .map(|(&c, &s)| c * s as i64)
                                     .sum::<i64>() >> qlp_shift;
        let delta = buffer[i];
        buffer[i] = prediction as i32 + delta;
    }

How would one break part of this into a function

    fn get_part ??? What might go here ???  

    let buffer: &mut [i32];
    let coefficients: [i64; 12];
    let qlp_shift: i16;

    for i in 12..buffer.len() {
        let prediction = get_part(&coefficients,&buffer,i)
                                     .map(|(&c, &s)| c * s as i64)
                                     .sum::<i64>() >> qlp_shift;
        let delta = buffer[i];
        buffer[i] = prediction as i32 + delta;
    }

[Exercise for the reader] I'm not sure If I could write the code to do this without taking a few wrong turns.
Re:Rust's 2017 roadmap, six months in by trishume on Wednesday July 05, 2017 @09:39PM (#14707587)
Iterators are the main place this is difficult, but as steveklabnik says the compiler can tell you the return type.

However, this will get better with the introduction of "impl Trait", where the return type will become `impl Iterator<Item = (i64, &[i32])>` which while admittedly long is better than what you'd have otherwise. It's definitely a known pain point.

In practice writing Rust code (full time!) I don't encounter this issue much because I rarely want to split an iterator chain across multiple functions, and iterators are the main place the types get long and hairy. Although I've heard it's really bad with Futures, but that's why "impl Trait" is coming.

Re:Rust's 2017 roadmap, six months in by steveklabnik on Wednesday July 05, 2017 @07:48PM (#14707127)
Well, this code in particular is presented as "hey there's no context." If I were to try to extract this, I would take each of those lets and make them an argument, then see what the compiler says for the return type, done.
Re:Rust's 2017 roadmap, six months in by pjmlp on Thursday July 06, 2017 @12:25AM (#14708124)
This is one example where having a REPL would help a lot.

That is how I check such types outside IDEs in other ML derived languages.

Re:Rust's 2017 roadmap, six months in by roblabla on Thursday July 06, 2017 @06:05AM (#14709227)
TBF, you can just do

    let _ : () = /* some expr whose type you don't know */
And compile it. It will quickly fail with a type error, giving you the full type of the expression.
Re:Rust's 2017 roadmap, six months in by pjmlp on Thursday July 06, 2017 @06:51AM (#14709400)
Yeah, but it feels like a kluge, specially when used to F# on Visual Studio.
Re:Rust's 2017 roadmap, six months in by Lerc on Wednesday July 05, 2017 @10:25PM (#14707740)
How do you find out what the compiler says for the return type? Is that covered in the book somewhere? I feel like this might help me quite a bit in my struggles.
Re:Rust's 2017 roadmap, six months in by bbatha on Wednesday July 05, 2017 @10:31PM (#14707759)
I commonly let the compiler error out by specifying the wrong type or leaving off a type annotation. For instance, https://is.gd/8lLrY8
Re:Rust's 2017 roadmap, six months in by steveklabnik on Wednesday July 05, 2017 @11:15PM (#14707922)
one way is to do

    return SOME_EXRPRESSION;
and then look at the compiler error. Another way is

    let () = SOME_EXPRESSION;
which works as long as SOME_EXPRESSION is not of type (), but if it compiles, well, you know the type :)

Another way is to use some sort of IDE integration that gives you "show me the type on hover".