blob: 11a294b4373149619e58b5836488c053c90e6305 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
(local {: insert : unpack} (require :toast.table))
; math
(fn dec [n]
"Decrement n by 1."
(- n 1))
(fn inc [n]
"Increment n by 1."
(+ n 1))
; checks?
(fn empty? [xs]
"Returns true if the lengthable contains no elements."
(= 0 (length xs)))
(fn nil? [x]
"Returns true if the argument is nil."
(= nil x))
(fn number? [n]
"Returns true if the argument is a number."
(= :number (type n)))
(fn even? [n]
"Returns true if the argument is an even number."
(and (number? n) (= 0 (% n 2))))
(fn odd? [n]
"Returns true if the argument is an odd number."
(and (number? n) (not= 0 (% n 2))))
(fn every? [pred xs]
"Returns true if (pred x) is logical true for every x in xs, else false."
(accumulate [pass true
_ x (ipairs xs)
&until (not pass)]
(pred x)))
; sequences
(fn drop [n xs]
"Returns a table of all but the first n elements in xs."
(let [out []]
(each [i v (ipairs xs)]
(when (> i n) (insert out v)))
out))
(fn first [xs]
"The first element in a sequential table."
(. xs 1))
(fn last [xs]
"The last element in a sequential table."
(. xs (length xs)))
(fn group [n xs]
"Group elements in xs in groups of n.
Extra elements at the end will sit in the final group.
For example, (group 2 [1 2 3 4 5]) results in [[1 2] [3 4] [5]].
One exception is if xs is empty, in which case an empty collection is returned."
(if (empty? xs)
[]
(let [ll #(length (last $))
donext #(= (ll $) n)]
(accumulate [out [[]]
_ v (ipairs xs)]
(do (when (donext out)
(insert out []))
(insert (last out) v
out))))))
; HOF
(fn assoc [?t ...]
"Sets the key `k` in table `t` to the value `v`.
Accepts an arbitrary amount of `k` and `v` pairs.
Returns the mutated table `t`."
(let [t (or ?t {})
lt (inc (length t)) ; for numerical keys
[k v & xs] [...]]
(case k
nil nil
(where k (and (number? k) (> lt k))) (set (. t k) v)
(where k (and (number? k) (= k lt))) (table.insert t v)
_ (tset t k v))
(case (length xs)
0 t
1 (error "assoc expects even number of arguments after table, found odd number")
_ (assoc t (unpack xs)))))
; TODO: split into filter and kfilter?
(fn filter [f xs]
"Returns a sequential table consisting only of elements in xs that return a truth value when passed to f.
Note that the call will be (f k v), not (f v)."
(accumulate [out []
k v (ipairs xs)]
(if (f k v)
(insert out v)
out)))
(fn map [f xs]
"Returns a sequential table consisting of the result of apply f to every item in xs."
(accumulate [out []
_ v (ipairs (or xs []))]
(let [mapped (f v)]
(insert out (if (= 0 (select :# mapped))
nil
mapped)))))
; TODO: rework
(fn mapcat [f xs]
(accumulate [out []
_ v (ipairs xs)]
(do (each [_ v (ipairs (f v))]
(table.insert out v))
out)))
; sequences cont
(fn flat [xs]
"Flattens a sequential table xs such that there are no sub-tables."
(case (type xs)
:table (mapcat flat xs)
_ [xs]))
{;math
: dec
: inc
; checks?
: empty?
: nil?
: number?
: even?
: odd?
: every?
; sequences
: drop
: first
: last
: group
: flat
; HOF
: assoc
: filter
: map
: mapcat}
|