Skip to content

Commit b2b07ef

Browse files
chuckwondolpil
authored andcommitted
Make iterator.any/all TCO eligible in JavaScript
Fixes #427
1 parent 35b5049 commit b2b07ef

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

src/gleam/iterator.gleam

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,11 @@ fn do_any(
995995
) -> Bool {
996996
case continuation() {
997997
Stop -> False
998-
Continue(e, next) -> predicate(e) || do_any(next, predicate)
998+
Continue(e, next) ->
999+
case predicate(e) {
1000+
True -> True
1001+
False -> do_any(next, predicate)
1002+
}
9991003
}
10001004
}
10011005

@@ -1037,7 +1041,11 @@ fn do_all(
10371041
) -> Bool {
10381042
case continuation() {
10391043
Stop -> True
1040-
Continue(e, next) -> predicate(e) && do_all(next, predicate)
1044+
Continue(e, next) ->
1045+
case predicate(e) {
1046+
True -> do_all(next, predicate)
1047+
False -> False
1048+
}
10411049
}
10421050
}
10431051

@@ -1391,10 +1399,10 @@ fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int {
13911399
/// Counts the number of elements in the given iterator.
13921400
///
13931401
/// This function has to traverse the entire iterator to count its elements,
1394-
/// so it runs in linear time.
1402+
/// so it runs in linear time.
13951403
///
13961404
/// ## Examples
1397-
///
1405+
///
13981406
/// ```gleam
13991407
/// > empty() |> length
14001408
/// 0

test/gleam/iterator_test.gleam

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ pub fn any_test() {
406406
iterator.from_list([1, 3, 5, 7, 9])
407407
|> iterator.any(satisfying: fn(n) { n % 2 == 0 })
408408
|> should.be_false
409+
410+
// TCO test
411+
iterator.repeat(1)
412+
|> iterator.take(1_000_000)
413+
|> iterator.any(satisfying: fn(n) { n % 2 == 0 })
414+
|> should.be_false
409415
}
410416

411417
pub fn all_test() {
@@ -420,6 +426,12 @@ pub fn all_test() {
420426
iterator.from_list([2, 4, 5, 8])
421427
|> iterator.all(satisfying: fn(n) { n % 2 == 0 })
422428
|> should.be_false
429+
430+
// TCO test
431+
iterator.repeat(0)
432+
|> iterator.take(1_000_000)
433+
|> iterator.all(satisfying: fn(n) { n % 2 == 0 })
434+
|> should.be_true
423435
}
424436

425437
pub fn group_test() {

0 commit comments

Comments
 (0)