These are chat archives for rust-lang/rust

3rd
Sep 2017
Robert Peters
@r2p2
Sep 03 2017 08:35
Splitting code into helper methods does not seem to be encouraged in rust https://play.rust-lang.org/?gist=2abb4bf1db827cf0776458ba41b4deee&version=stable
Denis Lisov
@tanriol
Sep 03 2017 09:02
The problem with a helper method is that you can't annotate which parts of the object it can touch, thus it has to borrow the object as a whole.
One workaround is to have a helper method on a field or a helper function that you pass the field(s) needed to.
Robert Peters
@r2p2
Sep 03 2017 09:18
Ah, I see. I've removed &self from the add signature and passed a as &Vec<i32>. That works. I am amazed by the fact that so many people like that. It feels cumbersome to me. But maybe thats the price for being safe.
Denis Lisov
@tanriol
Sep 03 2017 09:20
Well, your example seems pretty strange... starting with fn add that does not perform any addition or modification :-)
Robert Peters
@r2p2
Sep 03 2017 09:21
I can post my actual example if you want.
Aleksey Kladov
@matklad
Sep 03 2017 09:21
@r2p2 it's definitely the price required to enforce safety. However, such restrictions may make your code more readable: for example, you can be sure that helper methods won't change half of the object completely under you feet.
Like, while writing something similar in Java, you can accidentally change the collection in the helper, and then get ConcurentModificationException at runtime.
Robert Peters
@r2p2
Sep 03 2017 09:23
@matklad year, but my helper function receives an immutual reference to self so it can't change anything...
@tanriol https://play.rust-lang.org/?gist=b72a0b85f535b17016430f48ae7a48ed&version=stable won't run in playgrond since it requires external crates...
Denis Lisov
@tanriol
Sep 03 2017 09:39
@r2p2 Why does Mandelbrot need to expose these interfaces at all?
Robert Peters
@r2p2
Sep 03 2017 09:40
Which interfaces do you mean? calc_pixel is not exposed. Am I wrong?
Denis Lisov
@tanriol
Sep 03 2017 09:43
Your Mandelbrot object seems... incoherent. First you create it and then it's unrendered so you can get incorrect pixel values. Then you render it to some internal state that you cannot access without methods and finally get it out pixel-by-pixel?
Denis Lisov
@tanriol
Sep 03 2017 09:49
I'd actually suggest something like the following:
/// Specifies the visible area and max iterations
struct Mandelbrot {
    pub center_x: f32,
    pub center_y: f32,
    pub width: f32,
    pub height: f32,
    pub max_iter: u16,
}
impl Mandelbrot {
    /// Actually render it to a W*H image
    pub fn render_image(&self, w: usize, h: usize) -> image::ImageBuffer { ... }
}
Robert Peters
@r2p2
Sep 03 2017 09:54
I create a Manlbrot object with a specific size and allocate storage for it so that the center point can be moved later without allocating new memory. Yesterday I wanted to draw directly onto the image but I pulled my hair out of my head trying to pass the image buffer as argument to the function. So I thought I should store my ...
What? I've tried returning an image::ImageBuffer<P> yesterday in various forms. Since the documentation says ImageBuffer<P: Pixel, Container> and not just ImageBuffer. :/
Robert Peters
@r2p2
Sep 03 2017 10:01
error[E0243]: wrong number of type arguments: expected 2, found 0
  --> src/main.rs:49:29
   |
49 |     pub fn render(&self) -> image::ImageBuffer {
   |                             ^^^^^^^^^^^^^^^^^^ expected 2 type arguments
Year, dosn't work..
Denis Lisov
@tanriol
Sep 03 2017 10:16
Hmm... yeah, looks slightly more complex...
Denis Lisov
@tanriol
Sep 03 2017 10:21
pub fn render_image(&self, w: usize, h: usize) -> image::ImageBuffer<image::Luma<u16>, Vec<u16>>
And what were the problems with passing an image to render on like?
Robert Peters
@r2p2
Sep 03 2017 10:24
why u16? why Vec? the documentation says nothing about those types
Denis Lisov
@tanriol
Sep 03 2017 10:26
I used u16 as it's the type you used for the return value of Mandelbrot::get
...oops, sorry, haven't noticed you need it to be u8 for saving
As for Container, the documentation for ImageBuffer::new mentions it uses Vec
Actually, reading documentation, the type can just be used as image::GrayImage
Robert Peters
@r2p2
Sep 03 2017 10:38
Oh that works. Where did you got the reference to GrayImage? It is not mentioned in the ImageBuffer document.
Denis Lisov
@tanriol
Sep 03 2017 10:41
I saw you saving the image with image::ImageLuma8 and checked its docs to understand its requirements.
Robert Peters
@r2p2
Sep 03 2017 10:43
Ah, cool. Thanks.
Alyani
@notsonotso
Sep 03 2017 11:52
rustc is soooooo slow :(
stevensonmt
@stevensonmt
Sep 03 2017 14:37
            let mut candidates: Vec<u64> = (2..limit).collect();
            let mut counter = 0;
            while counter <= 10 {
                let current_candidate =
                    candidates.clone()[counter as usize];
                match candidates.iter().all(|&num|
                    match num == current_candidate { 
                        true => true,
                        false => current_candidate % num != 0,
                    }) {
                    false => candidates,
                    true => { 
                        let max_mult = limit / current_candidate;
                        for i in (1..max_mult).collect() {
                            let val = current_candidate * i;
                            candidates.retain(|&num| num != val);
                        }
                        candidates // line 60 in error
                    },
                }
                    counter += 1;
            }
            candidates

is giving me this error:

error[E0308]: mismatched types
  --> src/lib.rs:60:25
   |
60 |                         candidates
   |                         ^^^^^^^^^^ expected (), found struct `std::vec::Vec`
   |
   = note: expected type `()`
              found type `std::vec::Vec<u64>`

error: aborting due to previous error

Why? It should be expecting the Vec<u64> to match against the false arm that returns a Vec<u64>, right?

Aleksey Kladov
@matklad
Sep 03 2017 14:39
You need a semicolon after the outer match
Rust complains because it wants the body of while loop to have () type
stevensonmt
@stevensonmt
Sep 03 2017 14:44
Thanks.
stevensonmt
@stevensonmt
Sep 03 2017 14:54
Of course that gives rise to a use of moved value error. I can't seem to get out of the ruby way of thinking about variables being assigned and then called in nearly any context I want.
Denis Lisov
@tanriol
Sep 03 2017 14:57
@stevensonmt Are you still working on trial division search for nth prime?
stevensonmt
@stevensonmt
Sep 03 2017 14:58
fn trial_div(x: u32) -> Vec<u64> {
    let mut primes: Vec<u64> = Vec::with_capacity(x as usize);

    primes.push(2);

    if x > 1 {
        primes.push(3);
    } else {

    }
    let mut next_checked = *primes.last().unwrap() + 2;

    while primes.len() < x as usize {
            if primes.iter().all(|&i| next_checked % i != 0) {
                primes.push(next_checked)
            } else {

            }
            next_checked += 2;
    }
    primes
}
That seems to work as a trial division. I'm still trying to figure out a way to sieve.
Denis Lisov
@tanriol
Sep 03 2017 15:01
You're missing the point of the sieve... candidates.retain(|&num| num != val); is not gonna make your code run faster.
stevensonmt
@stevensonmt
Sep 03 2017 15:04
I'll admit to a lack of adequate mathematics background. As I understand it, the steps of a sieve are: take the first prime in a set and remove all multiples of that prime from the set, move to the next prime in the set and do the same, and so on. Are you suggesting that rather than doing the multiplication I should be removing by index steps?
The problem with that is that after removing, for instance, the multiples of 2 by removing each item in the vec with an odd index, removing multiples of 3 by index won't work.
Denis Lisov
@tanriol
Sep 03 2017 15:26
I'd suggest that you don't remove numbers, but just mark them as "not prime". When your current prime factor is, for example, 101, you can easily strike out every 101st number, but moving in memory the 100 of 101 that you don't strike out is much more difficult.
And every retain has to copy every value that's retained (well, after the first one you drop, but that's a minor difference)
Sathya Narrayanan
@sourcepirate
Sep 03 2017 15:43
#[derive(Debug)]
struct A{}

#[derive(Debug)]
struct B{}

#[derive(Debug)]
struct C{}

fn main(){
let a = "a";

let n = match a {
   "a" => A{},
   "b" => B{},
   "c" => C{}
};

println!("{:?}", n);

}
 let n = match a {
   |  _________^
14 | |    "a" => A{},
15 | |    "b" => B{},
16 | |    "c" => C{}
17 | | };
   | |_^ expected struct `A`, found struct `B`
   |
   = note: expected type `A`
              found type `B`
note: match arm with an incompatible type
  --> src/main.rs:15:11
How can i handle this
mhsjlw
@mhsjlw
Sep 03 2017 15:47
Well, what exactly are you trying to accomplish? That isn't type-safe because any of those structs can have different fields
So you either need all structs to be the same type, or maybe if you tell me what you want we can come up with a better solution
Sathya Narrayanan
@sourcepirate
Sep 03 2017 15:50
I have a build system. Which run different commands on the particular directory base on the chosen language.
say i have a struct for Python, Ruby, Java
Each of them implements a trait called Packable
I have a struct called Folder like this.
pub struct Folder<T: Packable>{
    pub path: String,
    pub lang: T
}
My problem is based on the input string i need to select the appropriate language structure.
Any suggestions ??
mhsjlw
@mhsjlw
Sep 03 2017 16:04
Well actually, is this what you're looking for https://stackoverflow.com/a/36098169 ?
Sathya Narrayanan
@sourcepirate
Sep 03 2017 16:10
Oh! didn't think of this approach thanks
Robert Peters
@r2p2
Sep 03 2017 18:40
What is the point in naming the alias like the original type? type Request = Request;
Andrey Lesnikov
@ozkriff
Sep 03 2017 18:54
Maybe it's associated type
Robert Peters
@r2p2
Sep 03 2017 19:02
Okaaayy, I think that's too early for me.
twissel
@twissel
Sep 03 2017 19:29
Hello. Question: how to append/push a new Future to existing futures::future::Stream?