These are chat archives for rust-lang/rust

7th
Jan 2017
Alexey
@KalitaAlexey
Jan 07 2017 12:32

@matanelevi,

use exercises;
use exercises::ExerciseResult;
use exercises::input_generators;

Can be written like:

use exercises::{self, ExerciseResult, input_generators};
@matanelevi,
If I get it right, then the type of current_exercise in let ref current_exercise = self.exercises[self.current_exercise_index]; is Exercise.
Matanel Levi
@matanelevi
Jan 07 2017 12:36
Cool! I didn't knew it
@KalitaAlexey yep
didn't know*
Alexey
@KalitaAlexey
Jan 07 2017 12:36
@matanelevi,
There is no need in 'a in pub struct ExerciseManager<'a> because you initialize exercises with &'static [Exercise]
I don't know what ref means in:
lazy_static! {
    static ref EXERCISES: Vec<Exercise> = {
        let ex_0 = Exercise {
            imp: Box::new(|input| wrapper(input, exercises::exercise_0)),
            input_generator: Box::new(input_generators::input_0)
        };
        let ex_1 = Exercise {
            imp: Box::new(|input| wrapper(input, exercises::exercise_1)),
            input_generator: Box::new(input_generators::input_1)
        };
        let ex_2 = Exercise {
            imp: Box::new(|input| wrapper(input, exercises::exercise_2)),
            input_generator: Box::new(input_generators::input_2)
        };
        vec![ex_0, ex_1, ex_2]
    };
}
@KalitaAlexey I don't know the internal implementation, I just saw how to use it
Alexey
@KalitaAlexey
Jan 07 2017 12:39
@matanelevi,
It is a part of the macro.
Matanel Levi
@matanelevi
Jan 07 2017 12:40
Yep..
@KalitaAlexey Do you have an idea how to get rid of the current_exercise_index and & current_exercise_inupt?
It just doesn' t look good from my opinion
Alexey
@KalitaAlexey
Jan 07 2017 12:45
@matanelevi,
You can get rid of them and use https://doc.rust-lang.org/std/slice/struct.Iter.html
But I would get rid of current_exercise_input and calculate it, but keep current_exercise_index.
Matanel Levi
@matanelevi
Jan 07 2017 12:49
@KalitaAlexey calculate it where?
Alexey
@KalitaAlexey
Jan 07 2017 12:49
match expected_answer_encoded.cmp(answer_encoded) {
    Ordering::Equal => {}
    _ => return ExerciseResult::WrongAnswer,
}
can be written like:
if expected_answer_encoded.cmp(answer_encoded) != Ordering::Equal {
    return ExerciseResult::WrongAnswer;
}
Matanel Levi
@matanelevi
Jan 07 2017 12:50
Makes sense, lol :D
Alexey
@KalitaAlexey
Jan 07 2017 12:50
@matanelevi,
In try_answer.
Matanel Levi
@matanelevi
Jan 07 2017 12:51
The input might be randomized
Alexey
@KalitaAlexey
Jan 07 2017 12:51
@matanelevi,
Then you have no choice.
Matanel Levi
@matanelevi
Jan 07 2017 12:51
@KalitaAlexey So you're saying to keep it as is now?
Alexey
@KalitaAlexey
Jan 07 2017 12:53

@matanelevi,
If I got it right, then yes.
Why

type ExerciseImpl = Fn(Vec<u8>) -> EncodingResult<Vec<u8>> + Sync;

accepts Vec<u8> instead of &Vec<u8>?

Matanel Levi
@matanelevi
Jan 07 2017 12:58
@KalitaAlexey It creates hell of lifetime issues
@KalitaAlexey Nope, actually it is ok
My bad
@KalitaAlexey If I'll try to return from get_current_exercise_input a &Vec<u8> it would be no fun
Alexey
@KalitaAlexey
Jan 07 2017 13:02
Yes, that's right)
I don't like the constant (0) and if EXERCISES is empty, it would panic
Alexey
@KalitaAlexey
Jan 07 2017 13:05
@matanelevi,
Your exercises never empty.
Matanel Levi
@matanelevi
Jan 07 2017 13:06
@KalitaAlexey hypothetically
as a good practice, I don't think this can't be better
Alexey
@KalitaAlexey
Jan 07 2017 13:07
After let ref current_exercise = self.exercises[self.current_exercise_index];
Add let i: i32 = current_exercise and try compiling to see what current_exercise's type is
Matanel Levi
@matanelevi
Jan 07 2017 13:08
just a sec
@KalitaAlexey
= note: expected type `i32`
= note:    found type `&exercise_manager::Exercise`
Alexey
@KalitaAlexey
Jan 07 2017 13:08
I don't understand why)
Matanel Levi
@matanelevi
Jan 07 2017 13:09
@KalitaAlexey let ref
Alexey
@KalitaAlexey
Jan 07 2017 13:10
@matanelevi,
Hm. I will think about it.
Matanel Levi
@matanelevi
Jan 07 2017 13:11
@KalitaAlexey
self.exercises[self.current_exercise_index] returns an Exercise
if I'll bind to to another variable, it will try to move this Exercise, so I'm using let ref to get a reference
@KalitaAlexey &self.exercises[self.current_exercise_index] will work too
Alexey
@KalitaAlexey
Jan 07 2017 13:12
@matanelevi,
The more I know.
Matanel Levi
@matanelevi
Jan 07 2017 13:12
@KalitaAlexey ?
Alexey
@KalitaAlexey
Jan 07 2017 13:12
@matanelevi,
I didn't know that.
Matanel Levi
@matanelevi
Jan 07 2017 13:15
pub fn is_prime(num: u32) -> bool {
    if num == 2 {
        return true;
    }

    let limit = f64::sqrt(num as f64) as u32 + 1;
    for i in 2..limit {
        if num % i == 0 {
            return false;
        }
    }

    true
}
Is there a better way to refactor this?
and this:
pub fn exercise_2(num: u32) -> u32 {
    let mut i = 0;
    loop {
        if is_prime(num + i) {
            break;
        }

        i += 1;
    }

    num + i
}
Alexey
@KalitaAlexey
Jan 07 2017 13:18
pub fn exercise_2(mut num: u32) -> u32 {
    loop {
        if is_prime(num + 1) {
            break;
        }

        num += 1
    }
    num
}
It was about the second.
Matanel Levi
@matanelevi
Jan 07 2017 13:20
@KalitaAlexey thanks for the help :)
Alexey
@KalitaAlexey
Jan 07 2017 13:41
About first:
Take a look at https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any
It can be written like:
pub fn is_prime(num: u32) -> bool {
    if num == 2 {
        return true;
    }

    let limit = f64::sqrt(num as f64) as u32 + 1;
    (2..limit).any(|denom| num % denom == 0)
}
Matanel Levi
@matanelevi
Jan 07 2017 13:46
@KalitaAlexey Cool!!
@KalitaAlexey it's not supposed to be num % denom != 0 ?
Alexey
@KalitaAlexey
Jan 07 2017 13:49
@matanelevi,
Yes it is.
Wait.
pub fn is_prime(num: u32) -> bool {
    if num == 2 {
        return true;
    }

    let limit = f64::sqrt(num as f64) as u32 + 1;
    (2..limit).all(|denom| num % denom != 0)
}
Now it is right.
Matanel Levi
@matanelevi
Jan 07 2017 13:51
Oh yes,
@KalitaAlexey Thanks, you proposal is very cool :)
@KalitaAlexey Actually..
Alexey
@KalitaAlexey
Jan 07 2017 13:52
Oh wait.
I again made a mistake.
pub fn is_prime(num: u32) -> bool {
    if num == 2 {
        return true;
    }

    let limit = f64::sqrt(num as f64) as u32 + 1;
    let has_denom = (2..limit).any(|denom| num % denom == 0);
    !has_denom
}
Matanel Levi
@matanelevi
Jan 07 2017 13:54
@KalitaAlexey Why?
Alexey
@KalitaAlexey
Jan 07 2017 13:54
@matanelevi What why?
Matanel Levi
@matanelevi
Jan 07 2017 13:54

Why this

```
pub fn is_prime(num: u32) -> bool {
    if num == 2 {
        return true;
    }

    let limit = f64::sqrt(num as f64) as u32 + 1;
    (2..limit).all(|denom| num % denom != 0)
}

won't work?

Alexey
@KalitaAlexey
Jan 07 2017 13:55
It will. I confused myself.
Matanel Levi
@matanelevi
Jan 07 2017 13:57
@KalitaAlexey What do you say about this?
pub fn exercise_2(num: u32) -> u32 {
    (num..).find(|num| is_prime(num)).unwrap()
}
actually
pub fn exercise_2(num: u32) -> u32 {
    (num..).find(is_prime(num)).unwrap()
}
Alexey
@KalitaAlexey
Jan 07 2017 13:59
@matanelevi,
You meant
(num..).find(is_prime).unwrap()
Matanel Levi
@matanelevi
Jan 07 2017 13:59
yeap
@KalitaAlexey Bah..
error[E0281]: type mismatch: the type `fn(u32) -> bool {exercises::primes::is_prime}` implements the trait `std::ops::FnMut<(u32,)>`, but the trait `for<'r> std::ops::FnMut<(&'r u32,)>` is required (expected &u32, found u32)
@KalitaAlexey it seems that I must do this:
(num..).find(|&num| is_prime(num)).unwrap()
Alexey
@KalitaAlexey
Jan 07 2017 14:01
@matanelevi,
)
Matanel Levi
@matanelevi
Jan 07 2017 14:03

@KalitaAlexey Why this work

(num..).find(|&num| is_prime(num)).unwrap()

and this not

(num..).find(|num| is_prime(num)).unwrap()
I get that the closure is FnMut(&...)
But why |&var| "unwraps" the reference
Alexey
@KalitaAlexey
Jan 07 2017 14:29
@matanelevi,
because both num and &num are patterns.
When num is used, num is bind to &u32.
When &num is used, num is bind to u32.
Matanel Levi
@matanelevi
Jan 07 2017 14:52
Oh.. from this prespective it makes sense
@KalitaAlexey thanks again!
Andrey Bushev
@reiver-dev
Jan 07 2017 21:38
Hi all!
Could you please help me with trait objects?
  1. trait object without data: what will be the size, will i need to pass &self into functions, will it be actually passed in the compiled binary?
  2. is there way to create trait object with known size? i.e. i have two implementations for the trait, but both have same data. I would not like to box this object, want to keep it sized and clonable. Now this is achieved with adding struct of function pointers, but this is ugly and requires a lot of code. Maybe good enough approach would be a trait object with only static functions (clone can be performed with copying the data and pointer to static trait obj).