1 func __math_select(list, cmp) {
2 ## Internal helper for `max` and `min`.
3 ##
4 ## NOTE: If `list` is empty, then an error is thrown.
5
6 if (len(list) === 0) {
7 error ("Unexpected empty list", status=3)
8 }
9
10 if (len(list) === 1) {
11 return (list[0])
12 }
13
14 var match = list[0]
15 for i in (1:len(list)) {
16 setvar match = cmp(list[i], match)
17 }
18 return (match)
19 }
20
21 func max(...args) {
22 ## Compute the maximum of 2 or more values.
23 ##
24 ## `max` takes two different signatures:
25 ## - `max(a, b)` to return the maximum of `a`, `b`
26 ## - `max(list)` to return the greatest item in the `list`
27 ##
28 ## So, for example:
29 ##
30 ## max(1, 2) # => 2
31 ## max([1, 2, 3]) # => 3
32
33 case (len(args)) {
34 (1) { return (__math_select(args[0], max)) }
35 (2) {
36 if (args[0] > args[1]) {
37 return (args[0])
38 } else {
39 return (args[1])
40 }
41 }
42 (else) { error ("max expects 1 or 2 args", status=3) }
43 }
44 }
45
46 func min(...args) {
47 ## Compute the minimum of 2 or more values.
48 ##
49 ## `min` takes two different signatures:
50 ## - `min(a, b)` to return the minimum of `a`, `b`
51 ## - `min(list)` to return the least item in the `list`
52 ##
53 ## So, for example:
54 ##
55 ## min(2, 3) # => 2
56 ## max([1, 2, 3]) # => 1
57
58 case (len(args)) {
59 (1) { return (__math_select(args[0], min)) }
60 (2) {
61 if (args[0] < args[1]) {
62 return (args[0])
63 } else {
64 return (args[1])
65 }
66 }
67 (else) { error ("min expects 1 or 2 args", status=3) }
68 }
69 }
70
71 func abs(x) {
72 ## Compute the absolute (positive) value of a number (float or int).
73
74 if (x < 0) {
75 return (-x)
76 } else {
77 return (x)
78 }
79 }