@grain/stdlib 0.6.6 → 0.7.0

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 (137) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/LICENSE +1 -1
  3. package/README.md +2 -2
  4. package/array.gr +55 -7
  5. package/array.md +123 -77
  6. package/bigint.md +30 -30
  7. package/buffer.gr +20 -53
  8. package/buffer.md +47 -47
  9. package/bytes.gr +111 -35
  10. package/bytes.md +111 -32
  11. package/char.gr +201 -99
  12. package/char.md +361 -34
  13. package/exception.gr +11 -11
  14. package/exception.md +26 -1
  15. package/float32.gr +327 -3
  16. package/float32.md +606 -19
  17. package/float64.gr +320 -3
  18. package/float64.md +606 -19
  19. package/fs.gr +1082 -0
  20. package/fs.md +630 -0
  21. package/hash.gr +142 -88
  22. package/hash.md +102 -14
  23. package/int16.md +23 -23
  24. package/int32.gr +25 -4
  25. package/int32.md +65 -30
  26. package/int64.gr +26 -1
  27. package/int64.md +65 -30
  28. package/int8.md +23 -23
  29. package/json.gr +366 -51
  30. package/json.md +418 -2
  31. package/list.gr +328 -31
  32. package/list.md +492 -69
  33. package/map.gr +20 -12
  34. package/map.md +44 -38
  35. package/marshal.gr +41 -40
  36. package/marshal.md +2 -2
  37. package/number.gr +159 -30
  38. package/number.md +215 -38
  39. package/option.md +21 -21
  40. package/package.json +5 -3
  41. package/path.gr +48 -0
  42. package/path.md +103 -12
  43. package/pervasives.gr +2 -2
  44. package/pervasives.md +37 -37
  45. package/priorityqueue.gr +7 -7
  46. package/priorityqueue.md +19 -19
  47. package/queue.gr +183 -29
  48. package/queue.md +296 -40
  49. package/random.md +6 -6
  50. package/range.gr +4 -4
  51. package/range.md +6 -6
  52. package/rational.md +16 -16
  53. package/regex.gr +52 -51
  54. package/regex.md +11 -11
  55. package/result.md +16 -16
  56. package/runtime/atof/common.md +39 -39
  57. package/runtime/atof/decimal.gr +6 -6
  58. package/runtime/atof/decimal.md +8 -8
  59. package/runtime/atof/lemire.gr +5 -5
  60. package/runtime/atof/lemire.md +1 -1
  61. package/runtime/atof/parse.gr +16 -16
  62. package/runtime/atof/parse.md +2 -2
  63. package/runtime/atof/slow.md +1 -1
  64. package/runtime/atof/table.md +2 -2
  65. package/runtime/atoi/parse.gr +3 -3
  66. package/runtime/atoi/parse.md +1 -1
  67. package/runtime/bigint.gr +15 -47
  68. package/runtime/bigint.md +54 -60
  69. package/runtime/compare.gr +2 -2
  70. package/runtime/compare.md +1 -1
  71. package/runtime/dataStructures.md +33 -33
  72. package/runtime/debugPrint.gr +4 -1
  73. package/runtime/debugPrint.md +9 -9
  74. package/runtime/equal.gr +99 -77
  75. package/runtime/equal.md +1 -1
  76. package/runtime/exception.gr +62 -82
  77. package/runtime/exception.md +62 -11
  78. package/runtime/gc.gr +39 -45
  79. package/runtime/gc.md +4 -4
  80. package/runtime/malloc.gr +7 -7
  81. package/runtime/malloc.md +4 -4
  82. package/runtime/math/kernel/cos.gr +70 -0
  83. package/runtime/math/kernel/cos.md +14 -0
  84. package/runtime/math/kernel/sin.gr +65 -0
  85. package/runtime/math/kernel/sin.md +14 -0
  86. package/runtime/math/kernel/tan.gr +136 -0
  87. package/runtime/math/kernel/tan.md +14 -0
  88. package/runtime/math/rempio2.gr +244 -0
  89. package/runtime/math/rempio2.md +14 -0
  90. package/runtime/math/trig.gr +130 -0
  91. package/runtime/math/trig.md +28 -0
  92. package/runtime/math/umuldi.gr +26 -0
  93. package/runtime/math/umuldi.md +14 -0
  94. package/runtime/numberUtils.gr +29 -29
  95. package/runtime/numberUtils.md +12 -12
  96. package/runtime/numbers.gr +373 -381
  97. package/runtime/numbers.md +79 -73
  98. package/runtime/string.gr +37 -105
  99. package/runtime/string.md +3 -9
  100. package/runtime/unsafe/constants.md +24 -24
  101. package/runtime/unsafe/conv.md +13 -13
  102. package/runtime/unsafe/memory.gr +24 -20
  103. package/runtime/unsafe/memory.md +27 -7
  104. package/runtime/unsafe/offsets.gr +36 -0
  105. package/runtime/unsafe/offsets.md +88 -0
  106. package/runtime/unsafe/panic.gr +28 -0
  107. package/runtime/unsafe/panic.md +14 -0
  108. package/runtime/unsafe/tags.md +32 -32
  109. package/runtime/unsafe/wasmf32.md +28 -28
  110. package/runtime/unsafe/wasmf64.md +28 -28
  111. package/runtime/unsafe/wasmi32.md +47 -47
  112. package/runtime/unsafe/wasmi64.md +50 -50
  113. package/runtime/utf8.gr +189 -0
  114. package/runtime/utf8.md +117 -0
  115. package/runtime/wasi.gr +4 -2
  116. package/runtime/wasi.md +138 -138
  117. package/set.gr +18 -11
  118. package/set.md +42 -36
  119. package/stack.gr +171 -2
  120. package/stack.md +297 -15
  121. package/string.gr +352 -557
  122. package/string.md +77 -34
  123. package/uint16.md +22 -22
  124. package/uint32.gr +25 -4
  125. package/uint32.md +63 -28
  126. package/uint64.gr +25 -5
  127. package/uint64.md +63 -28
  128. package/uint8.md +22 -22
  129. package/uri.gr +57 -53
  130. package/uri.md +11 -12
  131. package/wasi/file.gr +67 -59
  132. package/wasi/file.md +39 -39
  133. package/wasi/process.md +5 -5
  134. package/wasi/random.md +3 -3
  135. package/wasi/time.md +4 -4
  136. package/runtime/utils/printing.gr +0 -60
  137. package/runtime/utils/printing.md +0 -26
package/hash.gr CHANGED
@@ -3,8 +3,12 @@
3
3
  *
4
4
  * @example from "hash" include Hash
5
5
  *
6
- * @example Hash.hash(1)
7
- * @example Hash.hash("Hello World")
6
+ * @example
7
+ * let hashInstance = Hash.make()
8
+ * assert Hash.hash(hashInstance, "Hello World") == Hash.hash(hashInstance, "Hello World")
9
+ * @example
10
+ * let hashInstance = Hash.makeSeeded(10)
11
+ * assert Hash.hash(hashInstance, "Hello World") == Hash.hash(hashInstance, "Hello World")
8
12
  *
9
13
  * @since v0.1.0
10
14
  */
@@ -34,7 +38,7 @@ from "runtime/unsafe/wasmi64" include WasmI64
34
38
  from "runtime/unsafe/tags" include Tags
35
39
 
36
40
  from "runtime/dataStructures" include DataStructures
37
- use DataStructures.{ tagSimpleNumber }
41
+ use DataStructures.{ tagSimpleNumber, untagSimpleNumber }
38
42
  from "runtime/numbers" include Numbers
39
43
  use Numbers.{ coerceNumberToWasmI32 }
40
44
  from "runtime/bigint" include Bigint as BI
@@ -42,18 +46,6 @@ from "runtime/bigint" include Bigint as BI
42
46
  from "wasi/random" include Random
43
47
  from "result" include Result
44
48
 
45
- @unsafe
46
- let mut seed = 0n
47
-
48
- @unsafe
49
- let initalize = () => {
50
- // Delay initialization to the first call to `hash` to prevent WASI calls
51
- // during startup
52
- let random = Random.random()
53
- seed = coerceNumberToWasmI32(Result.unwrap(random))
54
- seed
55
- }
56
-
57
49
  @unsafe
58
50
  let _MAX_HASH_DEPTH = 31n
59
51
 
@@ -71,58 +63,56 @@ let m = 5n
71
63
  let n = 0xe6546b64n
72
64
 
73
65
  @unsafe
74
- let mut h = seed
75
-
76
- @unsafe
77
- let hash32 = k => {
66
+ let hash32 = (h, k) => {
78
67
  let mut k = k * c1
79
68
  k = WasmI32.rotl(k, r1)
80
69
  k *= c2
81
70
 
82
- h = h ^ k
83
- h = WasmI32.rotl(h, r2)
84
- h = h * m + n
71
+ let h = h ^ k
72
+ let h = WasmI32.rotl(h, r2)
73
+ h * m + n
85
74
  }
86
75
 
87
76
  @unsafe
88
- let hash64 = k => {
77
+ let hash64 = (h, k) => {
89
78
  use WasmI64.{ (>>>) }
90
79
  // convenience function for hashing 64-bit values
91
- hash32(WasmI32.wrapI64(k))
92
- hash32(WasmI32.wrapI64(k >>> 32N))
80
+ let h = hash32(h, WasmI32.wrapI64(k))
81
+ let h = hash32(h, WasmI32.wrapI64(k >>> 32N))
82
+ h
93
83
  }
94
84
 
95
85
  @unsafe
96
- let hashRemaining = r => {
86
+ let hashRemaining = (h, r) => {
97
87
  // Note: wasm is little-endian so no swap is necessary
98
88
 
99
89
  let mut r = r * c1
100
90
  r = WasmI32.rotl(r, r1)
101
91
  r *= c2
102
92
 
103
- h = h ^ r
93
+ h ^ r
104
94
  }
105
95
 
106
96
  @unsafe
107
- let finalize = len => {
108
- h = h ^ len
97
+ let finalize = (h, len) => {
98
+ let h = h ^ len
109
99
 
110
- h = h ^ h >>> 16n
111
- h *= 0x85ebca6bn
112
- h = h ^ h >>> 13n
113
- h *= 0xc2b2ae35n
114
- h = h ^ h >>> 16n
100
+ let h = h ^ h >>> 16n
101
+ let h = h * 0x85ebca6bn
102
+ let h = h ^ h >>> 13n
103
+ let h = h * 0xc2b2ae35n
104
+ h ^ h >>> 16n
115
105
  }
116
106
 
117
107
  @unsafe
118
- let rec hashOne = (val, depth) => {
108
+ let rec hashOne = (h, val, depth) => {
119
109
  if (depth > _MAX_HASH_DEPTH) {
120
- void
110
+ h
121
111
  } else if ((val & Tags._GRAIN_NUMBER_TAG_MASK) != 0n) {
122
- hash32(val)
112
+ hash32(h, val)
123
113
  } else if (
124
- (val & Tags._GRAIN_GENERIC_TAG_MASK) ==
125
- Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
114
+ (val & Tags._GRAIN_GENERIC_TAG_MASK)
115
+ == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
126
116
  ) {
127
117
  let heapPtr = val
128
118
  match (WasmI32.load(heapPtr, 0n)) {
@@ -130,141 +120,205 @@ let rec hashOne = (val, depth) => {
130
120
  let length = WasmI32.load(heapPtr, 4n)
131
121
  let extra = length % 4n
132
122
  let l = length - extra
123
+ let mut h = h
133
124
  for (let mut i = 0n; i < l; i += 4n) {
134
- hash32(WasmI32.load(heapPtr + i, 8n))
125
+ h = hash32(h, WasmI32.load(heapPtr + i, 8n))
135
126
  }
136
127
  let mut rem = 0n
137
128
  for (let mut i = 0n; i < extra; i += 1n) {
138
129
  rem = rem << 8n
139
130
  rem = rem | WasmI32.load8U(heapPtr + l + i, 8n)
140
131
  }
141
- if (rem != 0n) hashRemaining(rem)
142
- finalize(length)
132
+ if (rem != 0n) h = hashRemaining(h, rem)
133
+ finalize(h, length)
143
134
  },
144
135
  t when t == Tags._GRAIN_ADT_HEAP_TAG => {
145
136
  // moduleId
146
- hash32(WasmI32.load(heapPtr, 4n))
137
+ let h = hash32(h, WasmI32.load(heapPtr, 4n))
147
138
  // typeId
148
- hash32(WasmI32.load(heapPtr, 8n))
139
+ let h = hash32(h, WasmI32.load(heapPtr, 8n))
149
140
  // variantId
150
- hash32(WasmI32.load(heapPtr, 12n))
141
+ let h = hash32(h, WasmI32.load(heapPtr, 12n))
151
142
 
152
143
  let arity = WasmI32.load(heapPtr, 16n)
153
144
 
154
145
  let a = arity * 4n
146
+ let mut h = h
155
147
  for (let mut i = 0n; i < a; i += 4n) {
156
- hashOne(WasmI32.load(heapPtr + i, 20n), depth + 1n)
148
+ h = hashOne(h, WasmI32.load(heapPtr + i, 20n), depth + 1n)
157
149
  }
158
150
 
159
- finalize(arity)
151
+ finalize(h, arity)
160
152
  },
161
153
  t when t == Tags._GRAIN_RECORD_HEAP_TAG => {
162
154
  // moduleId
163
- hash32(WasmI32.load(heapPtr, 4n))
155
+ let h = hash32(h, WasmI32.load(heapPtr, 4n))
164
156
  // typeId
165
- hash32(WasmI32.load(heapPtr, 8n))
157
+ let h = hash32(h, WasmI32.load(heapPtr, 8n))
166
158
 
167
159
  let arity = WasmI32.load(heapPtr, 12n)
168
160
 
169
161
  let a = arity * 4n
162
+ let mut h = h
170
163
  for (let mut i = 0n; i < a; i += 4n) {
171
- hashOne(WasmI32.load(heapPtr + i, 16n), depth + 1n)
164
+ h = hashOne(h, WasmI32.load(heapPtr + i, 16n), depth + 1n)
172
165
  }
173
- finalize(arity)
166
+ finalize(h, arity)
174
167
  },
175
168
  t when t == Tags._GRAIN_ARRAY_HEAP_TAG => {
176
169
  let arity = WasmI32.load(heapPtr, 4n)
177
170
 
178
171
  let a = arity * 4n
172
+ let mut h = h
179
173
  for (let mut i = 0n; i < a; i += 4n) {
180
- hashOne(WasmI32.load(heapPtr + i, 8n), depth + 1n)
174
+ h = hashOne(h, WasmI32.load(heapPtr + i, 8n), depth + 1n)
181
175
  }
182
- finalize(arity)
176
+ finalize(h, arity)
183
177
  },
184
178
  t when t == Tags._GRAIN_TUPLE_HEAP_TAG => {
185
179
  let tupleLength = WasmI32.load(heapPtr, 4n)
186
180
  let l = tupleLength * 4n
181
+ let mut h = h
187
182
  for (let mut i = 0n; i < l; i += 4n) {
188
- hashOne(WasmI32.load(heapPtr + i, 8n), depth + 1n)
183
+ h = hashOne(h, WasmI32.load(heapPtr + i, 8n), depth + 1n)
189
184
  }
190
- finalize(tupleLength)
185
+ finalize(h, tupleLength)
191
186
  },
192
187
  t when t == Tags._GRAIN_LAMBDA_HEAP_TAG => {
193
- hash32(heapPtr)
188
+ hash32(h, heapPtr)
194
189
  },
195
190
  t when t == Tags._GRAIN_BOXED_NUM_HEAP_TAG => {
196
191
  let tag = WasmI32.load(heapPtr, 4n)
197
192
  match (tag) {
198
193
  t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => {
199
- hash32(WasmI32.load(heapPtr, 8n))
200
- hash32(WasmI32.load(heapPtr, 12n))
194
+ let h = hash32(h, WasmI32.load(heapPtr, 8n))
195
+ hash32(h, WasmI32.load(heapPtr, 12n))
201
196
  },
202
197
  t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => {
203
198
  // TODO(#1187): should include fixint size once implemented
204
199
  let size = BI.getSize(heapPtr)
205
- hash32(size)
206
- hash32(BI.getFlags(heapPtr))
200
+ let h = hash32(h, size)
201
+ let mut h = hash32(h, BI.getFlags(heapPtr))
207
202
  for (let mut i = 0n; i < size; i += 1n) {
208
- hash64(BI.getLimb(heapPtr, i))
203
+ h = hash64(h, BI.getLimb(heapPtr, i))
209
204
  }
205
+ h
210
206
  },
211
207
  t when t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => {
212
- hash32(WasmI32.load(heapPtr, 8n))
213
- hash32(WasmI32.load(heapPtr, 12n))
208
+ let h = hash32(h, WasmI32.load(heapPtr, 8n))
209
+ let h = hash32(h, WasmI32.load(heapPtr, 12n))
210
+ h
214
211
  },
215
212
  t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => {
216
- hashOne(WasmI32.load(heapPtr, 8n), depth + 1n)
217
- hashOne(WasmI32.load(heapPtr, 12n), depth + 1n)
213
+ let h = hashOne(h, WasmI32.load(heapPtr, 8n), depth + 1n)
214
+ let h = hashOne(h, WasmI32.load(heapPtr, 12n), depth + 1n)
215
+ h
218
216
  },
219
217
  _ => {
220
- hash32(heapPtr)
218
+ hash32(h, heapPtr)
221
219
  },
222
220
  }
223
221
  },
224
- t when t == Tags._GRAIN_INT32_HEAP_TAG ||
225
- t == Tags._GRAIN_FLOAT32_HEAP_TAG ||
226
- t == Tags._GRAIN_UINT32_HEAP_TAG => {
227
- hash32(WasmI32.load(heapPtr, 4n))
222
+ t when t == Tags._GRAIN_INT32_HEAP_TAG
223
+ || t == Tags._GRAIN_FLOAT32_HEAP_TAG
224
+ || t == Tags._GRAIN_UINT32_HEAP_TAG => {
225
+ hash32(h, WasmI32.load(heapPtr, 4n))
228
226
  },
229
227
  t when t == Tags._GRAIN_UINT64_HEAP_TAG => {
230
- hash32(WasmI32.load(heapPtr, 8n))
231
- hash32(WasmI32.load(heapPtr, 12n))
228
+ let h = hash32(h, WasmI32.load(heapPtr, 8n))
229
+ let h = hash32(h, WasmI32.load(heapPtr, 12n))
230
+ h
232
231
  },
233
232
  _ => {
234
- hash32(heapPtr)
233
+ hash32(h, heapPtr)
235
234
  },
236
235
  }
237
236
  } else {
238
237
  // Handle non-heap values: booleans, chars, void, etc.
239
- hash32(val)
238
+ hash32(h, val)
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Represents a particular hashing instance.
244
+ *
245
+ * @since v0.7.0
246
+ */
247
+ abstract type HashInstance = Number
248
+
249
+ let mut seed: HashInstance = 0
250
+ @unsafe
251
+ let getSeed = () => {
252
+ if (WasmI32.eqz(untagSimpleNumber(seed))) {
253
+ // Delay initialization to the first call to `hash` to prevent WASI calls
254
+ // during startup
255
+ let random = Random.random()
256
+ seed = Result.unwrap(random)
240
257
  }
258
+ seed: HashInstance
241
259
  }
242
260
 
243
261
  /**
244
- * A generic hash function that produces an integer from any value. If `a == b` then `Hash.hash(a) == Hash.hash(b)`.
262
+ * Produces a generic hash instance using a random seed value.
263
+ *
264
+ * @returns A hashing instance that can be consumed during hashing
265
+ *
266
+ * @throws Failure(String): If WASI random_get fails
267
+ *
268
+ * @example
269
+ * let hashInstance = Hash.make()
270
+ * assert Hash.hash(hashInstance," Hello World") == Hash.hash(hashInstance, "Hello World)
245
271
  *
272
+ * @since v0.7.0
273
+ */
274
+ provide let make = () => {
275
+ let seed = getSeed()
276
+ seed
277
+ }
278
+
279
+ /**
280
+ * Produces a hashInstance using the given seed.
281
+ *
282
+ * @param seed: The seed to use while hashing
283
+ * @returns A hashing instance that can be consumed during hashing
284
+ *
285
+ * @example
286
+ * let hashInstance = Hash.makeSeeded(1)
287
+ * assert Hash.hash(hashInstance," Hello World") == Hash.hash(hashInstance, "Hello World)
288
+ * @example
289
+ * let hashInstance1 = Hash.makeSeeded(1)
290
+ * let hashInstance2 = Hash.makeSeeded(2)
291
+ * assert Hash.hash(hashInstance1," Hello World") != Hash.hash(hashInstance2, "Hello World)
292
+ *
293
+ * @since v0.7.0
294
+ */
295
+ @unsafe
296
+ provide let makeSeeded = (seed: Number) => {
297
+ return seed: HashInstance
298
+ }
299
+
300
+ /**
301
+ * A generic hash function that produces an integer from any value given a hashing instance. If `a == b` then `Hash.hash(h, a) == Hash.hash(h, b)`.
302
+ *
303
+ * @param hashInstance: The hashing instance to use as a seed
246
304
  * @param anything: The value to hash
305
+ *
247
306
  * @returns A hash for the given value
248
- *
249
- * @throws Failure(String): If WASI random_get fails
250
307
  *
251
- * @example assert Hash.hash(1) == Hash.hash(1)
252
- * @example assert Hash.hash("Hello World") == Hash.hash("Hello World")
308
+ * @example
309
+ * let hashInstance = Hash.makeSeeded(1)
310
+ * assert Hash.hash(hashInstance," Hello World") == Hash.hash(hashInstance, "Hello World)
253
311
  *
254
312
  * @since v0.1.0
313
+ * @history v0.7.0: Added `hashInstance` parameter instead of using a global seed
255
314
  */
256
315
  @unsafe
257
- provide let hash = anything => {
258
- h = if (WasmI32.eqz(seed)) {
259
- initalize()
260
- } else {
261
- seed
262
- }
263
-
264
- hashOne(WasmI32.fromGrain(anything), 0n)
316
+ provide let hash = (hashInstance: HashInstance, anything) => {
317
+ let h = coerceNumberToWasmI32(hashInstance)
318
+ let h = hashOne(h, WasmI32.fromGrain(anything), 0n)
265
319
  ignore(anything)
266
320
 
267
- finalize(0n)
321
+ let h = finalize(h, 0n)
268
322
 
269
323
  // Tag the number on the way out.
270
324
  // Since Grain has proper modulus, negative numbers are okay.
package/hash.md CHANGED
@@ -14,55 +14,143 @@ from "hash" include Hash
14
14
  ```
15
15
 
16
16
  ```grain
17
- Hash.hash(1)
17
+ let hashInstance = Hash.make()
18
+ assert Hash.hash(hashInstance, "Hello World") == Hash.hash(hashInstance, "Hello World")
18
19
  ```
19
20
 
20
21
  ```grain
21
- Hash.hash("Hello World")
22
+ let hashInstance = Hash.makeSeeded(10)
23
+ assert Hash.hash(hashInstance, "Hello World") == Hash.hash(hashInstance, "Hello World")
22
24
  ```
23
25
 
26
+ ## Types
27
+
28
+ Type declarations included in the Hash module.
29
+
30
+ ### Hash.**HashInstance**
31
+
32
+ <details disabled>
33
+ <summary tabindex="-1">Added in <code>0.7.0</code></summary>
34
+ No other changes yet.
35
+ </details>
36
+
37
+ ```grain
38
+ type HashInstance
39
+ ```
40
+
41
+ Represents a particular hashing instance.
42
+
24
43
  ## Values
25
44
 
26
45
  Functions and constants included in the Hash module.
27
46
 
28
- ### Hash.**hash**
47
+ ### Hash.**make**
29
48
 
30
49
  <details disabled>
31
- <summary tabindex="-1">Added in <code>0.1.0</code></summary>
50
+ <summary tabindex="-1">Added in <code>0.7.0</code></summary>
32
51
  No other changes yet.
33
52
  </details>
34
53
 
35
54
  ```grain
36
- hash : (anything: a) => Number
55
+ make: () => HashInstance
56
+ ```
57
+
58
+ Produces a generic hash instance using a random seed value.
59
+
60
+ Returns:
61
+
62
+ |type|description|
63
+ |----|-----------|
64
+ |`HashInstance`|A hashing instance that can be consumed during hashing|
65
+
66
+ Throws:
67
+
68
+ `Failure(String)`
69
+
70
+ * If WASI random_get fails
71
+
72
+ Examples:
73
+
74
+ ```grain
75
+ let hashInstance = Hash.make()
76
+ assert Hash.hash(hashInstance," Hello World") == Hash.hash(hashInstance, "Hello World)
37
77
  ```
38
78
 
39
- A generic hash function that produces an integer from any value. If `a == b` then `Hash.hash(a) == Hash.hash(b)`.
79
+ ### Hash.**makeSeeded**
80
+
81
+ <details disabled>
82
+ <summary tabindex="-1">Added in <code>0.7.0</code></summary>
83
+ No other changes yet.
84
+ </details>
85
+
86
+ ```grain
87
+ makeSeeded: (seed: Number) => HashInstance
88
+ ```
89
+
90
+ Produces a hashInstance using the given seed.
40
91
 
41
92
  Parameters:
42
93
 
43
94
  |param|type|description|
44
95
  |-----|----|-----------|
45
- |`anything`|`a`|The value to hash|
96
+ |`seed`|`Number`|The seed to use while hashing|
46
97
 
47
98
  Returns:
48
99
 
49
100
  |type|description|
50
101
  |----|-----------|
51
- |`Number`|A hash for the given value|
102
+ |`HashInstance`|A hashing instance that can be consumed during hashing|
52
103
 
53
- Throws:
104
+ Examples:
54
105
 
55
- `Failure(String)`
106
+ ```grain
107
+ let hashInstance = Hash.makeSeeded(1)
108
+ assert Hash.hash(hashInstance," Hello World") == Hash.hash(hashInstance, "Hello World)
109
+ ```
56
110
 
57
- * If WASI random_get fails
111
+ ```grain
112
+ let hashInstance1 = Hash.makeSeeded(1)
113
+ let hashInstance2 = Hash.makeSeeded(2)
114
+ assert Hash.hash(hashInstance1," Hello World") != Hash.hash(hashInstance2, "Hello World)
115
+ ```
58
116
 
59
- Examples:
117
+ ### Hash.**hash**
118
+
119
+ <details>
120
+ <summary>Added in <code>0.1.0</code></summary>
121
+ <table>
122
+ <thead>
123
+ <tr><th>version</th><th>changes</th></tr>
124
+ </thead>
125
+ <tbody>
126
+ <tr><td><code>0.7.0</code></td><td>Added `hashInstance` parameter instead of using a global seed</td></tr>
127
+ </tbody>
128
+ </table>
129
+ </details>
60
130
 
61
131
  ```grain
62
- assert Hash.hash(1) == Hash.hash(1)
132
+ hash: (hashInstance: HashInstance, anything: a) => Number
63
133
  ```
64
134
 
135
+ A generic hash function that produces an integer from any value given a hashing instance. If `a == b` then `Hash.hash(h, a) == Hash.hash(h, b)`.
136
+
137
+ Parameters:
138
+
139
+ |param|type|description|
140
+ |-----|----|-----------|
141
+ |`hashInstance`|`HashInstance`|The hashing instance to use as a seed|
142
+ |`anything`|`a`|The value to hash|
143
+
144
+ Returns:
145
+
146
+ |type|description|
147
+ |----|-----------|
148
+ |`Number`|A hash for the given value|
149
+
150
+ Examples:
151
+
65
152
  ```grain
66
- assert Hash.hash("Hello World") == Hash.hash("Hello World")
153
+ let hashInstance = Hash.makeSeeded(1)
154
+ assert Hash.hash(hashInstance," Hello World") == Hash.hash(hashInstance, "Hello World)
67
155
  ```
68
156