These are chat archives for rust-lang/rust

21st
Feb 2017
JasonKleban
@JasonKleban
Feb 21 2017 03:09

Here's my updated attempt:

pub fn euler4<'func>() -> i32 {
    num::range_step(99, 0, -1)
        .flat_map(|&a : &'func i32| num::range_step(a, 0, -1).map(|&b : &'func i32| a * b))
        .find(|&a_x_b| is_palendrome(a_x_b))
        .unwrap()
}

I'm giving an explicit lifetime to the function so that the borrows in the lambdas can be given them too. But flat_map() and map() don't want references to i32s, they want i32s. Backing into range_step, I guess I need it to give boxed values instead of values? I tried range_step::<'func>(...) but it won't take a lifetime parameter.

I'm pretty sure I could do it with a for loop instead but I'm more interested in understanding the bug or limitation here.
Joonas Koivunen
@koivunej
Feb 21 2017 06:40
@JasonKleban i think you should just rewrite the flatmap part flat_map(|a| num::range_step(a, ...).map(|b| a*b)) as the range_step seems to iterate over values, not borrowed references
@JasonKleban contrast to find that expects a closure that works with borrowed refs; here you also want to specify the closure as find(|a_x_b| ...) (remove the &)
@JasonKleban boxing or lifetimes are both unnecessary here. you might need to do is_palendrome(*a_x_b) if depending on your fn is_palendrome(x: i32) or fn is_palendrome(x: &i32) (but I'd prefer the former)
JasonKleban
@JasonKleban
Feb 21 2017 12:17

@koivunej - thanks for looking. That's where I started but I get this error:

error: `a` does not live long enough
 --> src\euler4_6.rs:6:57
  |
6 |         .flat_map(|a| num::range_step(a, 0, -1).map(|b| a * b))
  |                                                     --- ^    - borrowed value only lives until here
  |                                                     |   |
  |                                                     |   does not live long enough
  |                                                     capture occurs here
7 |         .find(|a_x_b| is_palendrome(*a_x_b))
  |                                            - borrowed value needs to live until here

where fn is_palendrome(cand_palendrome: i32) -> bool { ... }

and
pub fn euler4() -> i32 {
    num::range_step(99, 0, -1)
        .flat_map(|a| num::range_step(a, 0, -1).map(|b| a * b))
        .find(|a_x_b| is_palendrome(*a_x_b))
        .unwrap()
Sergey Noskov
@Albibek
Feb 21 2017 12:23
@koivunej your a is just a binding inside a closure, a parameter name. And results of flat_map iterator are bound to b one by ony inside second closure, so your a is not usable anymore.
JasonKleban
@JasonKleban
Feb 21 2017 12:25
but the closures are nested
(and that's rustfmt's formatting recommendation)
but ah, if I add move to all the closures there it works!
so
pub fn euler4() -> i32 {
    num::range_step(999, 0, -1)
        .flat_map(move |a| num::range_step(a, 0, -1).map(move |b| a * b))
        .find(move |a_x_b| is_palendrome(*a_x_b))
        .unwrap()
}
JasonKleban
@JasonKleban
Feb 21 2017 12:34
of course now I can work on fixing the algorithm itself :-)
Tomer Margalit
@matomer
Feb 21 2017 14:44
hi, does anyone know how I can print an enum from an external crate that doesn't have Debug implemented for it?
is there an easy way (like #[derive(Debug)] ...)?
Felix S Klock II
@pnkfelix
Feb 21 2017 14:46
@matomer no, you cannot derive the impl in a downstream crate. (Even if you make your own wrapper type and derive Debug on that, it will then just balk because the wrapped enum does not implement Debug)
@matomer (one reason for this is that if there were hidden state, as-in not pub, then it would violate the abstraction boundary to let Debug peek inside the innards...)
Tomer Margalit
@matomer
Feb 21 2017 14:48
@pnkfelix So how am I supposed to print it? Do I have to manually go over all public items and print them?
Felix S Klock II
@pnkfelix
Feb 21 2017 14:49
@matomer that would be one option. I would probably make a wrapper type, e.g. Wrap(Enum), and then manually impl fmt::Debug for Wrap { ... } with a fmt method that traverses the public state, as you describe.
(just because with such a wrapper type in place, then you can compose the wrapped enum with other data types in your own crate and do derive(Debug) on them, now that the wrapper implements fmt::Debug)
Tomer Margalit
@matomer
Feb 21 2017 14:51
@pnkfelix is there an easy way to loop over all enum variants and then print them or do I have to copy the whole enum and the type names?
Felix S Klock II
@pnkfelix
Feb 21 2017 14:54
@matomer assuming you want a nice print out for the variant and its data, I think a manual traversal is the current best option.
@matomer there is the discriminant_value intrinsic which will give back a representation for the particular variant that you have in hand
Tomer Margalit
@matomer
Feb 21 2017 14:55
@pnkfelix I'm actually just looking for the most basic debug print - I want to print it to inspect the contents myself for a test program
Felix S Klock II
@pnkfelix
Feb 21 2017 14:56
@matomer but I suspect that all discriminant_value is going to give you is a number (not a nice name for the variant).
Tomer Margalit
@matomer
Feb 21 2017 14:56
@pnkfelix then I will impl fmt manually
Chris Evans
@cevans01
Feb 21 2017 17:15
do Mutexes guarantee threads will acquire the lock in the order that they call Mutex::lock() ??
Denis Lisov
@tanriol
Feb 21 2017 17:24
@cevans01 They delegate to OS primitives, so I'd assume not. However, this is a rather strange question. Do you need exactly this or some other property?
my poll_thread loops: dropping the lock and re-acquiring...my hope is that this allows the main thread to acquire
it appears that main thread is blocked on mutex.lock() for a really long time ... meaning: many many cycles of the poll_thread loop
(rust playground isn't very good for this because it outputs all stdout at the same time)
Denis Lisov
@tanriol
Feb 21 2017 17:36
Yeah, the mutex seems to be not fair.
Chris Evans
@cevans01
Feb 21 2017 17:38
yikes. ok I'll try to come up with an alternate solution then
Denis Lisov
@tanriol
Feb 21 2017 17:43
I'd suggest that sending a command with a channel will work better :-)