Skip to content

Commit 02505d8

Browse files
committed
Express some list primitives in a way that doesn't copy
It was somewhat embarassing that list::len copied its elements.
1 parent 0e98e64 commit 02505d8

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

src/libstd/list.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,10 @@ ls - The list to fold
4646
z - The initial value
4747
f - The function to apply
4848
*/
49-
fn foldl<copy T, copy U>(ls: list<U>, z: T, f: block(T, U) -> T) -> T {
49+
fn foldl<copy T, U>(ls: list<U>, z: T, f: block(T, U) -> T) -> T {
5050
let accum: T = z;
51-
let ls = ls;
52-
while true {
53-
alt ls {
54-
cons(hd, tl) { accum = f(accum, hd); ls = *tl; }
55-
nil. { break; }
56-
}
57-
}
58-
ret accum;
51+
iter(ls) {|elt| accum = f(accum, elt);}
52+
accum
5953
}
6054

6155
/*
@@ -123,9 +117,10 @@ Function: len
123117
124118
Returns the length of a list
125119
*/
126-
fn len<copy T>(ls: list<T>) -> uint {
127-
fn count<T>(&&u: uint, _t: T) -> uint { ret u + 1u; }
128-
ret foldl(ls, 0u, bind count(_, _));
120+
fn len<T>(ls: list<T>) -> uint {
121+
let count = 0u;
122+
iter(ls) {|_e| count += 1u;}
123+
count
129124
}
130125

131126
/*
@@ -169,15 +164,22 @@ Function: iter
169164
170165
Iterate over a list
171166
*/
172-
fn iter<copy T>(l: list<T>, f: block(T)) {
173-
let cur = l;
174-
while cur != nil {
175-
alt cur {
176-
cons(hd, tl) {
177-
f(hd);
178-
cur = *tl;
179-
}
167+
fn iter<T>(l: list<T>, f: block(T)) {
168+
alt l {
169+
cons(hd, tl) {
170+
f(hd);
171+
let cur = tl;
172+
while true {
173+
alt *cur {
174+
cons(hd, tl) {
175+
f(hd);
176+
cur = tl;
177+
}
178+
nil. { break; }
179+
}
180180
}
181+
}
182+
nil. {}
181183
}
182184
}
183185

0 commit comments

Comments
 (0)