do_expr : "do" expr [ '|' ident_list '|' ] ? '{' block '}' ;
~~~~
-A _do expression_ provides a more-familiar block-syntax for a [lambda expression](#lambda-expressions),
-including a special translation of [return expressions](#return-expressions) inside the supplied block.
-
-Any occurrence of a [return expression](#return-expressions)
-inside this `block` expression is rewritten
-as a reference to an (anonymous) flag set in the caller's environment,
-which is checked on return from the `expr` and, if set,
-causes a corresponding return from the caller.
-In this way, the meaning of `return` statements in language built-in control blocks is preserved,
-if they are rewritten using lambda functions and `do` expressions as abstractions.
-
-The optional `ident_list` and `block` provided in a `do` expression are parsed as though they constitute a lambda expression;
+A _do expression_ provides a more-familiar block syntax
+for invoking a function and passing it a newly-created a procedure.
+
+The optional `ident_list` and `block` provided in a `do` expression are parsed
+as though they constitute a procedure expression;
if the `ident_list` is missing, an empty `ident_list` is implied.
-The lambda expression is then provided as a _trailing argument_
-to the outermost [call](#call-expressions) or [method call](#method-call-expressions) expression
+The procedure expression is then provided as a _trailing argument_
+to the outermost [call](#call-expressions) or
+[method call](#method-call-expressions) expression
in the `expr` following `do`.
If the `expr` is a [path expression](#path-expressions), it is parsed as though it is a call expression.
If the `expr` is a [field expression](#field-expressions), it is parsed as though it is a method call expression.
In this example, both calls to `f` are equivalent:
~~~~
-# fn f(f: |int|) { }
+# fn f(f: proc(int)) { }
# fn g(i: int) { }
-f(|j| g(j));
+f(proc(j) { g(j) });
do f |j| {
g(j);
In this example, both calls to the (binary) function `k` are equivalent:
~~~~
-# fn k(x:int, f: |int|) { }
+# fn k(x:int, f: proc(int)) { }
# fn l(i: int) { }
-k(3, |j| l(j));
+k(3, proc(j) { l(j) });
do k(3) |j| {
l(j);
fn main() {
// Trap the condition:
- do malformed_line::cond.trap(|_| (-1,-1)).inside {
+ malformed_line::cond.trap(|_| (-1,-1)).inside(|| {
// The protected logic.
let pairs = read_int_pairs();
println!("{:4.4d}, {:4.4d}", a, b);
}
- }
+ })
}
fn read_int_pairs() -> ~[(int,int)] {
fn main() {
// Trap the condition and return `None`
- do malformed_line::cond.trap(|_| None).inside {
+ malformed_line::cond.trap(|_| None).inside(|| {
// The protected logic.
let pairs = read_int_pairs();
println!("{:4.4d}, {:4.4d}", a, b);
}
- }
+ })
}
fn read_int_pairs() -> ~[(int,int)] {
fn main() {
// Trap the condition and return `UsePreviousLine`
- do malformed_line::cond.trap(|_| UsePreviousLine).inside {
+ malformed_line::cond.trap(|_| UsePreviousLine).inside(|| {
// The protected logic.
let pairs = read_int_pairs();
println!("{:4.4d}, {:4.4d}", a, b);
}
- }
+ })
}
fn read_int_pairs() -> ~[(int,int)] {
fn main() {
// Trap the `malformed_int` condition and return -1
- do malformed_int::cond.trap(|_| -1).inside {
+ malformed_int::cond.trap(|_| -1).inside(|| {
// Trap the `malformed_line` condition and return `UsePreviousLine`
- do malformed_line::cond.trap(|_| UsePreviousLine).inside {
+ malformed_line::cond.trap(|_| UsePreviousLine).inside(|| {
// The protected logic.
let pairs = read_int_pairs();
println!("{:4.4d}, {:4.4d}", a, b);
}
- }
- }
+ })
+ })
}
// Parse an int; if parsing fails, call the condition handler and
# use std::vec;
// Create a vector of ports, one for each child task
-let ports = do vec::from_fn(3) |init_val| {
+let ports = vec::from_fn(3, |init_val| {
let (port, chan) = stream();
do spawn {
chan.send(some_expensive_computation(init_val));
}
port
-};
+});
// Wait on each port, accumulating the results
let result = ports.iter().fold(0, |accum, port| accum + port.recv() );
## Do syntax
-The `do` expression provides a way to treat higher-order functions
-(functions that take closures as arguments) as control structures.
+The `do` expression makes it easier to call functions that take procedures
+as arguments.
-Consider this function that iterates over a vector of
-integers, passing in a pointer to each integer in the vector:
+Consider this function that takes a procedure:
~~~~
-fn each(v: &[int], op: |v: &int|) {
- let mut n = 0;
- while n < v.len() {
- op(&v[n]);
- n += 1;
- }
+fn call_it(op: proc(v: int)) {
+ op(10)
}
~~~~
structure.
~~~~
-# fn each(v: &[int], op: |v: &int|) { }
-# fn do_some_work(i: &int) { }
-each([1, 2, 3], |n| {
- do_some_work(n);
+# fn call_it(op: proc(v: int)) { }
+call_it(proc(n) {
+ println(n.to_str());
});
~~~~
This is such a useful pattern that Rust has a special form of function
-call that can be written more like a built-in control structure:
+call for these functions.
~~~~
-# fn each(v: &[int], op: |v: &int|) { }
-# fn do_some_work(i: &int) { }
-do each([1, 2, 3]) |n| {
- do_some_work(n);
+# fn call_it(op: proc(v: int)) { }
+do call_it() |n| {
+ println(n.to_str());
}
~~~~
The call is prefixed with the keyword `do` and, instead of writing the
-final closure inside the argument list, it appears outside of the
+final procedure inside the argument list, it appears outside of the
parentheses, where it looks more like a typical block of
code.
for i in range(0u, 10) {
// Arena allocate something with drop glue to make sure it
// doesn't leak.
- do arena.alloc { @i };
+ arena.alloc(|| { @i });
// Allocate something with funny size and alignment, to keep
// things interesting.
- do arena.alloc { [0u8, 1u8, 2u8] };
+ arena.alloc(|| { [0u8, 1u8, 2u8] });
}
// Now, fail while allocating
- do arena.alloc::<@int> {
+ arena.alloc::<@int>(|| {
// Now fail.
fail!();
- };
+ });
}
use std::rand::{task_rng, random, Rng};
use std::vec;
- do 1000.times {
+ 1000.times(|| {
let times = task_rng().gen_range(1u, 100);
let v = vec::from_fn(times, |_| random::<u8>());
assert_eq!(v.to_base64(STANDARD).from_base64().unwrap(), v);
- }
+ })
}
#[bench]
pub fn bench_to_base64(bh: & mut BenchHarness) {
let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
- do bh.iter {
+ bh.iter(|| {
s.as_bytes().to_base64(STANDARD);
- }
+ });
bh.bytes = s.len() as u64;
}
let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
let b = s.as_bytes().to_base64(STANDARD);
- do bh.iter {
+ bh.iter(|| {
b.from_base64();
- }
+ });
bh.bytes = b.len() as u64;
}
fn test_small_clear() {
let mut b = Bitv::new(14, true);
b.clear();
- do b.ones |i| {
+ b.ones(|i| {
fail!("found 1 at {:?}", i)
- };
+ });
}
#[test]
fn test_big_clear() {
let mut b = Bitv::new(140, true);
b.clear();
- do b.ones |i| {
+ b.ones(|i| {
fail!("found 1 at {:?}", i)
- };
+ });
}
#[test]
let mut i = 0;
let expected = [3, 5, 11, 77];
- do a.intersection(&b) |x| {
+ a.intersection(&b, |x| {
assert_eq!(*x, expected[i]);
i += 1;
true
- };
+ });
assert_eq!(i, expected.len());
}
let mut i = 0;
let expected = [1, 5, 500];
- do a.difference(&b) |x| {
+ a.difference(&b, |x| {
assert_eq!(*x, expected[i]);
i += 1;
true
- };
+ });
assert_eq!(i, expected.len());
}
let mut i = 0;
let expected = [1, 5, 11, 14, 220];
- do a.symmetric_difference(&b) |x| {
+ a.symmetric_difference(&b, |x| {
assert_eq!(*x, expected[i]);
i += 1;
true
- };
+ });
assert_eq!(i, expected.len());
}
let mut i = 0;
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160];
- do a.union(&b) |x| {
+ a.union(&b, |x| {
assert_eq!(*x, expected[i]);
i += 1;
true
- };
+ });
assert_eq!(i, expected.len());
}
fn bench_uint_small(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = 0 as uint;
- do b.iter {
+ b.iter(|| {
bitv |= (1 << ((r.next_u32() as uint) % uint::bits));
- }
+ })
}
#[bench]
fn bench_small_bitv_small(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = SmallBitv::new(uint::bits);
- do b.iter {
+ b.iter(|| {
bitv.set((r.next_u32() as uint) % uint::bits, true);
- }
+ })
}
#[bench]
fn bench_big_bitv_small(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = BigBitv::new(~[0]);
- do b.iter {
+ b.iter(|| {
bitv.set((r.next_u32() as uint) % uint::bits, true);
- }
+ })
}
#[bench]
let mut storage = ~[];
storage.grow(BENCH_BITS / uint::bits, &0u);
let mut bitv = BigBitv::new(storage);
- do b.iter {
+ b.iter(|| {
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
- }
+ })
}
#[bench]
fn bench_bitv_big(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = Bitv::new(BENCH_BITS, false);
- do b.iter {
+ b.iter(|| {
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
- }
+ })
}
#[bench]
fn bench_bitv_small(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = Bitv::new(uint::bits, false);
- do b.iter {
+ b.iter(|| {
bitv.set((r.next_u32() as uint) % uint::bits, true);
- }
+ })
}
#[bench]
fn bench_bitv_set_small(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = BitvSet::new();
- do b.iter {
+ b.iter(|| {
bitv.insert((r.next_u32() as uint) % uint::bits);
- }
+ })
}
#[bench]
fn bench_bitv_set_big(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = BitvSet::new();
- do b.iter {
+ b.iter(|| {
bitv.insert((r.next_u32() as uint) % BENCH_BITS);
- }
+ })
}
#[bench]
fn bench_bitv_big_union(b: &mut BenchHarness) {
let mut b1 = Bitv::new(BENCH_BITS, false);
let b2 = Bitv::new(BENCH_BITS, false);
- do b.iter {
+ b.iter(|| {
b1.union(&b2);
- }
+ })
}
#[bench]
fn bench_btv_small_iter(b: &mut BenchHarness) {
let bitv = Bitv::new(uint::bits, false);
- do b.iter {
+ b.iter(|| {
let mut _sum = 0;
for pres in bitv.iter() {
_sum += pres as uint;
}
- }
+ })
}
#[bench]
fn bench_bitv_big_iter(b: &mut BenchHarness) {
let bitv = Bitv::new(BENCH_BITS, false);
- do b.iter {
+ b.iter(|| {
let mut _sum = 0;
for pres in bitv.iter() {
_sum += pres as uint;
}
- }
+ })
}
#[bench]
fn bench_bitvset_iter(b: &mut BenchHarness) {
let bitv = BitvSet::from_bitv(from_fn(BENCH_BITS,
|idx| {idx % 3 == 0}));
- do b.iter {
+ b.iter(|| {
let mut _sum = 0;
for idx in bitv.iter() {
_sum += idx;
}
- }
+ })
}
}
do run_in_uv_task {
let (port, chan) = rendezvous();
do spawn {
- do 1000000.times { chan.send(()) }
+ 1000000.times(|| { chan.send(()) })
}
- do 1000000.times { port.recv() }
+ 1000000.times(|| { port.recv() })
}
}
}
// measure
- do bh.iter {
+ bh.iter(|| {
let k = rng.gen::<uint>() % n;
map.insert(k, 1);
map.remove(&k);
- }
+ })
}
pub fn insert_seq_n<M:MutableMap<uint,uint>>(n: uint,
// measure
let mut i = 1;
- do bh.iter {
+ bh.iter(|| {
map.insert(i, 1);
map.remove(&i);
i = (i + 2) % n;
- }
+ })
}
pub fn find_rand_n<M:MutableMap<uint,uint>>(n: uint,
// measure
let mut i = 0;
- do bh.iter {
+ bh.iter(|| {
map.find(&(keys[i]));
i = (i + 1) % n;
- }
+ })
}
pub fn find_seq_n<M:MutableMap<uint,uint>>(n: uint,
// measure
let mut i = 0;
- do bh.iter {
+ bh.iter(|| {
map.find(&i);
i = (i + 1) % n;
- }
+ })
}
}
#[test]
fn test_fuzz() {
- do 25.times {
+ 25.times(|| {
fuzz_test(3);
fuzz_test(16);
fuzz_test(189);
- }
+ })
}
#[cfg(test)]
#[bench]
fn bench_collect_into(b: &mut test::BenchHarness) {
let v = &[0, ..64];
- do b.iter {
+ b.iter(|| {
let _: DList<int> = v.iter().map(|x| *x).collect();
- }
+ })
}
#[bench]
fn bench_push_front(b: &mut test::BenchHarness) {
let mut m: DList<int> = DList::new();
- do b.iter {
+ b.iter(|| {
m.push_front(0);
- }
+ })
}
#[bench]
fn bench_push_back(b: &mut test::BenchHarness) {
let mut m: DList<int> = DList::new();
- do b.iter {
+ b.iter(|| {
m.push_back(0);
- }
+ })
}
#[bench]
fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
let mut m: DList<int> = DList::new();
- do b.iter {
+ b.iter(|| {
m.push_back(0);
m.pop_back();
- }
+ })
}
#[bench]
fn bench_push_front_pop_front(b: &mut test::BenchHarness) {
let mut m: DList<int> = DList::new();
- do b.iter {
+ b.iter(|| {
m.push_front(0);
m.pop_front();
- }
+ })
}
#[bench]
let mut m: DList<int> = DList::new();
m.push_front(0);
m.push_front(1);
- do b.iter {
+ b.iter(|| {
m.rotate_forward();
- }
+ })
}
#[bench]
let mut m: DList<int> = DList::new();
m.push_front(0);
m.push_front(1);
- do b.iter {
+ b.iter(|| {
m.rotate_backward();
- }
+ })
}
#[bench]
fn bench_iter(b: &mut test::BenchHarness) {
let v = &[0, ..128];
let m: DList<int> = v.iter().map(|&x|x).collect();
- do b.iter {
+ b.iter(|| {
assert!(m.iter().len() == 128);
- }
+ })
}
#[bench]
fn bench_iter_mut(b: &mut test::BenchHarness) {
let v = &[0, ..128];
let mut m: DList<int> = v.iter().map(|&x|x).collect();
- do b.iter {
+ b.iter(|| {
assert!(m.mut_iter().len() == 128);
- }
+ })
}
#[bench]
fn bench_iter_rev(b: &mut test::BenchHarness) {
let v = &[0, ..128];
let m: DList<int> = v.iter().map(|&x|x).collect();
- do b.iter {
+ b.iter(|| {
assert!(m.rev_iter().len() == 128);
- }
+ })
}
#[bench]
fn bench_iter_mut_rev(b: &mut test::BenchHarness) {
let v = &[0, ..128];
let mut m: DList<int> = v.iter().map(|&x|x).collect();
- do b.iter {
+ b.iter(|| {
assert!(m.mut_rev_iter().len() == 128);
- }
+ })
}
}
fn test_flate_round_trip() {
let mut r = rand::rng();
let mut words = ~[];
- do 20.times {
+ 20.times(|| {
let range = r.gen_range(1u, 10);
words.push(r.gen_vec::<u8>(range));
- }
- do 20.times {
+ });
+ 20.times(|| {
let mut input = ~[];
- do 2000.times {
+ 2000.times(|| {
input.push_all(r.choose(words));
- }
+ });
debug!("de/inflate of {} bytes of random word-sequences",
input.len());
let cmp = deflate_bytes(input);
input.len(), cmp.len(),
100.0 * ((cmp.len() as f64) / (input.len() as f64)));
assert_eq!(input, out);
- }
+ });
}
#[test]
pub fn bench_to_hex(bh: & mut BenchHarness) {
let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
- do bh.iter {
+ bh.iter(|| {
s.as_bytes().to_hex();
- }
+ });
bh.bytes = s.len() as u64;
}
let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
let b = s.as_bytes().to_hex();
- do bh.iter {
+ bh.iter(|| {
b.from_hex();
- }
+ });
bh.bytes = b.len() as u64;
}
}
fn test_write_enum() {
let animal = Dog;
assert_eq!(
- do with_str_writer |wr| {
+ with_str_writer(|wr| {
let mut encoder = Encoder(wr);
animal.encode(&mut encoder);
- },
+ }),
~"\"Dog\""
);
assert_eq!(
- do with_str_writer |wr| {
+ with_str_writer(|wr| {
let mut encoder = PrettyEncoder(wr);
animal.encode(&mut encoder);
- },
+ }),
~"\"Dog\""
);
let animal = Frog(~"Henry", 349);
assert_eq!(
- do with_str_writer |wr| {
+ with_str_writer(|wr| {
let mut encoder = Encoder(wr);
animal.encode(&mut encoder);
- },
+ }),
~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
);
assert_eq!(
- do with_str_writer |wr| {
+ with_str_writer(|wr| {
let mut encoder = PrettyEncoder(wr);
animal.encode(&mut encoder);
- },
+ }),
~"\
[\n \
\"Frog\",\n \
#[test]
fn test_write_some() {
let value = Some(~"jodhpurs");
- let s = do with_str_writer |wr| {
+ let s = with_str_writer(|wr| {
let mut encoder = Encoder(wr);
value.encode(&mut encoder);
- };
+ });
assert_eq!(s, ~"\"jodhpurs\"");
let value = Some(~"jodhpurs");
- let s = do with_str_writer |wr| {
+ let s = with_str_writer(|wr| {
let mut encoder = PrettyEncoder(wr);
value.encode(&mut encoder);
- };
+ });
assert_eq!(s, ~"\"jodhpurs\"");
}
#[test]
fn test_write_none() {
let value: Option<~str> = None;
- let s = do with_str_writer |wr| {
+ let s = with_str_writer(|wr| {
let mut encoder = Encoder(wr);
value.encode(&mut encoder);
- };
+ });
assert_eq!(s, ~"null");
- let s = do with_str_writer |wr| {
+ let s = with_str_writer(|wr| {
let mut encoder = Encoder(wr);
value.encode(&mut encoder);
- };
+ });
assert_eq!(s, ~"null");
}
#[bench]
fn factorial_100(bh: &mut BenchHarness) {
- bh.iter(|| factorial(100));
+ bh.iter(|| {
+ factorial(100);
+ });
}
#[bench]
fn fib_100(bh: &mut BenchHarness) {
- bh.iter(|| fib(100));
+ bh.iter(|| {
+ fib(100);
+ });
}
#[bench]
fn to_str(bh: &mut BenchHarness) {
let fac = factorial(100);
let fib = fib(100);
- bh.iter(|| fac.to_str());
- bh.iter(|| fib.to_str());
+ bh.iter(|| {
+ fac.to_str();
+ });
+ bh.iter(|| {
+ fib.to_str();
+ });
}
}
#[bench]
fn bench_new(b: &mut test::BenchHarness) {
- do b.iter {
+ b.iter(|| {
let _: RingBuf<u64> = RingBuf::new();
- }
+ })
}
#[bench]
fn bench_push_back(b: &mut test::BenchHarness) {
let mut deq = RingBuf::new();
- do b.iter {
+ b.iter(|| {
deq.push_back(0);
- }
+ })
}
#[bench]
fn bench_push_front(b: &mut test::BenchHarness) {
let mut deq = RingBuf::new();
- do b.iter {
+ b.iter(|| {
deq.push_front(0);
- }
+ })
}
#[bench]
fn bench_grow(b: &mut test::BenchHarness) {
let mut deq = RingBuf::new();
- do b.iter {
- do 65.times {
+ b.iter(|| {
+ 65.times(|| {
deq.push_front(1);
- }
- }
+ })
+ })
}
#[deriving(Clone, Eq)]
let expected = ~[1, 2, 3];
- do quick_sort(names) |x, y| { *x < *y };
+ quick_sort(names, |x, y| *x < *y);
let immut_names = names;
#[cfg(unix)]
fn crash_test() {
let mut rng = rand::rng();
- let mut arr = do vec::from_fn(1000) |_i| {
+ let mut arr = vec::from_fn(1000, |_i| {
CVal { val: rng.gen() }
- };
+ });
tim_sort(arr);
fail!("Guarantee the fail");
#[test]
fn test_bad_Ord_impl() {
let mut rng = rand::rng();
- let mut arr = do vec::from_fn(500) |_i| {
+ let mut arr = vec::from_fn(500, |_i| {
DVal { val: rng.gen() }
- };
+ });
tim_sort(arr);
}
fn multiplyVec<T:Clone>(arr: &[T], num: uint) -> ~[T] {
let size = arr.len();
- let res = do vec::from_fn(num) |i| {
+ let res = vec::from_fn(num, |i| {
arr[i % size].clone()
- };
+ });
res
}
fn makeRange(n: uint) -> ~[uint] {
- let one = do vec::from_fn(n) |i| { i };
+ let one = vec::from_fn(n, |i| i);
let mut two = one.clone();
two.reverse();
vec::append(two, one)
for i in range(lo, hi) {
let n = 1 << i;
- let mut arr: ~[f64] = do vec::from_fn(n) |_i| {
+ let mut arr: ~[f64] = vec::from_fn(n, |_i| {
rng.gen()
- };
+ });
tim_sort(arr); // *sort
isSorted(arr);
tim_sort(arr); // /sort
isSorted(arr);
- do 3.times {
+ 3.times(|| {
let i1 = rng.gen_range(0u, n);
let i2 = rng.gen_range(0u, n);
arr.swap(i1, i2);
- }
+ });
tim_sort(arr); // 3sort
isSorted(arr);
tim_sort(arr); // +sort
isSorted(arr);
- do (n/100).times {
+ (n/100).times(|| {
let idx = rng.gen_range(0u, n);
arr[idx] = rng.gen();
- }
+ });
tim_sort(arr);
isSorted(arr);
for i in range(lo, hi) {
let n = 1 << i;
- let arr: ~[@f64] = do vec::from_fn(n) |_i| {
+ let arr: ~[@f64] = vec::from_fn(n, |_i| {
@rng.gen()
- };
+ });
let mut arr = arr;
tim_sort(arr); // *sort
tim_sort(arr); // /sort
isSorted(arr);
- do 3.times {
+ 3.times(|| {
let i1 = rng.gen_range(0u, n);
let i2 = rng.gen_range(0u, n);
arr.swap(i1, i2);
- }
+ });
tim_sort(arr); // 3sort
isSorted(arr);
tim_sort(arr); // +sort
isSorted(arr);
- do (n/100).times {
+ (n/100).times(|| {
let idx = rng.gen_range(0u, n);
arr[idx] = @rng.gen();
- }
+ });
tim_sort(arr);
isSorted(arr);
* # Example
*
* ```rust
- * do lock.write_downgrade |mut write_token| {
- * do write_token.write_cond |condvar| {
+ * lock.write_downgrade(|mut write_token| {
+ * write_token.write_cond(|condvar| {
* ... exclusive access ...
- * }
+ * });
* let read_token = lock.downgrade(write_token);
- * do read_token.read {
+ * read_token.read(|| {
* ... shared access ...
- * }
- * }
+ * })
+ * })
* ```
*/
pub fn write_downgrade<U>(&self, blk: |v: RWLockWriteMode| -> U) -> U {
#[test]
fn test_sem_basic() {
let s = Semaphore::new(1);
- do s.access { }
+ s.access(|| { })
}
#[test]
fn test_sem_as_mutex() {
let s = Semaphore::new(1);
let s2 = s.clone();
do task::spawn {
- do s2.access {
- do 5.times { task::deschedule(); }
- }
- }
- do s.access {
- do 5.times { task::deschedule(); }
+ s2.access(|| {
+ 5.times(|| { task::deschedule(); })
+ })
}
+ s.access(|| {
+ 5.times(|| { task::deschedule(); })
+ })
}
#[test]
fn test_sem_as_cvar() {
s2.acquire();
c.send(());
}
- do 5.times { task::deschedule(); }
+ 5.times(|| { task::deschedule(); });
s.release();
let _ = p.recv();
let s = Semaphore::new(0);
let s2 = s.clone();
do task::spawn {
- do 5.times { task::deschedule(); }
+ 5.times(|| { task::deschedule(); });
s2.release();
let _ = p.recv();
}
let (p1,c1) = comm::stream();
let (p2,c2) = comm::stream();
do task::spawn {
- do s2.access {
+ s2.access(|| {
let _ = p2.recv();
c1.send(());
- }
+ })
}
- do s.access {
+ s.access(|| {
c2.send(());
let _ = p1.recv();
- }
+ })
}
#[test]
fn test_sem_runtime_friendly_blocking() {
let s2 = s.clone();
let (p, c) = comm::stream();
let child_data = Cell::new((s2, c));
- do s.access {
+ s.access(|| {
let (s2, c) = child_data.take();
do task::spawn {
c.send(());
- do s2.access { }
+ s2.access(|| { });
c.send(());
}
let _ = p.recv(); // wait for child to come alive
- do 5.times { task::deschedule(); } // let the child contend
- }
+ 5.times(|| { task::deschedule(); }); // let the child contend
+ });
let _ = p.recv(); // wait for child to be done
}
}
}
fn access_shared(sharedstate: &mut int, m: &Mutex, n: uint) {
- do n.times {
- do m.lock {
+ n.times(|| {
+ m.lock(|| {
let oldval = *sharedstate;
task::deschedule();
*sharedstate = oldval + 1;
- }
- }
+ })
+ })
}
}
#[test]
let m = Mutex::new();
// Child wakes up parent
- do m.lock_cond |cond| {
+ m.lock_cond(|cond| {
let m2 = m.clone();
do task::spawn {
- do m2.lock_cond |cond| {
+ m2.lock_cond(|cond| {
let woken = cond.signal();
assert!(woken);
- }
+ })
}
cond.wait();
- }
+ });
// Parent wakes up child
let (port,chan) = comm::stream();
let m3 = m.clone();
do task::spawn {
- do m3.lock_cond |cond| {
+ m3.lock_cond(|cond| {
chan.send(());
cond.wait();
chan.send(());
- }
+ })
}
let _ = port.recv(); // Wait until child gets in the mutex
- do m.lock_cond |cond| {
+ m.lock_cond(|cond| {
let woken = cond.signal();
assert!(woken);
- }
+ });
let _ = port.recv(); // Wait until child wakes up
}
#[cfg(test)]
let m = Mutex::new();
let mut ports = ~[];
- do num_waiters.times {
+ num_waiters.times(|| {
let mi = m.clone();
let (port, chan) = comm::stream();
ports.push(port);
do task::spawn {
- do mi.lock_cond |cond| {
+ mi.lock_cond(|cond| {
chan.send(());
cond.wait();
chan.send(());
- }
+ })
}
- }
+ });
// wait until all children get in the mutex
for port in ports.iter() { let _ = port.recv(); }
- do m.lock_cond |cond| {
+ m.lock_cond(|cond| {
let num_woken = cond.broadcast();
assert_eq!(num_woken, num_waiters);
- }
+ });
// wait until all children wake up
for port in ports.iter() { let _ = port.recv(); }
}
let m = Mutex::new();
let m2 = m.clone();
do task::try {
- do m.lock_cond |_x| { }
+ m.lock_cond(|_x| { })
};
- do m2.lock_cond |cond| {
+ m2.lock_cond(|cond| {
assert!(!cond.signal());
- }
+ })
}
#[test]
fn test_mutex_killed_simple() {
let m2 = m.clone();
let result: result::Result<(), ~Any> = do task::try {
- do m2.lock {
+ m2.lock(|| {
fail!();
- }
+ })
};
assert!(result.is_err());
// child task must have finished by the time try returns
- do m.lock { }
+ m.lock(|| { })
}
#[ignore(reason = "linked failure")]
#[test]
task::deschedule();
fail!();
}
- do m2.lock_cond |cond| {
+ m2.lock_cond(|cond| {
c.send(()); // tell sibling go ahead
cond.wait(); // block forever
- }
+ })
};
assert!(result.is_err());
// child task must have finished by the time try returns
- do m.lock_cond |cond| {
+ m.lock_cond(|cond| {
let woken = cond.signal();
assert!(!woken);
- }
+ })
}
#[ignore(reason = "linked failure")]
#[test]
let result: result::Result<(), ~Any> = do task::try {
let mut sibling_convos = ~[];
- do 2.times {
+ 2.times(|| {
let (p, c) = comm::stream();
let c = Cell::new(c);
sibling_convos.push(p);
let mi = m2.clone();
// spawn sibling task
do task::spawn { // linked
- do mi.lock_cond |cond| {
+ mi.lock_cond(|cond| {
let c = c.take();
c.send(()); // tell sibling to go ahead
- do (|| {
+ (|| {
cond.wait(); // block forever
- }).finally {
+ }).finally(|| {
error!("task unwinding and sending");
c.send(());
error!("task unwinding and done sending");
- }
- }
+ })
+ })
}
- }
+ });
for p in sibling_convos.iter() {
let _ = p.recv(); // wait for sibling to get in the mutex
}
- do m2.lock { }
+ m2.lock(|| { });
c.send(sibling_convos); // let parent wait on all children
fail!();
};
// child task must have finished by the time try returns
let r = p.recv();
for p in r.iter() { p.recv(); } // wait on all its siblings
- do m.lock_cond |cond| {
+ m.lock_cond(|cond| {
let woken = cond.broadcast();
assert_eq!(woken, 0);
- }
+ })
}
#[test]
fn test_mutex_cond_signal_on_0() {
// Tests that signal_on(0) is equivalent to signal().
let m = Mutex::new();
- do m.lock_cond |cond| {
+ m.lock_cond(|cond| {
let m2 = m.clone();
do task::spawn {
- do m2.lock_cond |cond| {
+ m2.lock_cond(|cond| {
cond.signal_on(0);
- }
+ })
}
cond.wait();
- }
+ })
}
#[test]
fn test_mutex_different_conds() {
let m2 = m.clone();
let (p, c) = comm::stream();
do task::spawn {
- do m2.lock_cond |cond| {
+ m2.lock_cond(|cond| {
c.send(());
cond.wait_on(1);
- }
+ })
}
let _ = p.recv();
- do m.lock_cond |cond| {
+ m.lock_cond(|cond| {
if !cond.signal_on(0) {
fail!(); // success; punt sibling awake.
}
- }
+ })
};
assert!(result.is_err());
}
fn test_mutex_no_condvars() {
let result = do task::try {
let m = Mutex::new_with_condvars(0);
- do m.lock_cond |cond| { cond.wait(); }
+ m.lock_cond(|cond| { cond.wait(); })
};
assert!(result.is_err());
let result = do task::try {
let m = Mutex::new_with_condvars(0);
- do m.lock_cond |cond| { cond.signal(); }
+ m.lock_cond(|cond| { cond.signal(); })
};
assert!(result.is_err());
let result = do task::try {
let m = Mutex::new_with_condvars(0);
- do m.lock_cond |cond| { cond.broadcast(); }
+ m.lock_cond(|cond| { cond.broadcast(); })
};
assert!(result.is_err());
}
Read => x.read(blk),
Write => x.write(blk),
Downgrade =>
- do x.write_downgrade |mode| {
- do mode.write { blk() };
- },
+ x.write_downgrade(|mode| {
+ mode.write(|| { blk() });
+ }),
DowngradeRead =>
- do x.write_downgrade |mode| {
+ x.write_downgrade(|mode| {
let mode = x.downgrade(mode);
- do mode.read { blk() };
- },
+ mode.read(|| { blk() });
+ }),
}
}
#[cfg(test)]
fn access_shared(sharedstate: &mut int, x: &RWLock, mode: RWLockMode,
n: uint) {
- do n.times {
- do lock_rwlock_in_mode(x, mode) {
+ n.times(|| {
+ lock_rwlock_in_mode(x, mode, || {
let oldval = *sharedstate;
task::deschedule();
*sharedstate = oldval + 1;
- }
- }
+ })
+ })
}
}
#[test]
if !make_mode2_go_first {
let _ = p2.recv(); // parent sends to us once it locks, or ...
}
- do lock_rwlock_in_mode(&x2, mode2) {
+ lock_rwlock_in_mode(&x2, mode2, || {
if make_mode2_go_first {
c1.send(()); // ... we send to it once we lock
}
let _ = p2.recv();
c1.send(());
- }
+ })
}
if make_mode2_go_first {
let _ = p1.recv(); // child sends to us once it locks, or ...
}
- do lock_rwlock_in_mode(x, mode1) {
+ lock_rwlock_in_mode(x, mode1, || {
if !make_mode2_go_first {
c2.send(()); // ... we send to it once we lock
}
c2.send(());
let _ = p1.recv();
- }
+ })
}
#[test]
fn test_rwlock_readers_and_readers() {
fn test_rwlock_downgrade_unlock() {
// Tests that downgrade can unlock the lock in both modes
let x = RWLock::new();
- do lock_rwlock_in_mode(&x, Downgrade) { }
+ lock_rwlock_in_mode(&x, Downgrade, || { });
test_rwlock_handshake(&x, Read, Read, false);
let y = RWLock::new();
- do lock_rwlock_in_mode(&y, DowngradeRead) { }
+ lock_rwlock_in_mode(&y, DowngradeRead, || { });
test_rwlock_exclusion(&y, Write, Write);
}
#[test]
fn test_rwlock_read_recursive() {
let x = RWLock::new();
- do x.read { do x.read { } }
+ x.read(|| { x.read(|| { }) })
}
#[test]
fn test_rwlock_cond_wait() {
let x = RWLock::new();
// Child wakes up parent
- do x.write_cond |cond| {
+ x.write_cond(|cond| {
let x2 = x.clone();
do task::spawn {
- do x2.write_cond |cond| {
+ x2.write_cond(|cond| {
let woken = cond.signal();
assert!(woken);
- }
+ })
}
cond.wait();
- }
+ });
// Parent wakes up child
let (port, chan) = comm::stream();
let x3 = x.clone();
do task::spawn {
- do x3.write_cond |cond| {
+ x3.write_cond(|cond| {
chan.send(());
cond.wait();
chan.send(());
- }
+ })
}
let _ = port.recv(); // Wait until child gets in the rwlock
- do x.read { } // Must be able to get in as a reader in the meantime
- do x.write_cond |cond| { // Or as another writer
+ x.read(|| { }); // Must be able to get in as a reader in the meantime
+ x.write_cond(|cond| { // Or as another writer
let woken = cond.signal();
assert!(woken);
- }
+ });
let _ = port.recv(); // Wait until child wakes up
- do x.read { } // Just for good measure
+ x.read(|| { }); // Just for good measure
}
#[cfg(test)]
fn test_rwlock_cond_broadcast_helper(num_waiters: uint,
// Much like the mutex broadcast test. Downgrade-enabled.
fn lock_cond(x: &RWLock, downgrade: bool, blk: |c: &Condvar|) {
if downgrade {
- do x.write_downgrade |mode| {
- do mode.write_cond |c| { blk(c) }
- }
+ x.write_downgrade(|mode| {
+ mode.write_cond(|c| { blk(c) });
+ });
} else {
- do x.write_cond |c| { blk(c) }
+ x.write_cond(|c| { blk(c) });
}
}
let x = RWLock::new();
let mut ports = ~[];
- do num_waiters.times {
+ num_waiters.times(|| {
let xi = x.clone();
let (port, chan) = comm::stream();
ports.push(port);
do task::spawn {
- do lock_cond(&xi, dg1) |cond| {
+ lock_cond(&xi, dg1, |cond| {
chan.send(());
cond.wait();
chan.send(());
- }
+ })
}
- }
+ });
// wait until all children get in the mutex
for port in ports.iter() { let _ = port.recv(); }
- do lock_cond(&x, dg2) |cond| {
+ lock_cond(&x, dg2, |cond| {
let num_woken = cond.broadcast();
assert_eq!(num_woken, num_waiters);
- }
+ });
// wait until all children wake up
for port in ports.iter() { let _ = port.recv(); }
}
let x2 = x.clone();
let result: result::Result<(), ~Any> = do task::try || {
- do lock_rwlock_in_mode(&x2, mode1) {
+ lock_rwlock_in_mode(&x2, mode1, || {
fail!();
- }
+ })
};
assert!(result.is_err());
// child task must have finished by the time try returns
- do lock_rwlock_in_mode(&x, mode2) { }
+ lock_rwlock_in_mode(&x, mode2, || { })
}
#[test]
fn test_rwlock_reader_killed_writer() {
// Tests that you can't downgrade with a different rwlock's token.
let x = RWLock::new();
let y = RWLock::new();
- do x.write_downgrade |xwrite| {
+ x.write_downgrade(|xwrite| {
let mut xopt = Some(xwrite);
- do y.write_downgrade |_ywrite| {
+ y.write_downgrade(|_ywrite| {
y.downgrade(xopt.take_unwrap());
error!("oops, y.downgrade(x) should have failed!");
- }
- }
+ })
+ })
}
}
g
};
let mut pool = TaskPool::new(4, Some(SingleThreaded), f);
- do 8.times {
+ 8.times(|| {
pool.execute(|i| println!("Hello from thread {}!", *i));
- }
+ })
}
let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(&[42]);
- do 3.times {
- do 90.times {
+ 3.times(|| {
+ 90.times(|| {
let k = rng.gen();
let v = rng.gen();
if !ctrl.iter().any(|x| x == &(k, v)) {
check_structure(&map);
check_equal(ctrl, &map);
}
- }
+ });
- do 30.times {
+ 30.times(|| {
let r = rng.gen_range(0, ctrl.len());
let (key, _) = ctrl.remove(r);
assert!(map.remove(&key));
check_structure(&map);
check_equal(ctrl, &map);
- }
- }
+ });
+ })
}
#[test]
for y in b.iter() { assert!(set_b.insert(*y)) }
let mut i = 0;
- do f(&set_a, &set_b) |x| {
+ f(&set_a, &set_b, |x| {
assert_eq!(*x, expected[i]);
i += 1;
true
- };
+ });
assert_eq!(i, expected.len());
}
#[bench]
pub fn create_uuids(bh: &mut BenchHarness) {
- do bh.iter {
+ bh.iter(|| {
Uuid::new_v4();
- }
+ })
}
#[bench]
pub fn uuid_to_str(bh: &mut BenchHarness) {
let u = Uuid::new_v4();
- do bh.iter {
+ bh.iter(|| {
u.to_str();
- }
+ })
}
#[bench]
pub fn parse_str(bh: &mut BenchHarness) {
let s = "urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
- do bh.iter {
+ bh.iter(|| {
Uuid::parse_string(s);
- }
+ })
}
}
fn test_executable_exists(repo: &Path, short_name: &str) -> bool {
debug!("test_executable_exists: repo = {}, short_name = {}", repo.display(), short_name);
let exec = built_test_in_workspace(&PkgId::new(short_name), repo);
- exec.map_default(false, |exec| exec.exists() && is_rwx(&exec));
+ exec.map_default(false, |exec| exec.exists() && is_rwx(&exec))
}
fn remove_executable_file(p: &PkgId, workspace: &Path) {
unsafe {
cast::transmute(Local::borrow(|sched: &mut Scheduler| {
let mut io = None;
- do sched.event_loop.io |i| {
+ sched.event_loop.io(|i| {
let (_vtable, uvio): (uint, &'static mut uvio::UvIoFactory) =
cast::transmute(i);
io = Some(uvio);
- }
+ });
io.unwrap()
}).uv_loop())
}
// parse a string, return a crate.
pub fn string_to_crate (source_str : @str) -> ast::Crate {
- do with_error_checking_parse(source_str) |p| {
+ with_error_checking_parse(source_str, |p| {
p.parse_crate_mod()
- }
+ })
}
// parse a string, return a crate and the ParseSess
// parse a string, return an expr
pub fn string_to_expr (source_str : @str) -> @ast::Expr {
- do with_error_checking_parse(source_str) |p| {
+ with_error_checking_parse(source_str, |p| {
p.parse_expr()
- }
+ })
}
// parse a string, return an item
pub fn string_to_item (source_str : @str) -> Option<@ast::item> {
- do with_error_checking_parse(source_str) |p| {
+ with_error_checking_parse(source_str, |p| {
p.parse_item(~[])
- }
+ })
}
// parse a string, return a stmt
pub fn string_to_stmt(source_str : @str) -> @ast::Stmt {
- do with_error_checking_parse(source_str) |p| {
+ with_error_checking_parse(source_str, |p| {
p.parse_stmt(~[])
- }
+ })
}
// parse a string, return a pat. Uses "irrefutable"... which doesn't
fn ascending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
println(" Ascending integers:");
- do timed("insert") {
+ timed("insert", || {
for i in range(0u, n_keys) {
map.insert(i, i + 1);
}
- }
+ });
- do timed("search") {
+ timed("search", || {
for i in range(0u, n_keys) {
assert_eq!(map.find(&i).unwrap(), &(i + 1));
}
- }
+ });
- do timed("remove") {
+ timed("remove", || {
for i in range(0, n_keys) {
assert!(map.remove(&i));
}
- }
+ });
}
fn descending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
println(" Descending integers:");
- do timed("insert") {
+ timed("insert", || {
for i in range(0, n_keys).invert() {
map.insert(i, i + 1);
}
- }
+ });
- do timed("search") {
+ timed("search", || {
for i in range(0, n_keys).invert() {
assert_eq!(map.find(&i).unwrap(), &(i + 1));
}
- }
+ });
- do timed("remove") {
+ timed("remove", || {
for i in range(0, n_keys) {
assert!(map.remove(&i));
}
- }
+ });
}
fn vector<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {
-
- do timed("insert") {
+ timed("insert", || {
for i in range(0u, n_keys) {
map.insert(dist[i], i + 1);
}
- }
+ });
- do timed("search") {
+ timed("search", || {
for i in range(0u, n_keys) {
assert_eq!(map.find(&dist[i]).unwrap(), &(i + 1));
}
- }
+ });
- do timed("remove") {
+ timed("remove", || {
for i in range(0u, n_keys) {
assert!(map.remove(&dist[i]));
}
- }
+ });
}
fn main() {
rand_cap: uint,
f: || -> T) { {
let mut set = f();
- do timed(&mut self.sequential_ints) {
+ timed(&mut self.sequential_ints, || {
for i in range(0u, num_keys) {
set.insert(i);
}
for i in range(0u, num_keys) {
assert!(set.contains(&i));
}
- }
+ })
}
{
let mut set = f();
- do timed(&mut self.random_ints) {
+ timed(&mut self.random_ints, || {
for _ in range(0, num_keys) {
set.insert(rng.gen::<uint>() % rand_cap);
}
- }
+ })
}
{
set.insert(i);
}
- do timed(&mut self.delete_ints) {
+ timed(&mut self.delete_ints, || {
for i in range(0u, num_keys) {
assert!(set.remove(&i));
}
- }
+ })
}
}
f: || -> T) {
{
let mut set = f();
- do timed(&mut self.sequential_strings) {
+ timed(&mut self.sequential_strings, || {
for i in range(0u, num_keys) {
set.insert(i.to_str());
}
for i in range(0u, num_keys) {
assert!(set.contains(&i.to_str()));
}
- }
+ })
}
{
let mut set = f();
- do timed(&mut self.random_strings) {
+ timed(&mut self.random_strings, || {
for _ in range(0, num_keys) {
let s = rng.gen::<uint>().to_str();
set.insert(s);
}
- }
+ })
}
{
for i in range(0u, num_keys) {
set.insert(i.to_str());
}
- do timed(&mut self.delete_strings) {
+ timed(&mut self.delete_strings, || {
for i in range(0u, num_keys) {
assert!(set.remove(&i.to_str()));
}
- }
+ })
}
}
}
fn send(p: &pipe, msg: uint) {
unsafe {
- do p.access_cond |state, cond| {
+ p.access_cond(|state, cond| {
state.push(msg);
cond.signal();
- }
+ })
}
}
fn recv(p: &pipe) -> uint {
unsafe {
- do p.access_cond |state, cond| {
+ p.access_cond(|state, cond| {
while state.is_empty() {
cond.wait();
}
state.pop()
- }
+ })
}
}
type pipe = arc::RWArc<~[uint]>;
fn send(p: &pipe, msg: uint) {
- do p.write_cond |state, cond| {
+ p.write_cond(|state, cond| {
state.push(msg);
cond.signal();
- }
+ })
}
fn recv(p: &pipe) -> uint {
- do p.write_cond |state, cond| {
+ p.write_cond(|state, cond| {
while state.is_empty() {
cond.wait();
}
state.pop()
- }
+ })
}
fn init() -> (pipe,pipe) {
do spawntask_later() || {
let chan = ca.take();
let port = pb.take();
- do n.times {
+ n.times(|| {
chan.send(());
port.recv();
- }
+ })
}
do spawntask_later() || {
let chan = cb.take();
let port = pa.take();
- do n.times {
+ n.times(|| {
port.recv();
chan.send(());
- }
+ })
}
}
- do m.times {
+ m.times(|| {
run_pair(n)
- }
-
+ })
}
100000
};
- do n.times {
+ n.times(|| {
do spawn || {};
- }
+ })
}
fn bottom_up_tree<'r>(arena: &'r Arena, item: int, depth: int) -> &'r Tree<'r> {
if depth > 0 {
- do arena.alloc {
+ arena.alloc(|| {
Node(bottom_up_tree(arena, 2 * item - 1, depth - 1),
bottom_up_tree(arena, 2 * item, depth - 1),
item)
- }
+ })
} else {arena.alloc(|| Nil)}
}
let sizes = ~[1u,2,3,4,6,12,18];
let mut streams = vec::from_fn(sizes.len(), |_| Some(stream::<~str>()));
let mut from_child = ~[];
- let to_child = do sizes.iter().zip(streams.mut_iter()).map |(sz, stream_ref)| {
+ let to_child = sizes.iter().zip(streams.mut_iter()).map(|(sz, stream_ref)| {
let sz = *sz;
let stream = util::replace(stream_ref, None);
let (from_child_, to_parent_) = stream.unwrap();
}
to_child
- }.collect::<~[Chan<~[u8]>]>();
+ }).collect::<~[Chan<~[u8]>]>();
// latch stores true after we've started
Iterate {f: f, next: x}
}
struct Iterate<'self, T> {
- priv f: &'self |&T| -> T,
+ priv f: 'self |&T| -> T,
priv next: T
}
impl<'self, T> Iterator<T> for Iterate<'self, T> {
}
pub fn from_vec(vec: &[[u8, ..9], ..9]) -> Sudoku {
- let g = do vec::from_fn(9u) |i| {
- do vec::from_fn(9u) |j| { vec[i][j] }
- };
+ let g = vec::from_fn(9u, |i| {
+ vec::from_fn(9u, |j| { vec[i][j] })
+ });
return Sudoku::new(g)
}
fn calc(children: uint, parent_wait_chan: &Chan<Chan<Chan<int>>>) {
- let wait_ports: ~[Port<Chan<Chan<int>>>] = do vec::from_fn(children) |_| {
+ let wait_ports: ~[Port<Chan<Chan<int>>>] = vec::from_fn(children, |_| {
let (wait_port, wait_chan) = stream::<Chan<Chan<int>>>();
do task::spawn {
calc(children / 2, &wait_chan);
}
wait_port
- };
+ });
let child_start_chans: ~[Chan<Chan<int>>] =
wait_ports.move_iter().map(|port| port.recv()).collect();
let parent_result_chan: Chan<int> = start_port.recv();
let child_sum_ports: ~[Port<int>] =
- do child_start_chans.move_iter().map |child_start_chan| {
+ child_start_chans.move_iter().map(|child_start_chan| {
let (child_sum_port, child_sum_chan) = stream::<int>();
child_start_chan.send(child_sum_chan);
child_sum_port
- }.collect();
+ }).collect();
let sum = child_sum_ports.move_iter().fold(0, |sum, sum_port| sum + sum_port.recv() );