aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2022-07-25 22:16:59 +0100
committerLouis Pilfold <louis@lpil.uk>2022-07-25 22:17:05 +0100
commitf4ff3b795e105e216c1a3b4d9b350f06533e1927 (patch)
treea476802d119dd7b0de695aaaab351cfd1f5d5367
parent472fbe4fb741f274be1054276065a4b06b84f92a (diff)
downloadgleam_stdlib-f4ff3b795e105e216c1a3b4d9b350f06533e1927.tar.gz
gleam_stdlib-f4ff3b795e105e216c1a3b4d9b350f06533e1927.zip
Make list.range tail recursive
-rw-r--r--src/gleam/list.gleam10
-rw-r--r--test/gleam/list_test.gleam3
2 files changed, 10 insertions, 3 deletions
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam
index c787935..1a9d5ce 100644
--- a/src/gleam/list.gleam
+++ b/src/gleam/list.gleam
@@ -1048,10 +1048,14 @@ pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) {
/// ```
///
pub fn range(from start: Int, to stop: Int) -> List(Int) {
+ tail_recursive_range(start, stop, [])
+}
+
+fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) {
case int.compare(start, stop) {
- order.Eq -> []
- order.Gt -> [start, ..range(start - 1, stop)]
- order.Lt -> [start, ..range(start + 1, stop)]
+ order.Eq -> reverse(acc)
+ order.Gt -> tail_recursive_range(start - 1, stop, [start, ..acc])
+ order.Lt -> tail_recursive_range(start + 1, stop, [start, ..acc])
}
}
diff --git a/test/gleam/list_test.gleam b/test/gleam/list_test.gleam
index 971a5f1..566aa94 100644
--- a/test/gleam/list_test.gleam
+++ b/test/gleam/list_test.gleam
@@ -488,6 +488,9 @@ pub fn range_test() {
list.range(1, -5)
|> should.equal([1, 0, -1, -2, -3, -4])
+
+ // This should not overflow the stack
+ list.range(1, 100_000)
}
pub fn repeat_test() {