@grain/stdlib 0.5.0 → 0.5.3

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.
package/marshal.md ADDED
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: Marshal
3
+ ---
4
+
5
+ Utilities for serializing and deserializing Grain data.
6
+
7
+ <details disabled>
8
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
9
+ No other changes yet.
10
+ </details>
11
+
12
+ ```grain
13
+ import Marshal from "marshal"
14
+ ```
15
+
16
+ ## Values
17
+
18
+ Functions for marshaling and unmarshaling data.
19
+
20
+ ### Marshal.**marshal**
21
+
22
+ <details disabled>
23
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
24
+ No other changes yet.
25
+ </details>
26
+
27
+ ```grain
28
+ marshal : a -> Bytes
29
+ ```
30
+
31
+ Serialize a value into a byte-based representation suitable for transmission
32
+ across a network or disk storage. The byte-based representation can be
33
+ deserialized at a later time to restore the value.
34
+
35
+ Parameters:
36
+
37
+ |param|type|description|
38
+ |-----|----|-----------|
39
+ |`value`|`a`|The value to serialize|
40
+
41
+ Returns:
42
+
43
+ |type|description|
44
+ |----|-----------|
45
+ |`Bytes`|A byte-based representation of the value|
46
+
47
+ ### Marshal.**unmarshal**
48
+
49
+ <details disabled>
50
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
51
+ No other changes yet.
52
+ </details>
53
+
54
+ ```grain
55
+ unmarshal : Bytes -> Result<a, String>
56
+ ```
57
+
58
+ Deserialize the byte-based representation of a value back into an in-memory
59
+ value. This operation is not type-safe, and it is recommended that a type
60
+ annotation is used to declare the type of the unmarshaled value. While
61
+ attempts to unmarshal bad data will fail, this operation is still generally
62
+ unsafe and great care should be taken to ensure that the data being
63
+ unmarshaled corresponds to the expected type.
64
+
65
+ Parameters:
66
+
67
+ |param|type|description|
68
+ |-----|----|-----------|
69
+ |`bytes`|`Bytes`|The data to deserialize|
70
+
71
+ Returns:
72
+
73
+ |type|description|
74
+ |----|-----------|
75
+ |`Result<a, String>`|An in-memory value|
76
+
package/number.gr CHANGED
@@ -13,12 +13,43 @@ import {
13
13
  coerceNumberToWasmF64,
14
14
  reducedInteger,
15
15
  isFloat,
16
+ isInteger,
17
+ isRational,
16
18
  isBoxedNumber,
17
19
  } from "runtime/numbers"
18
20
  import { parseInt } from "runtime/stringUtils"
19
21
  import { newFloat64, newInt64 } from "runtime/dataStructures"
20
22
  import Tags from "runtime/unsafe/tags"
21
23
 
24
+ /**
25
+ * @section Constants: Number constant values.
26
+ */
27
+
28
+ /**
29
+ * Pi represented as a Number value.
30
+ *
31
+ * @since v0.5.2
32
+ */
33
+ export let pi = 3.141592653589793
34
+
35
+ /**
36
+ * Tau represented as a Number value.
37
+ *
38
+ * @since v0.5.2
39
+ */
40
+ export let tau = 6.283185307179586
41
+
42
+ /**
43
+ * Euler's number represented as a Number value.
44
+ *
45
+ * @since v0.5.2
46
+ */
47
+ export let e = 2.718281828459045
48
+
49
+ /**
50
+ * @section Operations: Functions for operating on values of the Number type.
51
+ */
52
+
22
53
  /**
23
54
  * Computes the sum of its operands.
24
55
  *
@@ -203,6 +234,45 @@ export let abs = (x: Number) => if (0 > x) x * -1 else x
203
234
  */
204
235
  export let neg = (x: Number) => x * -1
205
236
 
237
+ /**
238
+ * Checks if a number is a floating point value.
239
+ *
240
+ * @param x: The number to check
241
+ * @returns `true` if the value is a floating point number or `false` otherwise
242
+ *
243
+ * @since v0.5.3
244
+ */
245
+ @unsafe
246
+ export let isFloat = (x: Number) => {
247
+ isFloat(WasmI32.fromGrain(x))
248
+ }
249
+
250
+ /**
251
+ * Checks if a number is an integer.
252
+ *
253
+ * @param x: The number to check
254
+ * @returns `true` if the value is an integer or `false` otherwise
255
+ *
256
+ * @since v0.5.3
257
+ */
258
+ @unsafe
259
+ export let isInteger = (x: Number) => {
260
+ isInteger(WasmI32.fromGrain(x))
261
+ }
262
+
263
+ /**
264
+ * Checks if a number is a non-integer rational value.
265
+ *
266
+ * @param x: The number to check
267
+ * @returns `true` if the value is a non-integer rational number or `false` otherwise
268
+ *
269
+ * @since v0.5.3
270
+ */
271
+ @unsafe
272
+ export let isRational = (x: Number) => {
273
+ isRational(WasmI32.fromGrain(x))
274
+ }
275
+
206
276
  /**
207
277
  * Checks if a number is finite.
208
278
  * All values are finite exept for floating point NaN, infinity or negative infinity.
@@ -317,3 +387,55 @@ export let isInfinite = (x: Number) => {
317
387
  * @since v0.4.5
318
388
  */
319
389
  export parseInt
390
+
391
+ /**
392
+ * Computes how many times pi has to be subtracted to achieve the required bounds for sin.
393
+ */
394
+ let reduceToPiBound = (radians: Number) => {
395
+ floor(radians / pi)
396
+ }
397
+
398
+ /**
399
+ * Computes the sine of a number using Chebyshev polynomials. Requires the input to be bounded to (-pi, pi). More information on the algorithm can be found here: http://mooooo.ooo/chebyshev-sine-approximation/.
400
+ */
401
+ let chebyshevSine = (radians: Number) => {
402
+ let pi_minor = -0.00000008742278
403
+ let x2 = radians * radians
404
+ let p11 = 0.00000000013291342
405
+ let p9 = p11 * x2 + -0.000000023317787
406
+ let p7 = p9 * x2 + 0.0000025222919
407
+ let p5 = p7 * x2 + -0.00017350505
408
+ let p3 = p5 * x2 + 0.0066208798
409
+ let p1 = p3 * x2 + -0.10132118
410
+ (radians - pi - pi_minor) * (radians + pi + pi_minor) * p1 * radians
411
+ }
412
+
413
+ /**
414
+ * Computes the sine of a number (in radians) using Chebyshev polynomials.
415
+ *
416
+ * @param radians: The input in radians
417
+ * @returns The computed sine
418
+ *
419
+ * @since v0.5.2
420
+ */
421
+ export let sin = (radians: Number) => {
422
+ let quot = reduceToPiBound(radians)
423
+ let bounded = radians - pi * quot
424
+ if (quot % 2 == 0) {
425
+ chebyshevSine(bounded)
426
+ } else {
427
+ neg(chebyshevSine(bounded))
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Computes the cosine of a number (in radians) using Chebyshev polynomials.
433
+ *
434
+ * @param radians: The input in radians
435
+ * @returns The computed cosine
436
+ *
437
+ * @since v0.5.2
438
+ */
439
+ export let cos = (radians: Number) => {
440
+ sin(pi / 2 + radians)
441
+ }
package/number.md CHANGED
@@ -13,6 +13,53 @@ No other changes yet.
13
13
  import Number from "number"
14
14
  ```
15
15
 
16
+ ## Constants
17
+
18
+ Number constant values.
19
+
20
+ ### Number.**pi**
21
+
22
+ <details disabled>
23
+ <summary tabindex="-1">Added in <code>0.5.2</code></summary>
24
+ No other changes yet.
25
+ </details>
26
+
27
+ ```grain
28
+ pi : Number
29
+ ```
30
+
31
+ Pi represented as a Number value.
32
+
33
+ ### Number.**tau**
34
+
35
+ <details disabled>
36
+ <summary tabindex="-1">Added in <code>0.5.2</code></summary>
37
+ No other changes yet.
38
+ </details>
39
+
40
+ ```grain
41
+ tau : Number
42
+ ```
43
+
44
+ Tau represented as a Number value.
45
+
46
+ ### Number.**e**
47
+
48
+ <details disabled>
49
+ <summary tabindex="-1">Added in <code>0.5.2</code></summary>
50
+ No other changes yet.
51
+ </details>
52
+
53
+ ```grain
54
+ e : Number
55
+ ```
56
+
57
+ Euler's number represented as a Number value.
58
+
59
+ ## Operations
60
+
61
+ Functions for operating on values of the Number type.
62
+
16
63
  ### Number.**add**
17
64
 
18
65
  <details disabled>
@@ -378,6 +425,81 @@ Returns:
378
425
  |----|-----------|
379
426
  |`Number`|The negated operand|
380
427
 
428
+ ### Number.**isFloat**
429
+
430
+ <details disabled>
431
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
432
+ No other changes yet.
433
+ </details>
434
+
435
+ ```grain
436
+ isFloat : Number -> Bool
437
+ ```
438
+
439
+ Checks if a number is a floating point value.
440
+
441
+ Parameters:
442
+
443
+ |param|type|description|
444
+ |-----|----|-----------|
445
+ |`x`|`Number`|The number to check|
446
+
447
+ Returns:
448
+
449
+ |type|description|
450
+ |----|-----------|
451
+ |`Bool`|`true` if the value is a floating point number or `false` otherwise|
452
+
453
+ ### Number.**isInteger**
454
+
455
+ <details disabled>
456
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
457
+ No other changes yet.
458
+ </details>
459
+
460
+ ```grain
461
+ isInteger : Number -> Bool
462
+ ```
463
+
464
+ Checks if a number is an integer.
465
+
466
+ Parameters:
467
+
468
+ |param|type|description|
469
+ |-----|----|-----------|
470
+ |`x`|`Number`|The number to check|
471
+
472
+ Returns:
473
+
474
+ |type|description|
475
+ |----|-----------|
476
+ |`Bool`|`true` if the value is an integer or `false` otherwise|
477
+
478
+ ### Number.**isRational**
479
+
480
+ <details disabled>
481
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
482
+ No other changes yet.
483
+ </details>
484
+
485
+ ```grain
486
+ isRational : Number -> Bool
487
+ ```
488
+
489
+ Checks if a number is a non-integer rational value.
490
+
491
+ Parameters:
492
+
493
+ |param|type|description|
494
+ |-----|----|-----------|
495
+ |`x`|`Number`|The number to check|
496
+
497
+ Returns:
498
+
499
+ |type|description|
500
+ |----|-----------|
501
+ |`Bool`|`true` if the value is a non-integer rational number or `false` otherwise|
502
+
381
503
  ### Number.**isFinite**
382
504
 
383
505
  <details disabled>
@@ -488,3 +610,53 @@ Returns:
488
610
  |----|-----------|
489
611
  |`Result<Number, String>`|`Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise|
490
612
 
613
+ ### Number.**sin**
614
+
615
+ <details disabled>
616
+ <summary tabindex="-1">Added in <code>0.5.2</code></summary>
617
+ No other changes yet.
618
+ </details>
619
+
620
+ ```grain
621
+ sin : Number -> Number
622
+ ```
623
+
624
+ Computes the sine of a number (in radians) using Chebyshev polynomials.
625
+
626
+ Parameters:
627
+
628
+ |param|type|description|
629
+ |-----|----|-----------|
630
+ |`radians`|`Number`|The input in radians|
631
+
632
+ Returns:
633
+
634
+ |type|description|
635
+ |----|-----------|
636
+ |`Number`|The computed sine|
637
+
638
+ ### Number.**cos**
639
+
640
+ <details disabled>
641
+ <summary tabindex="-1">Added in <code>0.5.2</code></summary>
642
+ No other changes yet.
643
+ </details>
644
+
645
+ ```grain
646
+ cos : Number -> Number
647
+ ```
648
+
649
+ Computes the cosine of a number (in radians) using Chebyshev polynomials.
650
+
651
+ Parameters:
652
+
653
+ |param|type|description|
654
+ |-----|----|-----------|
655
+ |`radians`|`Number`|The input in radians|
656
+
657
+ Returns:
658
+
659
+ |type|description|
660
+ |----|-----------|
661
+ |`Number`|The computed cosine|
662
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grain/stdlib",
3
- "version": "0.5.0",
3
+ "version": "0.5.3",
4
4
  "description": "The standard library for the Grain language.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://grain-lang.org",
package/pervasives.gr CHANGED
@@ -11,6 +11,7 @@ import Memory from "runtime/unsafe/memory"
11
11
  import WasmI32 from "runtime/unsafe/wasmi32"
12
12
 
13
13
  import { equal as (==) } from "runtime/equal"
14
+ import { compare } from "runtime/compare"
14
15
 
15
16
  import {
16
17
  incr,
@@ -218,6 +219,19 @@ export (<=)
218
219
  */
219
220
  export (>=)
220
221
 
222
+ /**
223
+ * Compares the first argument to the second argument and produces an integer result.
224
+ * Provides a consistent ordering over all types and is suitable for sorting and other kinds of ordering.
225
+ * `compare` treats `NaN` differently than the other comparison operators in that it considers `NaN` equal to itself and smaller than any other number.
226
+ *
227
+ * @param num1: The first operand
228
+ * @param num2: The second operand
229
+ * @returns A negative integer if the first operand is less than the second operand, `0` if they are equal, or a positive integer otherwise
230
+ *
231
+ * @since v0.5.3
232
+ */
233
+ export compare
234
+
221
235
  /**
222
236
  * @section Math operations: Infix functions for working with Number values.
223
237
  */
@@ -410,7 +424,7 @@ export (>>)
410
424
 
411
425
  // Number coercions & conversions
412
426
 
413
- // [TODO] (#311) Commented until we nail down semantics
427
+ // TODO(#311): Commented until we nail down semantics
414
428
  // import foreign wasm convertExactToInexact : Number -> Number as inexact from "stdlib-external/runtime"
415
429
  // import foreign wasm convertInexactToExact : Number -> Number as exact from "stdlib-external/runtime"
416
430
 
@@ -553,10 +567,7 @@ export primitive unbox: Box<a> -> a = "@unbox"
553
567
  * @since v0.4.0
554
568
  */
555
569
  export let cons = (a, b) =>
556
- [
557
- a,
558
- ...b
559
- ] // <- workaround for (grain-lang/grain#802) [TODO] fix #802 and delete
570
+ [a, ...b] // TODO(#802): Remove workaround after 802 is completed
560
571
  /**
561
572
  * The empty list syntax (`[]`) provided as a value.
562
573
  *
package/pervasives.md CHANGED
@@ -369,6 +369,34 @@ Returns:
369
369
  |----|-----------|
370
370
  |`Bool`|`true` if the first operand is greater than or equal to the second operand or `false` otherwise|
371
371
 
372
+ ### Pervasives.**compare**
373
+
374
+ <details disabled>
375
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
376
+ No other changes yet.
377
+ </details>
378
+
379
+ ```grain
380
+ compare : (a, a) -> Number
381
+ ```
382
+
383
+ Compares the first argument to the second argument and produces an integer result.
384
+ Provides a consistent ordering over all types and is suitable for sorting and other kinds of ordering.
385
+ `compare` treats `NaN` differently than the other comparison operators in that it considers `NaN` equal to itself and smaller than any other number.
386
+
387
+ Parameters:
388
+
389
+ |param|type|description|
390
+ |-----|----|-----------|
391
+ |`num1`|`a`|The first operand|
392
+ |`num2`|`a`|The second operand|
393
+
394
+ Returns:
395
+
396
+ |type|description|
397
+ |----|-----------|
398
+ |`Number`|A negative integer if the first operand is less than the second operand, `0` if they are equal, or a positive integer otherwise|
399
+
372
400
  ## Math operations
373
401
 
374
402
  Infix functions for working with Number values.