These are chat archives for rust-lang/rust

2nd
Sep 2017
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 06:35
Hm. Anybody here able to give some some advice? Pretty new to Rust. I'm trying to replace an iterator every iteration so that I can change its sequence...
This is what I have so far:
#![feature(iterator_step_by)]

use std::iter::Iterator;

fn main() {
    let max = 100u32;//10u32.pow(7);
    let target = 32u32;

    let mut numbers = 1..(max + 1);
    let mut last_value = 0u32;

    loop {
        let value = match numbers.next() {
            Some(value) => value,
            None => break
        };
        if value > target {
            println!("{} < {} < {}", last_value, target, value);
            break
        }
        last_value = value;
        numbers = numbers.step_by(value as usize);
    }
}
But I'm getting "mismatched types" error:
error[E0308]: mismatched types
  --> src/main.rs:22:19
   |
22 |         numbers = numbers.step_by(value as usize);
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::ops::Range`, found struct `std::iter::StepBy`
   |
   = note: expected type `std::ops::Range<_>`
              found type `std::iter::StepBy<std::ops::Range<_>>`
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 06:41
I get the feeling I'm doing something silly here :point_up:
Michal 'vorner' Vaner
@vorner
Sep 02 2017 06:59
@rhys-vdw Right, first, I don't really see the idea behind what you do, it seems suspicious. Is the idea really to have numbers 1, 2,3…a lot, then have 2,3,4,5,…, then 3,5,7,9…, then 5,11,17,…?
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 06:59
That's right
It's a programming exercise I'm usign to learn Rust
I might have some logic errors, but it's meant to end up as 1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, ...
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:01
But what the compiler is complaining about… the iterator isn't really bunch of numbers. It is some type that knows how to produce the numbers. So, there's range that remembers the next number to produce and the one where it stops. And you have that in the variable numbers at first, take the first number out.
But then, you try to do step_by on it. That one creates a new, wrapping type that knows it should skip some number of elements from the inner iterator.
So, if you call someiterator.step_by(2) and call .next on it, it calls someiterator.next(); someiterator.next() and returns the second result.
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:03
Yep.
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:03
But the problem is, you have a variable for range and you're trying to stuff StepBy<Range> inside it ‒ which doesn't work, because it is larger.
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:03
By "larger" do you mean it occupies more space on the stack?
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:03
And you'd try to stuff StepBy<StepBy<Range>> in the next iteration, which is even larger.
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:03
Yep, right.
I need them to be heap allocated for that to work...
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:04
Yes, it occupies more space on the stack
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:04
Like they might in in C# LINQ
Is there a way to dynamically build up an iterator in this way? Or is this perhaps a silly approach to take in Rust?
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:04
but it would be a problem even if it occupied the same amount, because it is a different type
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:05
Yeah, this makes sense.
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:05
Well, it could be done, you can have something like an abstract iterator ‒ Box<Iterator<Whatever>>. That one is only a pointer to unknown iterator somewhere on the heap and you can hide different types behind it.
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:06
Yeah, cool.
I understand the concept. Guess I'll have to work out how to do it.
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:06
I still believe this is not what you want, mostly because it does something else. I think you want to skip so many original numbers, not so many elements from the lower-level iterator which already skips some more numbers. But I might be wrong there.
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:07
I think it's the nature of the exercise that you need to generate each number in each series.
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:07
Anyway, you're still producing all the numbers deep down and skipping a lot of them one by one, which seems a bit wasteful.
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:07
Because each subsequent "step" relies on knowing the result of the prior.
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:08
OK, I'm going to read the exercise
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:08
Only if you want to! You've given me the info I need to understand what I was doing wrong
Much appreciated
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:09
Right, the exercise is really close to what you do. However, step_by takes the nth element, while you want to remove nth element. This is the difference.
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:10
Oh yeah! I misread it myself.
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:11
I'm not sure iterators are the best abstraction here, but I'll let you enjoy the exercise :-)
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:11
Heheh, yeah. Esp. since it's not step_by compatible.
I think it'll probably be easier to just use a single mutable vector
(or a linked list maybe)
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:13
Do you want a tip?
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:13
Sure :)
Michal 'vorner' Vaner
@vorner
Sep 02 2017 07:14
Take a look at Vec::retain
(method on vector)
Rhys van der Waerden
@rhys-vdw
Sep 02 2017 07:14
Ah, cool. Can I get the index in the callback there?
I'm think not. I might end up just using a for 0..v.len()
Robert Peters
@r2p2
Sep 02 2017 18:37
I am playing with the image crate. Which method signature do I need, when I want to pass the return value of this method fn enumerate_pixels_mut(&mut self) -> EnumeratePixelsMut<P> as argument? I've got fn process(&self, pixels: &mut image::EnumeratePixelsMut<image::Pixel>) but EnumeratePixelMut... is not found in image. :/
Alyani
@notsonotso
Sep 02 2017 18:49
Hello
I'm struggling with extremely slow compilation speed
anything I can do? Trying incremental with only slightly improved results
Michal 'vorner' Vaner
@vorner
Sep 02 2017 18:51
Reporting it with code examples might help discovering a bug
(or, you may try finding a similar issue already reported)
Alyani
@notsonotso
Sep 02 2017 19:09
@vorner i found a similar issue and commented there, thanks
stevensonmt
@stevensonmt
Sep 02 2017 21:51
I have a Vec<u64> and I want to retain() any element for which all of the elements return a non-zero modulus (i.e., none of the elements are factors of any other element). I am trying this
candidates.retain(|&candidate| 
    candidates.clone().iter().all(|&divisor| 
        candidate != divisor &&
        candidate % divisor != 0));
This generates a borrow conflict that I don't quite understand.
error[E0502]: cannot borrow `candidates` as immutable because it is also borrowed as mutable
  --> src/lib.rs:43:31
   |
43 |             candidates.retain(|&candidate| candidates.clone().iter().all(|&divisor| candidate != divisor &&
   |             ----------        ^^^^^^^^^^^^ ---------- borrow occurs due to use of `candidates` in closure
   |             |                 |
   |             |                 immutable borrow occurs here
   |             mutable borrow occurs here
44 |             candidate % divisor != 0));
   |                                      - mutable borrow ends here

error: aborting due to previous error

error[E0502]: cannot borrow `candidates` as immutable because it is also borrowed as mutable
  --> src/lib.rs:43:31
stevensonmt
@stevensonmt
Sep 02 2017 21:57
I had assumed that the call to clone() in the retain predicate would remedy this, but it does not. Any suggestions?
Denis Lisov
@tanriol
Sep 02 2017 21:58
You most likely don't want to clone the entire vector on every call. Maybe clone it just once before the call?
stevensonmt
@stevensonmt
Sep 02 2017 21:59
ah, beautiful, thanks.
so candidates.clone().retain(...
Denis Lisov
@tanriol
Sep 02 2017 22:00
Don't forget that you want to keep the filtered version, not the original :-)
stevensonmt
@stevensonmt
Sep 02 2017 22:00
I wish I could figure out all these little things that keep tripping me up. I clearly don't have a firm grasp of Rust's ownership and lifetime concepts.
Denis Lisov
@tanriol
Sep 02 2017 22:01
I'd actually suggest not retain, but candidates.iter().filter(...).collect::<Vec<_>>()
Denis Lisov
@tanriol
Sep 02 2017 22:08
Is this some particular exercise? The algorithm might be suboptimal, but I don't know the exact requirements...
stevensonmt
@stevensonmt
Sep 02 2017 22:09
It's definitely suboptimal.
I'm doing an nth prime exercise
but I've got something wrong in my logic
Using a slow trial division approach I was successful even for large values of n up to 10**4
I'm trying to implement a sieve method that just matches up to n = 5 and for >= 6 goes through the sieve.
It seems to work for n = 6 but not for large values of n.
Denis Lisov
@tanriol
Sep 02 2017 22:17
The code above does not look like a sieve, but as an attempt to implement (optimized?) trial division...
stevensonmt
@stevensonmt
Sep 02 2017 22:25
You are right. I've been falling back to that trying to figure out why the sieve wasn't working.