a fast, general-purpose, persistent array structure for Gleam.
28

Configure Feed

Select the types of activity you want to include in your feed.

deprecate iv.range

yoshie (Dec 16, 2025, 12:16 AM +0100) 32b71739 5b6271dd

+22 -122
+1 -1
TODO
··· 8 8 [ ] deprecate anything that promotes slow code (delete maybe) 9 9 [ ] the append/lens optimisation 10 10 [ ] measure when O(log n) concat is worth it vs not, heuristics etc 11 - [ ] deprecate iv.range 11 + [x] deprecate iv.range
+3 -3
src/iv.gleam
··· 55 55 //// [new](#new "Create an empty array"), 56 56 //// [wrap](#wrap "A single element"), 57 57 //// [repeat](#repeat "Repeat a single element"), 58 - //// [range](#range "Range of integers"), 59 58 //// [from_list](#from_list "Convert a list to an array"), 60 59 //// [from_reverse_list](#from_reverse_list "Convert a reversed list to an array"), 61 60 //// [from_yielder](#from_yielder "Consume any yielder to build an array"), ··· 294 293 /// Convert an array to a standard Gleam list. 295 294 /// 296 295 /// ```gleam 297 - /// to_list(range(1, 5)) 296 + /// to_list(initialise(5, fn(x) { x + 1 })) 298 297 /// // --> [1, 2, 3, 4, 5] 299 298 /// ``` 300 299 /// ··· 388 387 /// <small>Back to top ↑</small> 389 388 /// </a> 390 389 /// </div> 390 + @deprecated("use initialise instead.") 391 391 pub fn range(from start: Int, to stop: Int) -> Array(Int) { 392 392 case start <= stop { 393 393 True -> initialise(stop - start + 1, fn(x) { x + start }) ··· 481 481 /// Arrays containing the same elements can have different runtime representations. 482 482 /// 483 483 /// ```gleam 484 - /// equal(from_list([1, 2, 3]), range(1, 3)) 484 + /// equal(from_list([1, 2, 3]), initialise(3, fn(x) { x + 1 })) 485 485 /// // --> True 486 486 /// 487 487 /// equal(from_list([1, 2, 3]), from_list([1]))
+1 -1
test/benchmark.gleam
··· 46 46 [ 47 47 bench.Function("create", fn(input) { 48 48 let count = iv.size(input) 49 - iv.range(1, count) 49 + iv.initialise(count, fn(i) { i + 1 }) 50 50 Nil 51 51 }), 52 52 bench.Function("insert 1k elements", fn(input) {
+3 -11
test/doc_test.gleam
··· 10 10 fold_right, from_list, from_reverse_list, from_yielder, get, get_or_default, 11 11 index_map, index_of, initialise, insert, insert_clamped, insert_list, 12 12 insert_list_clamped, is_empty, join, last, last_index_of, leading, map, map2, 13 - new, prepend, prepend_list, prepend_reverse_list, range, repeat, replace, rest, 13 + new, prepend, prepend_list, prepend_reverse_list, repeat, replace, rest, 14 14 reverse, set, size, slice, splice, split, take_first, take_last, to_list, 15 15 to_yielder, try_delete, try_map, try_set, try_update, update, wrap, zip, 16 16 } ··· 526 526 } 527 527 528 528 pub fn doc_equal_test() { 529 - equal(from_list([1, 2, 3]), range(1, 3)) 529 + equal(from_list([1, 2, 3]), initialise(3, fn(x) { x + 1 })) 530 530 |> should.equal(True) 531 531 532 532 equal(from_list([1, 2, 3]), from_list([1])) ··· 556 556 |> equal_elements([0, 2, 4, 6, 8]) 557 557 } 558 558 559 - pub fn doc_range_test() { 560 - range(1, 3) 561 - |> equal_elements([1, 2, 3]) 562 - 563 - range(10, 1) 564 - |> equal_elements([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) 565 - } 566 - 567 559 pub fn doc_repeat_test() { 568 560 repeat("hi", times: 3) 569 561 |> equal_elements(["hi", "hi", "hi"]) ··· 584 576 } 585 577 586 578 pub fn doc_to_list_test() { 587 - to_list(range(1, 5)) 579 + to_list(initialise(5, fn(x) { x + 1 })) 588 580 |> should.equal([1, 2, 3, 4, 5]) 589 581 } 590 582
+14 -13
test/iv_test.gleam
··· 43 43 pub fn split_concat_test() { 44 44 let sizes = [10, 100, 1000] 45 45 use size <- list.each(sizes) 46 - let array = iv.range(0, size - 1) 46 + let array = iv.initialise(size, fn(x) { x }) 47 47 use idx <- iv.each(array) 48 48 let #(before, after) = iv.split(array, idx) 49 49 iv.concat(before, after) ··· 53 53 pub fn split_concat2_test() { 54 54 let sizes = [10, 100] 55 55 use size <- list.each(sizes) 56 - let array = iv.range(0, size - 1) 56 + let array = iv.initialise(size, fn(x) { x }) 57 57 use idx <- iv.each(array) 58 58 let #(before, after) = iv.split(array, idx) 59 59 use before_split <- loop(iv.size(before)) ··· 72 72 pub fn split_test() { 73 73 let sizes = [10, 100, 1000, 10_000] 74 74 use size <- list.each(sizes) 75 - let array = iv.range(0, size - 1) 75 + let array = iv.initialise(size, fn(x) { x }) 76 76 use idx <- iv.each(array) 77 77 let #(before, after) = iv.split(array, idx) 78 78 ··· 89 89 } 90 90 91 91 pub fn get_test() { 92 - let arr = iv.range(1, 100_000) 92 + let arr = iv.initialise(100_000, fn(x) { x + 1 }) 93 93 test_utils.loop(iv.size(arr), fn(i) { 94 94 assert iv.get(arr, i - 1) == Ok(i) 95 95 }) ··· 103 103 } 104 104 105 105 pub fn index_test() { 106 - iv.range(1, 100) 106 + iv.initialise(100, fn(x) { x + 1 }) 107 107 |> iv.find_index(fn(x) { x > 90 }) 108 108 |> should.equal(Ok(90)) 109 109 110 - iv.range(1, 1024) 110 + iv.initialise(1024, fn(x) { x + 1 }) 111 111 |> iv.find_index(fn(x) { x > 900 }) 112 112 |> should.equal(Ok(900)) 113 113 } 114 114 115 115 pub fn last_index_test() { 116 - iv.range(1, 100) 116 + iv.initialise(100, fn(x) { x + 1 }) 117 117 |> iv.find_last_index(fn(x) { x < 90 }) 118 118 |> should.equal(Ok(88)) 119 119 120 - iv.range(1, 1024) 120 + iv.initialise(1024, fn(x) { x + 1 }) 121 121 |> iv.find_last_index(fn(x) { x < 900 }) 122 122 |> should.equal(Ok(898)) 123 123 } ··· 125 125 pub fn yielder_test() { 126 126 let sizes = [10, 100, 1000, 10_000] 127 127 use size <- list.each(sizes) 128 - let array = iv.range(0, size - 1) 128 + let array = iv.initialise(size, fn(x) { x }) 129 129 130 130 iv.to_yielder(array) 131 131 |> yielder.to_list ··· 133 133 } 134 134 135 135 pub fn index_map_test() { 136 - let arr = iv.range(0, 1024) 136 + let arr = iv.initialise(1024, fn(x) { x }) 137 137 arr 138 138 |> iv.index_map(fn(_, i) { i }) 139 139 |> test_utils.equal_arrays(arr) 140 140 141 - let arr = iv.concat(iv.range(0, 500), iv.range(0, 500)) 141 + let arr = 142 + iv.concat(iv.initialise(501, fn(x) { x }), iv.initialise(501, fn(x) { x })) 142 143 arr 143 144 |> iv.index_map(fn(_, i) { i }) 144 145 |> test_utils.equal_elements(list.range(0, 1001)) 145 146 } 146 147 147 148 pub fn index_fold_test() { 148 - let arr = iv.range(0, 100_000) 149 + let arr = iv.initialise(100_000, fn(x) { x }) 149 150 iv.index_fold(arr, 0, fn(acc, _, index) { 150 151 assert acc == index 151 152 acc + 1 ··· 153 154 } 154 155 155 156 pub fn index_fold_right_test() { 156 - let arr = iv.range(0, 100_000) 157 + let arr = iv.initialise(100_000, fn(x) { x }) 157 158 iv.index_fold_right(arr, iv.size(arr) - 1, fn(acc, _, index) { 158 159 assert acc == index 159 160 acc - 1
-93
test/loop_bench.gleam
··· 1 - import gleam/io 2 - import gleam/list 3 - import gleam/yielder 4 - import gleamy/bench 5 - import iv 6 - 7 - pub fn main() { 8 - bench.run( 9 - [ 10 - bench.Input("10", 10), 11 - // bench.Input("100", 100), 12 - bench.Input("1000", 1000), 13 - // bench.Input("10k", 10_000), 14 - bench.Input("100k", 100_000), 15 - ], 16 - [ 17 - bench.SetupFunction("iv:fold", fold(array, iv.fold, body)), 18 - bench.SetupFunction("iv:try_fold", fold(array, iv.try_fold, try_body)), 19 - bench.SetupFunction( 20 - "yielder:try_fold", 21 - fold(yielder, yielder.try_fold, try_body), 22 - ), 23 - bench.SetupFunction("iv:index", fn(input) { 24 - let array = array(input) 25 - fn(_) { array_loop(array, 0, iv.size(array), 0) } 26 - }), 27 - bench.SetupFunction("iv:uncons", fn(input) { 28 - let array = array(input) 29 - fn(_) { list_loop(iv.to_list(array), 0) } 30 - }), 31 - bench.SetupFunction("list:uncons", fn(input) { 32 - let list = list(input) 33 - fn(_) { list_loop(list, 0) } 34 - }), 35 - bench.SetupFunction("list:fold", fold(list, list.fold, body)), 36 - bench.SetupFunction("list:try_fold", fold(list, list.try_fold, try_body)), 37 - ], 38 - [bench.Duration(1000), bench.Warmup(300)], 39 - ) 40 - |> bench.table([bench.IPS, bench.Min, bench.P(99)]) 41 - |> io.println 42 - } 43 - 44 - fn fold(to_collection, fold, body) { 45 - fn(input) { 46 - let collection = to_collection(input) 47 - fn(_) { 48 - let _ = fold(collection, 0, body) 49 - Nil 50 - } 51 - } 52 - } 53 - 54 - fn array_loop(array, index, len, acc) { 55 - case index < len { 56 - True -> 57 - array_loop( 58 - array, 59 - index + 1, 60 - len, 61 - acc + iv.get_or_default(array, index, 0), 62 - ) 63 - False -> Nil 64 - } 65 - } 66 - 67 - fn list_loop(list, acc) { 68 - case list { 69 - [] -> Nil 70 - [x, ..xs] -> list_loop(xs, acc + x) 71 - } 72 - } 73 - 74 - fn array(input) { 75 - iv.range(0, input) 76 - } 77 - 78 - fn yielder(input) { 79 - iv.range(0, input) 80 - |> iv.to_yielder 81 - } 82 - 83 - fn list(input) { 84 - list.range(0, input) 85 - } 86 - 87 - fn body(a, b) { 88 - a + b 89 - } 90 - 91 - fn try_body(a, b) { 92 - Ok(a + b) 93 - }