Tuesday 15 January 2013

rust - Returning a closure with mutable environment -



rust - Returning a closure with mutable environment -

i trying build solution graham´s accumulator mill challenge requires function homecoming closure closes on mutable numeric variable initial value received through parameter. each phone call closure increments captured variable value parameter closure , returns accumulated value.

after reading closures rfc , questions returning unboxed closures (in particular this). come solution compiled, result not expect.

#![feature(unboxed_closures, unboxed_closure_sugar)] fn accumulator_factory(n: f64) -> box<|&mut: f64| -> f64> { allow mut acc = n; box |&mut: i: f64| { acc += i; acc } } fn main() { allow mut acc_cl = accumulator_factory(5f64); println!("{}", acc_cl.call_mut((3f64,))); println!("{}", acc_cl.call_mut((3f64,))); }

afaik closure captures acc value, generated struct acts environment mutable , acc_cl should retain same environment instance between calls.

but printed result 6 in both cases, seems modified value not persisting. , more confusing how result computed. on each execution of closure initial value of acc 3 though n 5 when called.

if modify generator this:

fn accumulator_factory(n: f64) -> box<|&mut: f64| -> f64> { println!("n {}", n); allow mut acc = n; box |&mut: i: f64| { acc += i; acc } }

then execution homecoming 3 , initial value of acc 0 on closure entry.

this difference in semantics looks bug. apart that, why environment reset between calls?

this run rustc 0.12.0.

recently closures capture mode has been changed. default closures biased capture reference because mutual utilize case closures passing them functions downwards phone call stack, , capturing reference create working environment more natural.

sometimes, however, capture reference limiting. example, can't homecoming such closures functions because environment tied phone call stack. such closures need set move keyword before closure:

#![feature(unboxed_closures, unboxed_closure_sugar)] fn accumulator_factory(n: f64) -> box<|&mut: f64| -> f64> { println!("n: {}", n); allow mut acc = n; box move |&mut: i: f64| { acc += i; acc } } fn main() { allow mut acc = accumulator_factory(10.0); println!("{}", acc.call_mut((12.0,))); println!("{}", acc.call_mut((12.0,))); }

this programme works intended:

n: 10 22 34

these 2 closure kinds covered this rfc.

unfortunately, current nightly version of rust compiler crashes on programme (it works on oct. 14 version). don't know why overloaded calls don't work, bug. reason why unboxed closures feature-gated :)

closures rust

No comments:

Post a Comment