@grain/stdlib 0.5.13 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/CHANGELOG.md +201 -0
  2. package/LICENSE +1 -1
  3. package/README.md +25 -2
  4. package/array.gr +1512 -199
  5. package/array.md +2032 -94
  6. package/bigint.gr +239 -140
  7. package/bigint.md +450 -106
  8. package/buffer.gr +595 -102
  9. package/buffer.md +903 -145
  10. package/bytes.gr +401 -110
  11. package/bytes.md +551 -63
  12. package/char.gr +228 -49
  13. package/char.md +373 -7
  14. package/exception.gr +26 -12
  15. package/exception.md +29 -5
  16. package/float32.gr +130 -109
  17. package/float32.md +185 -57
  18. package/float64.gr +112 -99
  19. package/float64.md +185 -57
  20. package/hash.gr +62 -40
  21. package/hash.md +27 -3
  22. package/int16.gr +430 -0
  23. package/int16.md +618 -0
  24. package/int32.gr +200 -269
  25. package/int32.md +254 -289
  26. package/int64.gr +142 -225
  27. package/int64.md +254 -289
  28. package/int8.gr +511 -0
  29. package/int8.md +786 -0
  30. package/json.gr +2071 -0
  31. package/json.md +646 -0
  32. package/list.gr +120 -68
  33. package/list.md +125 -80
  34. package/map.gr +560 -57
  35. package/map.md +672 -56
  36. package/marshal.gr +239 -227
  37. package/marshal.md +36 -4
  38. package/number.gr +626 -676
  39. package/number.md +738 -153
  40. package/option.gr +33 -35
  41. package/option.md +58 -42
  42. package/package.json +2 -2
  43. package/path.gr +148 -187
  44. package/path.md +47 -96
  45. package/pervasives.gr +75 -416
  46. package/pervasives.md +85 -180
  47. package/priorityqueue.gr +433 -74
  48. package/priorityqueue.md +422 -54
  49. package/queue.gr +362 -80
  50. package/queue.md +433 -38
  51. package/random.gr +67 -75
  52. package/random.md +68 -40
  53. package/range.gr +135 -63
  54. package/range.md +198 -43
  55. package/rational.gr +284 -0
  56. package/rational.md +545 -0
  57. package/regex.gr +933 -1066
  58. package/regex.md +59 -60
  59. package/result.gr +23 -25
  60. package/result.md +54 -39
  61. package/runtime/atof/common.gr +78 -82
  62. package/runtime/atof/common.md +22 -10
  63. package/runtime/atof/decimal.gr +102 -127
  64. package/runtime/atof/decimal.md +28 -7
  65. package/runtime/atof/lemire.gr +56 -71
  66. package/runtime/atof/lemire.md +9 -1
  67. package/runtime/atof/parse.gr +83 -110
  68. package/runtime/atof/parse.md +12 -2
  69. package/runtime/atof/slow.gr +28 -35
  70. package/runtime/atof/slow.md +9 -1
  71. package/runtime/atof/table.gr +19 -18
  72. package/runtime/atof/table.md +10 -2
  73. package/runtime/atoi/parse.gr +153 -136
  74. package/runtime/atoi/parse.md +50 -1
  75. package/runtime/bigint.gr +410 -517
  76. package/runtime/bigint.md +71 -57
  77. package/runtime/compare.gr +176 -85
  78. package/runtime/compare.md +31 -1
  79. package/runtime/dataStructures.gr +144 -32
  80. package/runtime/dataStructures.md +267 -31
  81. package/runtime/debugPrint.gr +34 -15
  82. package/runtime/debugPrint.md +37 -5
  83. package/runtime/equal.gr +53 -52
  84. package/runtime/equal.md +30 -1
  85. package/runtime/exception.gr +38 -47
  86. package/runtime/exception.md +10 -8
  87. package/runtime/gc.gr +23 -152
  88. package/runtime/gc.md +13 -17
  89. package/runtime/malloc.gr +31 -31
  90. package/runtime/malloc.md +11 -3
  91. package/runtime/numberUtils.gr +193 -174
  92. package/runtime/numberUtils.md +29 -9
  93. package/runtime/numbers.gr +1695 -1021
  94. package/runtime/numbers.md +1098 -134
  95. package/runtime/string.gr +543 -245
  96. package/runtime/string.md +76 -6
  97. package/runtime/unsafe/constants.gr +30 -13
  98. package/runtime/unsafe/constants.md +80 -0
  99. package/runtime/unsafe/conv.gr +55 -28
  100. package/runtime/unsafe/conv.md +41 -9
  101. package/runtime/unsafe/memory.gr +10 -30
  102. package/runtime/unsafe/memory.md +15 -19
  103. package/runtime/unsafe/tags.gr +37 -21
  104. package/runtime/unsafe/tags.md +88 -8
  105. package/runtime/unsafe/wasmf32.gr +30 -36
  106. package/runtime/unsafe/wasmf32.md +64 -56
  107. package/runtime/unsafe/wasmf64.gr +30 -36
  108. package/runtime/unsafe/wasmf64.md +64 -56
  109. package/runtime/unsafe/wasmi32.gr +49 -66
  110. package/runtime/unsafe/wasmi32.md +102 -94
  111. package/runtime/unsafe/wasmi64.gr +52 -79
  112. package/runtime/unsafe/wasmi64.md +108 -100
  113. package/runtime/utils/printing.gr +13 -15
  114. package/runtime/utils/printing.md +11 -3
  115. package/runtime/wasi.gr +294 -295
  116. package/runtime/wasi.md +62 -42
  117. package/set.gr +574 -64
  118. package/set.md +634 -54
  119. package/stack.gr +181 -64
  120. package/stack.md +271 -42
  121. package/string.gr +453 -533
  122. package/string.md +241 -151
  123. package/uint16.gr +369 -0
  124. package/uint16.md +585 -0
  125. package/uint32.gr +470 -0
  126. package/uint32.md +737 -0
  127. package/uint64.gr +471 -0
  128. package/uint64.md +737 -0
  129. package/uint8.gr +369 -0
  130. package/uint8.md +585 -0
  131. package/uri.gr +1093 -0
  132. package/uri.md +477 -0
  133. package/{sys → wasi}/file.gr +914 -500
  134. package/{sys → wasi}/file.md +454 -50
  135. package/wasi/process.gr +292 -0
  136. package/{sys → wasi}/process.md +164 -6
  137. package/wasi/random.gr +77 -0
  138. package/wasi/random.md +80 -0
  139. package/{sys → wasi}/time.gr +15 -22
  140. package/{sys → wasi}/time.md +5 -5
  141. package/immutablearray.gr +0 -929
  142. package/immutablearray.md +0 -1038
  143. package/immutablemap.gr +0 -493
  144. package/immutablemap.md +0 -479
  145. package/immutablepriorityqueue.gr +0 -360
  146. package/immutablepriorityqueue.md +0 -291
  147. package/immutableset.gr +0 -498
  148. package/immutableset.md +0 -449
  149. package/runtime/debug.gr +0 -2
  150. package/runtime/debug.md +0 -6
  151. package/runtime/unsafe/errors.gr +0 -36
  152. package/runtime/unsafe/errors.md +0 -204
  153. package/sys/process.gr +0 -254
  154. package/sys/random.gr +0 -79
  155. package/sys/random.md +0 -66
package/random.gr CHANGED
@@ -1,58 +1,53 @@
1
1
  /**
2
- * @module Random: Pseudo-random number generation.
3
- * @example import Random from "random"
2
+ * Pseudo-random number generation.
3
+ *
4
+ * @example from "random" include Random
5
+ *
4
6
  * @since v0.5.0
5
7
  */
6
- import WasiRandom from "sys/random"
7
- import Result from "result"
8
- import Int32 from "int32"
9
- import Int64 from "int64"
10
- import WasmI32 from "runtime/unsafe/wasmi32"
11
- import WasmI64 from "runtime/unsafe/wasmi64"
12
- import Memory from "runtime/unsafe/memory"
13
- import DS from "runtime/dataStructures"
8
+ module Random
14
9
 
15
- /**
16
- * @section Types: Type declarations included in the Random module.
17
- */
10
+ from "wasi/random" include Random as WasiRandom
11
+ from "result" include Result
12
+ from "uint32" include Uint32
13
+ from "uint64" include Uint64
14
+ from "runtime/unsafe/wasmi32" include WasmI32
15
+ from "runtime/unsafe/wasmi64" include WasmI64
16
+ from "runtime/unsafe/memory" include Memory
17
+ from "runtime/dataStructures" include DataStructures as DS
18
18
 
19
- record Random {
20
- seed: Int64,
21
- mut counter: Int64,
19
+ abstract record Random {
20
+ seed: Uint64,
21
+ mut counter: Uint64,
22
22
  mut initialized: Bool,
23
23
  }
24
24
 
25
- /**
26
- * @section Values: Functions for working with pseudo-random number generators.
27
- */
28
-
29
25
  let incCounter = random => {
30
- random.counter = Int64.incr(random.counter)
26
+ random.counter = Uint64.incr(random.counter)
31
27
  }
32
28
 
33
29
  // https://arxiv.org/pdf/2004.06278v3.pdf
34
30
  @unsafe
35
- let squares = (ctr: Int64, key: Int64) => {
31
+ let squares = (ctr: Uint64, key: Uint64) => {
32
+ use WasmI64.{ (+), (*), (|), (<<), (>>>) }
36
33
  // Implemented with @unsafe to boost efficiency
37
34
  // and have fine-grained control over overflow semantics
38
35
  let ctr = WasmI64.load(WasmI32.fromGrain(ctr), 8n)
39
36
  let key = WasmI64.load(WasmI32.fromGrain(key), 8n)
40
- let mut x = WasmI64.mul(ctr, key)
37
+ let mut x = ctr * key
41
38
  let mut y = x
42
- let mut z = WasmI64.add(y, key)
39
+ let mut z = y + key
43
40
  // round 1
44
- x = WasmI64.add(WasmI64.mul(x, x), y)
45
- x = WasmI64.or(WasmI64.shrU(x, 32N), WasmI64.shl(x, 32N))
41
+ x = x * x + y
42
+ x = x >>> 32N | x << 32N
46
43
  // round 2
47
- x = WasmI64.add(WasmI64.mul(x, x), z)
48
- x = WasmI64.or(WasmI64.shrU(x, 32N), WasmI64.shl(x, 32N))
44
+ x = x * x + z
45
+ x = x >>> 32N | x << 32N
49
46
  // round 3
50
- x = WasmI64.add(WasmI64.mul(x, x), y)
51
- x = WasmI64.or(WasmI64.shrU(x, 32N), WasmI64.shl(x, 32N))
52
- let ret = WasmI32.wrapI64(
53
- WasmI64.shrU(WasmI64.add(WasmI64.mul(x, x), z), 32N)
54
- )
55
- WasmI32.toGrain(DS.newInt32(ret)): Int32
47
+ x = x * x + y
48
+ x = x >>> 32N | x << 32N
49
+ let ret = WasmI32.wrapI64((x * x + z) >>> 32N)
50
+ WasmI32.toGrain(DS.newUint32(ret)): Uint32
56
51
  }
57
52
 
58
53
  /**
@@ -63,8 +58,8 @@ let squares = (ctr: Int64, key: Int64) => {
63
58
  *
64
59
  * @since v0.5.0
65
60
  */
66
- export let make = seed => {
67
- { seed, counter: 0L, initialized: false }
61
+ provide let make = seed => {
62
+ { seed, counter: 0uL, initialized: false }
68
63
  }
69
64
 
70
65
  /**
@@ -74,11 +69,11 @@ export let make = seed => {
74
69
  *
75
70
  * @since v0.5.0
76
71
  */
77
- export let makeUnseeded = () => {
72
+ provide let makeUnseeded = () => {
78
73
  // TODO: Should we just .expect this result for UX's sake?
79
74
  Result.map(seed => {
80
- { seed, counter: 0L, initialized: false }
81
- }, WasiRandom.randomInt64())
75
+ { seed, counter: 0uL, initialized: false }
76
+ }, WasiRandom.randomUint64())
82
77
  }
83
78
 
84
79
  /**
@@ -91,8 +86,10 @@ export let makeUnseeded = () => {
91
86
  * we do another increment at the end.
92
87
  */
93
88
  let checkInitialized = (random: Random) => {
89
+ use Uint32.*
90
+
94
91
  if (!random.initialized) {
95
- while (Int32.gt(Int32.clz(squares(random.counter, random.seed)), 0l)) {
92
+ while (clz(squares(random.counter, random.seed)) > 0ul) {
96
93
  incCounter(random)
97
94
  }
98
95
  // now that it's initialized, increment it again to make it a little more random
@@ -107,9 +104,10 @@ let checkInitialized = (random: Random) => {
107
104
  * @param random: The pseudo-random number generator to use
108
105
  * @returns The randomly generated number
109
106
  *
110
- * @since v0.5.0
107
+ * @since v0.6.0
108
+ * @history v0.5.0: Originally named `nextInt32`
111
109
  */
112
- export let nextInt32 = (random: Random) => {
110
+ provide let nextUint32 = (random: Random) => {
113
111
  checkInitialized(random)
114
112
  let ret = squares(random.counter, random.seed)
115
113
  incCounter(random)
@@ -122,19 +120,21 @@ export let nextInt32 = (random: Random) => {
122
120
  * @param random: The pseudo-random number generator to use
123
121
  * @returns The randomly generated number
124
122
  *
125
- * @since v0.5.0
123
+ * @since v0.6.0
124
+ * @history v0.5.0: Originally named `nextInt64`
126
125
  */
127
- export let nextInt64 = (random: Random) => {
126
+ provide let nextUint64 = (random: Random) => {
127
+ use Uint64.{ (|), (<<) }
128
128
  checkInitialized(random)
129
- let ret1 = Int64.fromNumber(
130
- Int32.toNumber(squares(random.counter, random.seed))
129
+ let ret1 = Uint64.fromNumber(
130
+ Uint32.toNumber(squares(random.counter, random.seed))
131
131
  )
132
132
  incCounter(random)
133
- let ret2 = Int64.fromNumber(
134
- Int32.toNumber(squares(random.counter, random.seed))
133
+ let ret2 = Uint64.fromNumber(
134
+ Uint32.toNumber(squares(random.counter, random.seed))
135
135
  )
136
136
  incCounter(random)
137
- Int64.lor(Int64.shl(ret1, 32L), ret2)
137
+ ret1 << 32uL | ret2
138
138
  }
139
139
 
140
140
  /**
@@ -146,23 +146,19 @@ export let nextInt64 = (random: Random) => {
146
146
  * @param high: The upper bound of the range (exclusive)
147
147
  * @returns The randomly generated number
148
148
  *
149
- * @since v0.5.0
149
+ * @since v0.6.0
150
+ * @history v0.5.0: Originally named `nextInt32InRange`
150
151
  */
151
- export let nextInt32InRange = (random: Random, low: Int32, high: Int32) => {
152
+ provide let nextUint32InRange = (random: Random, low: Uint32, high: Uint32) => {
152
153
  // Algorithm source: https://www.pcg-random.org/posts/bounded-rands.html#bitmask-with-rejection-unbiased-apples-method
153
- let (+) = Int32.add
154
- let (-) = Int32.sub
155
- let (*) = Int32.mul
156
- let (/) = Int32.divU
157
- let (&) = Int32.land
158
- let (>) = Int32.gtU
159
- let range = high - low - 1l
160
- let mask = Int32.shrU(Int32.lnot(0l), Int32.clz(Int32.lor(range, 1l)))
161
- let mut x = nextInt32(random) & mask
162
- let mut iters = 0l
154
+ use Uint32.*
155
+ let range = high - low - 1ul
156
+ let mask = lnot(0ul) >>> clz(range | 1ul)
157
+ let mut x = nextUint32(random) & mask
158
+ let mut iters = 0ul
163
159
  while (x > range) {
164
- x = nextInt32(random) & mask
165
- iters += 1l
160
+ x = nextUint32(random) & mask
161
+ iters += 1ul
166
162
  }
167
163
  x + low
168
164
  }
@@ -176,21 +172,17 @@ export let nextInt32InRange = (random: Random, low: Int32, high: Int32) => {
176
172
  * @param high: The upper bound of the range (exclusive)
177
173
  * @returns The randomly generated number
178
174
  *
179
- * @since v0.5.0
175
+ * @since v0.6.0
176
+ * @history v0.5.0: Originally named `nextInt64InRange`
180
177
  */
181
- export let nextInt64InRange = (random: Random, low: Int64, high: Int64) => {
178
+ provide let nextUint64InRange = (random: Random, low: Uint64, high: Uint64) => {
182
179
  // Algorithm source: https://www.pcg-random.org/posts/bounded-rands.html#bitmask-with-rejection-unbiased-apples-method
183
- let (+) = Int64.add
184
- let (-) = Int64.sub
185
- let (*) = Int64.mul
186
- let (/) = Int64.divU
187
- let (&) = Int64.land
188
- let (>) = Int64.gtU
189
- let range = high - low - 1L
190
- let mask = Int64.shrU(Int64.lnot(0L), Int64.clz(Int64.lor(range, 1L)))
191
- let mut x = nextInt64(random) & mask
180
+ use Uint64.*
181
+ let range = high - low - 1uL
182
+ let mask = lnot(0uL) >>> clz(range | 1uL)
183
+ let mut x = nextUint64(random) & mask
192
184
  while (x > range) {
193
- x = nextInt64(random) & mask
185
+ x = nextUint64(random) & mask
194
186
  }
195
187
  x + low
196
188
  }
package/random.md CHANGED
@@ -10,7 +10,7 @@ No other changes yet.
10
10
  </details>
11
11
 
12
12
  ```grain
13
- import Random from "random"
13
+ from "random" include Random
14
14
  ```
15
15
 
16
16
  ## Types
@@ -25,7 +25,7 @@ type Random
25
25
 
26
26
  ## Values
27
27
 
28
- Functions for working with pseudo-random number generators.
28
+ Functions and constants included in the Random module.
29
29
 
30
30
  ### Random.**make**
31
31
 
@@ -35,7 +35,7 @@ No other changes yet.
35
35
  </details>
36
36
 
37
37
  ```grain
38
- make : Int64 -> Random
38
+ make : (seed: Uint64) => Random
39
39
  ```
40
40
 
41
41
  Creates a new pseudo-random number generator with the given seed.
@@ -44,7 +44,7 @@ Parameters:
44
44
 
45
45
  |param|type|description|
46
46
  |-----|----|-----------|
47
- |`seed`|`Int64`|The seed for the pseudo-random number generator|
47
+ |`seed`|`Uint64`|The seed for the pseudo-random number generator|
48
48
 
49
49
  Returns:
50
50
 
@@ -60,7 +60,7 @@ No other changes yet.
60
60
  </details>
61
61
 
62
62
  ```grain
63
- makeUnseeded : () -> Result<Random, Exception>
63
+ makeUnseeded : () => Result<Random, Exception>
64
64
  ```
65
65
 
66
66
  Creates a new pseudo-random number generator with a random seed.
@@ -71,15 +71,22 @@ Returns:
71
71
  |----|-----------|
72
72
  |`Result<Random, Exception>`|`Ok(generator)` of a pseudo-random number generator if successful or `Err(exception)` otherwise|
73
73
 
74
- ### Random.**nextInt32**
75
-
76
- <details disabled>
77
- <summary tabindex="-1">Added in <code>0.5.0</code></summary>
78
- No other changes yet.
74
+ ### Random.**nextUint32**
75
+
76
+ <details>
77
+ <summary>Added in <code>0.6.0</code></summary>
78
+ <table>
79
+ <thead>
80
+ <tr><th>version</th><th>changes</th></tr>
81
+ </thead>
82
+ <tbody>
83
+ <tr><td><code>0.5.0</code></td><td>Originally named `nextInt32`</td></tr>
84
+ </tbody>
85
+ </table>
79
86
  </details>
80
87
 
81
88
  ```grain
82
- nextInt32 : Random -> Int32
89
+ nextUint32 : (random: Random) => Uint32
83
90
  ```
84
91
 
85
92
  Generates a random 32-bit integer from the given pseudo-random number generator.
@@ -94,17 +101,24 @@ Returns:
94
101
 
95
102
  |type|description|
96
103
  |----|-----------|
97
- |`Int32`|The randomly generated number|
98
-
99
- ### Random.**nextInt64**
100
-
101
- <details disabled>
102
- <summary tabindex="-1">Added in <code>0.5.0</code></summary>
103
- No other changes yet.
104
+ |`Uint32`|The randomly generated number|
105
+
106
+ ### Random.**nextUint64**
107
+
108
+ <details>
109
+ <summary>Added in <code>0.6.0</code></summary>
110
+ <table>
111
+ <thead>
112
+ <tr><th>version</th><th>changes</th></tr>
113
+ </thead>
114
+ <tbody>
115
+ <tr><td><code>0.5.0</code></td><td>Originally named `nextInt64`</td></tr>
116
+ </tbody>
117
+ </table>
104
118
  </details>
105
119
 
106
120
  ```grain
107
- nextInt64 : Random -> Int64
121
+ nextUint64 : (random: Random) => Uint64
108
122
  ```
109
123
 
110
124
  Generates a random 64-bit integer from the given pseudo-random number generator.
@@ -119,17 +133,24 @@ Returns:
119
133
 
120
134
  |type|description|
121
135
  |----|-----------|
122
- |`Int64`|The randomly generated number|
123
-
124
- ### Random.**nextInt32InRange**
125
-
126
- <details disabled>
127
- <summary tabindex="-1">Added in <code>0.5.0</code></summary>
128
- No other changes yet.
136
+ |`Uint64`|The randomly generated number|
137
+
138
+ ### Random.**nextUint32InRange**
139
+
140
+ <details>
141
+ <summary>Added in <code>0.6.0</code></summary>
142
+ <table>
143
+ <thead>
144
+ <tr><th>version</th><th>changes</th></tr>
145
+ </thead>
146
+ <tbody>
147
+ <tr><td><code>0.5.0</code></td><td>Originally named `nextInt32InRange`</td></tr>
148
+ </tbody>
149
+ </table>
129
150
  </details>
130
151
 
131
152
  ```grain
132
- nextInt32InRange : (Random, Int32, Int32) -> Int32
153
+ nextUint32InRange : (random: Random, low: Uint32, high: Uint32) => Uint32
133
154
  ```
134
155
 
135
156
  Generates a random 32-bit integer from the given pseudo-random number generator
@@ -140,24 +161,31 @@ Parameters:
140
161
  |param|type|description|
141
162
  |-----|----|-----------|
142
163
  |`random`|`Random`|The pseudo-random number generator to use|
143
- |`low`|`Int32`|The lower bound of the range (inclusive)|
144
- |`high`|`Int32`|The upper bound of the range (exclusive)|
164
+ |`low`|`Uint32`|The lower bound of the range (inclusive)|
165
+ |`high`|`Uint32`|The upper bound of the range (exclusive)|
145
166
 
146
167
  Returns:
147
168
 
148
169
  |type|description|
149
170
  |----|-----------|
150
- |`Int32`|The randomly generated number|
151
-
152
- ### Random.**nextInt64InRange**
153
-
154
- <details disabled>
155
- <summary tabindex="-1">Added in <code>0.5.0</code></summary>
156
- No other changes yet.
171
+ |`Uint32`|The randomly generated number|
172
+
173
+ ### Random.**nextUint64InRange**
174
+
175
+ <details>
176
+ <summary>Added in <code>0.6.0</code></summary>
177
+ <table>
178
+ <thead>
179
+ <tr><th>version</th><th>changes</th></tr>
180
+ </thead>
181
+ <tbody>
182
+ <tr><td><code>0.5.0</code></td><td>Originally named `nextInt64InRange`</td></tr>
183
+ </tbody>
184
+ </table>
157
185
  </details>
158
186
 
159
187
  ```grain
160
- nextInt64InRange : (Random, Int64, Int64) -> Int64
188
+ nextUint64InRange : (random: Random, low: Uint64, high: Uint64) => Uint64
161
189
  ```
162
190
 
163
191
  Generates a random 64-bit integer from the given pseudo-random number generator
@@ -168,12 +196,12 @@ Parameters:
168
196
  |param|type|description|
169
197
  |-----|----|-----------|
170
198
  |`random`|`Random`|The pseudo-random number generator to use|
171
- |`low`|`Int64`|The lower bound of the range (inclusive)|
172
- |`high`|`Int64`|The upper bound of the range (exclusive)|
199
+ |`low`|`Uint64`|The lower bound of the range (inclusive)|
200
+ |`high`|`Uint64`|The upper bound of the range (exclusive)|
173
201
 
174
202
  Returns:
175
203
 
176
204
  |type|description|
177
205
  |----|-----------|
178
- |`Int64`|The randomly generated number|
206
+ |`Uint64`|The randomly generated number|
179
207
 
package/range.gr CHANGED
@@ -1,24 +1,17 @@
1
1
  /**
2
- * @module Range: Utilities for working with ranges. A range represents an interval—a set of values with a beginning and an end.
3
- * @example import Range from "range"
2
+ * Utilities for working with ranges.
3
+ *
4
+ * A range represents an interval—a set of values with a beginning and an end.
5
+ *
6
+ * All functions in this module treat ranges as exclusive, but inclusive versions
7
+ * of all APIs are available in the `Inclusive` submodule.
8
+ *
9
+ * @example from "range" include Range
10
+ *
4
11
  * @since v0.3.0
12
+ * @history v0.6.0: Treats all ranges as exclusive
5
13
  */
6
-
7
- /**
8
- * @section Types: Type declarations included in the Range module.
9
- */
10
-
11
- /**
12
- * Ranges can be inclusive or exclusive. When `Inclusive`, the end value will be included in operations. When `Exclusive`, the end value will be excluded from operations.
13
- */
14
- export enum Range {
15
- Inclusive(Number, Number),
16
- Exclusive(Number, Number),
17
- }
18
-
19
- /**
20
- * @section Values: Functions and constants included in the Range module.
21
- */
14
+ module Range
22
15
 
23
16
  /**
24
17
  * Checks if the given number is within the range.
@@ -27,55 +20,47 @@ export enum Range {
27
20
  * @param range: The range to check within
28
21
  * @returns Whether or not the value is within range
29
22
  *
30
- * @example Range.inRange(1, Range.Inclusive(0, 2)) == true
31
- * @example Range.inRange(10, Range.Inclusive(0, 2)) == false
23
+ * @example Range.inRange(1, { rangeStart: 0, rangeEnd: 2 }) == true
24
+ * @example Range.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false
32
25
  *
33
26
  * @since v0.3.0
27
+ * @history v0.6.0: Treats all ranges as exclusive
34
28
  */
35
- export let inRange = (value, range) => {
29
+ provide let inRange = (value, range) => {
36
30
  match (range) {
37
- Inclusive(lower, upper) when value >= lower && value <= upper => true,
38
- Inclusive(upper, lower) when value >= lower && value <= upper => true,
39
- Exclusive(lower, upper) when value >= lower && value < upper => true,
40
- Exclusive(upper, lower) when value >= lower && value < upper => true,
31
+ { rangeStart: lower, rangeEnd: upper } when value >= lower && value < upper =>
32
+ true,
33
+ { rangeStart: upper, rangeEnd: lower } when value >= lower && value < upper =>
34
+ true,
41
35
  _ => false,
42
36
  }
43
37
  }
44
38
 
45
39
  /**
46
- * Calls the given function with each number in the range. For increasing ranges, the value is increased by `1` in each iteration, and for decreasing ranges, the value is decreased by `1`. The value is always changed by `1`, even if non-integer values were provided in the range.
40
+ * Calls the given function with each number in the range.
41
+ *
42
+ * For increasing ranges, the value is increased by `1` in each iteration,
43
+ * and for decreasing ranges, the value is decreased by `1`. The value is
44
+ * always changed by `1`, even if non-integer values were provided in the range.
47
45
  *
48
46
  * @param fn: The function to be executed on each number in the range
49
47
  * @param range: The range to iterate
50
48
  *
51
- * @example Range.forEach(val => print(val), Range.Exclusive(0, 2))
49
+ * @example Range.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 })
52
50
  *
53
51
  * @since v0.3.0
52
+ * @history v0.6.0: Treats all ranges as exclusive
54
53
  */
55
- export let forEach = (fn: Number -> Void, range) => {
54
+ provide let forEach = (fn: Number => Void, range) => {
56
55
  match (range) {
57
- Inclusive(lower, upper) when lower <= upper => {
58
- let mut idx = lower
59
- while (idx <= upper) {
60
- fn(idx)
61
- idx += 1
62
- }
63
- },
64
- Inclusive(upper, lower) => {
65
- let mut idx = upper
66
- while (idx >= lower) {
67
- fn(idx)
68
- idx -= 1
69
- }
70
- },
71
- Exclusive(lower, upper) when lower <= upper => {
56
+ { rangeStart: lower, rangeEnd: upper } when lower <= upper => {
72
57
  let mut idx = lower
73
58
  while (idx < upper) {
74
59
  fn(idx)
75
60
  idx += 1
76
61
  }
77
62
  },
78
- Exclusive(upper, lower) => {
63
+ { rangeStart: upper, rangeEnd: lower } => {
79
64
  let mut idx = upper
80
65
  while (idx > lower) {
81
66
  fn(idx)
@@ -86,41 +71,32 @@ export let forEach = (fn: Number -> Void, range) => {
86
71
  }
87
72
 
88
73
  /**
89
- * Produces a list by calling the given function on each number included in the range. For increasing ranges, the value is increased by `1` in each iteration, and for decreasing ranges, the value is decreased by `1`. The value is always changed by `1`, even if non-integer values were provided in the range.
74
+ * Produces a list by calling the given function on each number included in the range.
75
+ *
76
+ * For increasing ranges, the value is increased by `1` in each iteration,
77
+ * and for decreasing ranges, the value is decreased by `1`. The value is
78
+ * always changed by `1`, even if non-integer values were provided in the range.
90
79
  *
91
80
  * @param fn: The function called on each number in the range that returns the value for the output list
92
81
  * @param range: The range to iterate
93
82
  * @returns A list containing all values returned from the `fn`
94
83
  *
95
- * @example Range.map(val => val * 2, Range.Inclusive(0, 2)) == [0, 2, 4]
84
+ * @example Range.map(val => val * 2, { rangeStart: 0, rangeEnd: 3 }) == [0, 2, 4]
96
85
  *
97
86
  * @since v0.3.2
87
+ * @history v0.6.0: Treats all ranges as exclusive
98
88
  */
99
- export let map = (fn, range) => {
89
+ provide let map = (fn, range) => {
100
90
  let mut result = []
101
91
  match (range) {
102
- Inclusive(lower, upper) when lower <= upper => {
103
- let mut idx = upper
104
- while (idx >= lower) {
105
- result = [fn(idx), ...result]
106
- idx -= 1
107
- }
108
- },
109
- Inclusive(upper, lower) => {
110
- let mut idx = lower
111
- while (idx <= upper) {
112
- result = [fn(idx), ...result]
113
- idx += 1
114
- }
115
- },
116
- Exclusive(lower, upper) when lower <= upper => {
92
+ { rangeStart: lower, rangeEnd: upper } when lower <= upper => {
117
93
  let mut idx = upper - 1
118
94
  while (idx >= lower) {
119
95
  result = [fn(idx), ...result]
120
96
  idx -= 1
121
97
  }
122
98
  },
123
- Exclusive(upper, lower) => {
99
+ { rangeStart: upper, rangeEnd: lower } => {
124
100
  let mut idx = lower + 1
125
101
  while (idx <= upper) {
126
102
  result = [fn(idx), ...result]
@@ -130,3 +106,99 @@ export let map = (fn, range) => {
130
106
  }
131
107
  result
132
108
  }
109
+
110
+ provide module Inclusive {
111
+ /**
112
+ * Checks if the given number is within the range.
113
+ *
114
+ * @param value: The number being checked
115
+ * @param range: The range to check within
116
+ * @returns Whether or not the value is within range
117
+ *
118
+ * @example Range.Inclusive.inRange(1, { rangeStart: 0, rangeEnd: 1 }) == true
119
+ * @example Range.Inclusive.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false
120
+ *
121
+ * @since v0.6.0
122
+ * @history v0.3.0: Root APIs originally handled Inclusive & Exclusive variants
123
+ */
124
+ provide let inRange = (value, range) => {
125
+ match (range) {
126
+ { rangeStart: lower, rangeEnd: upper } when value >= lower &&
127
+ value <= upper => true,
128
+ { rangeStart: upper, rangeEnd: lower } when value >= lower &&
129
+ value <= upper => true,
130
+ _ => false,
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Calls the given function with each number in the range.
136
+ *
137
+ * For increasing ranges, the value is increased by `1` in each iteration,
138
+ * and for decreasing ranges, the value is decreased by `1`. The value is
139
+ * always changed by `1`, even if non-integer values were provided in the range.
140
+ *
141
+ * @param fn: The function to be executed on each number in the range
142
+ * @param range: The range to iterate
143
+ *
144
+ * @example Range.Inclusive.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 })
145
+ *
146
+ * @since v0.3.0
147
+ * @history v0.3.0: Root APIs originally handled Inclusive & Exclusive variants
148
+ */
149
+ provide let forEach = (fn: Number => Void, range) => {
150
+ match (range) {
151
+ { rangeStart: lower, rangeEnd: upper } when lower <= upper => {
152
+ let mut idx = lower
153
+ while (idx <= upper) {
154
+ fn(idx)
155
+ idx += 1
156
+ }
157
+ },
158
+ { rangeStart: upper, rangeEnd: lower } => {
159
+ let mut idx = upper
160
+ while (idx >= lower) {
161
+ fn(idx)
162
+ idx -= 1
163
+ }
164
+ },
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Produces a list by calling the given function on each number included in the range.
170
+ *
171
+ * For increasing ranges, the value is increased by `1` in each iteration,
172
+ * and for decreasing ranges, the value is decreased by `1`. The value is
173
+ * always changed by `1`, even if non-integer values were provided in the range.
174
+ *
175
+ * @param fn: The function called on each number in the range that returns the value for the output list
176
+ * @param range: The range to iterate
177
+ * @returns A list containing all values returned from the `fn`
178
+ *
179
+ * @example Range.Inclusive.map(val => val * 2, { rangeStart: 0, rangeEnd: 2 }) == [0, 2, 4]
180
+ *
181
+ * @since v0.3.2
182
+ * @history v0.3.0: Root APIs originally handled Inclusive & Exclusive variants
183
+ */
184
+ provide let map = (fn, range) => {
185
+ let mut result = []
186
+ match (range) {
187
+ { rangeStart: lower, rangeEnd: upper } when lower <= upper => {
188
+ let mut idx = upper
189
+ while (idx >= lower) {
190
+ result = [fn(idx), ...result]
191
+ idx -= 1
192
+ }
193
+ },
194
+ { rangeStart: upper, rangeEnd: lower } => {
195
+ let mut idx = lower
196
+ while (idx <= upper) {
197
+ result = [fn(idx), ...result]
198
+ idx += 1
199
+ }
200
+ },
201
+ }
202
+ result
203
+ }
204
+ }