conjure-js 0.0.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.
- package/conjure +0 -0
- package/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- package/dist/assets/editor.worker-CdQrwHl8.js +26 -0
- package/dist/assets/main-A7ZMId9A.css +1 -0
- package/dist/assets/main-CmI-7epE.js +3137 -0
- package/dist/index.html +195 -0
- package/dist/vite.svg +1 -0
- package/package.json +68 -0
- package/src/bin/__fixtures__/smoke/app/lib.clj +4 -0
- package/src/bin/__fixtures__/smoke/app/main.clj +4 -0
- package/src/bin/__fixtures__/smoke/repl-smoke.ts +12 -0
- package/src/bin/bencode.ts +205 -0
- package/src/bin/cli.ts +250 -0
- package/src/bin/nrepl-utils.ts +59 -0
- package/src/bin/nrepl.ts +393 -0
- package/src/bin/version.ts +4 -0
- package/src/clojure/core.clj +620 -0
- package/src/clojure/core.clj.d.ts +189 -0
- package/src/clojure/demo/math.clj +16 -0
- package/src/clojure/demo/math.clj.d.ts +4 -0
- package/src/clojure/demo.clj +42 -0
- package/src/clojure/demo.clj.d.ts +0 -0
- package/src/clojure/generated/builtin-namespace-registry.ts +14 -0
- package/src/clojure/generated/clojure-core-source.ts +623 -0
- package/src/clojure/generated/clojure-string-source.ts +196 -0
- package/src/clojure/string.clj +192 -0
- package/src/clojure/string.clj.d.ts +25 -0
- package/src/core/assertions.ts +134 -0
- package/src/core/conversions.ts +108 -0
- package/src/core/core-env.ts +58 -0
- package/src/core/env.ts +78 -0
- package/src/core/errors.ts +39 -0
- package/src/core/evaluator/apply.ts +114 -0
- package/src/core/evaluator/arity.ts +174 -0
- package/src/core/evaluator/collections.ts +25 -0
- package/src/core/evaluator/destructure.ts +247 -0
- package/src/core/evaluator/dispatch.ts +73 -0
- package/src/core/evaluator/evaluate.ts +100 -0
- package/src/core/evaluator/expand.ts +79 -0
- package/src/core/evaluator/index.ts +72 -0
- package/src/core/evaluator/quasiquote.ts +87 -0
- package/src/core/evaluator/recur-check.ts +109 -0
- package/src/core/evaluator/special-forms.ts +517 -0
- package/src/core/factories.ts +155 -0
- package/src/core/gensym.ts +9 -0
- package/src/core/index.ts +76 -0
- package/src/core/positions.ts +38 -0
- package/src/core/printer.ts +86 -0
- package/src/core/reader.ts +559 -0
- package/src/core/scanners.ts +93 -0
- package/src/core/session.ts +610 -0
- package/src/core/stdlib/arithmetic.ts +361 -0
- package/src/core/stdlib/atoms.ts +88 -0
- package/src/core/stdlib/collections.ts +784 -0
- package/src/core/stdlib/errors.ts +81 -0
- package/src/core/stdlib/hof.ts +307 -0
- package/src/core/stdlib/meta.ts +48 -0
- package/src/core/stdlib/predicates.ts +240 -0
- package/src/core/stdlib/regex.ts +238 -0
- package/src/core/stdlib/strings.ts +311 -0
- package/src/core/stdlib/transducers.ts +256 -0
- package/src/core/stdlib/utils.ts +287 -0
- package/src/core/tokenizer.ts +437 -0
- package/src/core/transformations.ts +75 -0
- package/src/core/types.ts +258 -0
- package/src/main.ts +1 -0
- package/src/monaco-esm.d.ts +7 -0
- package/src/playground/clojure-tokens.ts +67 -0
- package/src/playground/editor.worker.ts +5 -0
- package/src/playground/find-form.ts +138 -0
- package/src/playground/playground.ts +342 -0
- package/src/playground/samples/00-welcome.clj +385 -0
- package/src/playground/samples/01-collections.clj +191 -0
- package/src/playground/samples/02-higher-order-functions.clj +215 -0
- package/src/playground/samples/03-destructuring.clj +194 -0
- package/src/playground/samples/04-strings-and-regex.clj +202 -0
- package/src/playground/samples/05-error-handling.clj +212 -0
- package/src/repl/repl.ts +116 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
(ns clojure.core)
|
|
2
|
+
|
|
3
|
+
(defmacro defn [name & fdecl]
|
|
4
|
+
(let [doc (if (string? (first fdecl)) (first fdecl) nil)
|
|
5
|
+
rest-decl (if doc (rest fdecl) fdecl)
|
|
6
|
+
arglists (if (vector? (first rest-decl))
|
|
7
|
+
(vector (first rest-decl))
|
|
8
|
+
(reduce (fn [acc arity] (conj acc (first arity))) [] rest-decl))]
|
|
9
|
+
(if doc
|
|
10
|
+
`(def ~name (with-meta (fn ~@rest-decl) {:doc ~doc :arglists '~arglists}))
|
|
11
|
+
`(def ~name (with-meta (fn ~@rest-decl) {:arglists '~arglists})))))
|
|
12
|
+
|
|
13
|
+
(defn next
|
|
14
|
+
"Returns a seq of the items after the first. Calls seq on its
|
|
15
|
+
argument. If there are no more items, returns nil."
|
|
16
|
+
[coll]
|
|
17
|
+
(seq (rest coll)))
|
|
18
|
+
|
|
19
|
+
(defn not
|
|
20
|
+
"Returns true if x is logical false, false otherwise."
|
|
21
|
+
[x] (if x false true))
|
|
22
|
+
|
|
23
|
+
(defn second
|
|
24
|
+
"Same as (first (next x))"
|
|
25
|
+
[coll]
|
|
26
|
+
(first (next coll)))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
(defmacro when [condition & body]
|
|
30
|
+
`(if ~condition (do ~@body) nil))
|
|
31
|
+
|
|
32
|
+
(defmacro when-not [condition & body]
|
|
33
|
+
`(if ~condition nil (do ~@body)))
|
|
34
|
+
|
|
35
|
+
(defmacro if-let
|
|
36
|
+
([bindings then] `(if-let ~bindings ~then nil))
|
|
37
|
+
([bindings then else]
|
|
38
|
+
(let [form (first bindings)
|
|
39
|
+
tst (second bindings)]
|
|
40
|
+
`(let [~form ~tst]
|
|
41
|
+
(if ~form ~then ~else)))))
|
|
42
|
+
|
|
43
|
+
(defmacro when-let [bindings & body]
|
|
44
|
+
(let [form (first bindings)
|
|
45
|
+
tst (second bindings)]
|
|
46
|
+
`(let [~form ~tst]
|
|
47
|
+
(when ~form ~@body))))
|
|
48
|
+
|
|
49
|
+
(defmacro and [& forms]
|
|
50
|
+
(if (nil? forms)
|
|
51
|
+
true
|
|
52
|
+
(if (nil? (seq (rest forms)))
|
|
53
|
+
(first forms)
|
|
54
|
+
`(let [v# ~(first forms)]
|
|
55
|
+
(if v# (and ~@(rest forms)) v#)))))
|
|
56
|
+
|
|
57
|
+
(defmacro or [& forms]
|
|
58
|
+
(if (nil? forms)
|
|
59
|
+
nil
|
|
60
|
+
(if (nil? (seq (rest forms)))
|
|
61
|
+
(first forms)
|
|
62
|
+
`(let [v# ~(first forms)]
|
|
63
|
+
(if v# v# (or ~@(rest forms)))))))
|
|
64
|
+
|
|
65
|
+
(defmacro cond [& clauses]
|
|
66
|
+
(if (nil? clauses)
|
|
67
|
+
nil
|
|
68
|
+
`(if ~(first clauses)
|
|
69
|
+
~(first (next clauses))
|
|
70
|
+
(cond ~@(rest (rest clauses))))))
|
|
71
|
+
|
|
72
|
+
(defmacro -> [x & forms]
|
|
73
|
+
(if (nil? forms)
|
|
74
|
+
x
|
|
75
|
+
(let [form (first forms)
|
|
76
|
+
more (rest forms)
|
|
77
|
+
threaded (if (list? form)
|
|
78
|
+
`(~(first form) ~x ~@(rest form))
|
|
79
|
+
`(~form ~x))]
|
|
80
|
+
`(-> ~threaded ~@more))))
|
|
81
|
+
|
|
82
|
+
(defmacro ->> [x & forms]
|
|
83
|
+
(if (nil? forms)
|
|
84
|
+
x
|
|
85
|
+
(let [form (first forms)
|
|
86
|
+
more (rest forms)
|
|
87
|
+
threaded (if (list? form)
|
|
88
|
+
`(~(first form) ~@(rest form) ~x)
|
|
89
|
+
`(~form ~x))]
|
|
90
|
+
`(->> ~threaded ~@more))))
|
|
91
|
+
|
|
92
|
+
(defmacro comment
|
|
93
|
+
; Ignores body, yields nil
|
|
94
|
+
[& body])
|
|
95
|
+
|
|
96
|
+
(defn constantly
|
|
97
|
+
"Returns a function that takes any number of arguments and returns x."
|
|
98
|
+
[x] (fn [& _] x))
|
|
99
|
+
|
|
100
|
+
(defn some?
|
|
101
|
+
"Returns true if x is not nil, false otherwise"
|
|
102
|
+
[x] (not (nil? x)))
|
|
103
|
+
|
|
104
|
+
(defn any?
|
|
105
|
+
"Returns true for any given argument"
|
|
106
|
+
[_x] true)
|
|
107
|
+
|
|
108
|
+
(defn complement
|
|
109
|
+
"Takes a fn f and returns a fn that takes the same arguments as f,
|
|
110
|
+
has the same effects, if any, and returns the opposite truth value."
|
|
111
|
+
[f]
|
|
112
|
+
(fn
|
|
113
|
+
([] (not (f)))
|
|
114
|
+
([x] (not (f x)))
|
|
115
|
+
([x y] (not (f x y)))
|
|
116
|
+
([x y & zs] (not (apply f x y zs)))))
|
|
117
|
+
|
|
118
|
+
(defn juxt
|
|
119
|
+
"Takes a set of functions and returns a fn that is the juxtaposition
|
|
120
|
+
of those fns. The returned fn takes a variable number of args and
|
|
121
|
+
returns a vector containing the result of applying each fn to the args."
|
|
122
|
+
[& fns]
|
|
123
|
+
(fn [& args]
|
|
124
|
+
(reduce (fn [acc f] (conj acc (apply f args))) [] fns)))
|
|
125
|
+
|
|
126
|
+
(defn merge
|
|
127
|
+
"Returns a map that consists of the rest of the maps conj-ed onto
|
|
128
|
+
the first. If a key occurs in more than one map, the mapping from
|
|
129
|
+
the latter (left-to-right) will be the mapping in the result."
|
|
130
|
+
[& maps]
|
|
131
|
+
(if (nil? maps)
|
|
132
|
+
nil
|
|
133
|
+
(reduce
|
|
134
|
+
(fn [acc m]
|
|
135
|
+
(if (nil? m)
|
|
136
|
+
acc
|
|
137
|
+
(if (nil? acc)
|
|
138
|
+
m
|
|
139
|
+
(reduce
|
|
140
|
+
(fn [macc entry]
|
|
141
|
+
(assoc macc (first entry) (second entry)))
|
|
142
|
+
acc
|
|
143
|
+
m))))
|
|
144
|
+
nil
|
|
145
|
+
maps)))
|
|
146
|
+
|
|
147
|
+
(defn select-keys
|
|
148
|
+
"Returns a map containing only those entries in map whose key is in keys."
|
|
149
|
+
[m keys]
|
|
150
|
+
(if (or (nil? m) (nil? keys))
|
|
151
|
+
{}
|
|
152
|
+
(let [missing (gensym)]
|
|
153
|
+
(reduce
|
|
154
|
+
(fn [acc k]
|
|
155
|
+
(let [v (get m k missing)]
|
|
156
|
+
(if (= v missing)
|
|
157
|
+
acc
|
|
158
|
+
(assoc acc k v))))
|
|
159
|
+
{}
|
|
160
|
+
keys))))
|
|
161
|
+
|
|
162
|
+
(defn update
|
|
163
|
+
"Updates a value in an associative structure where k is a key and f is a
|
|
164
|
+
function that will take the old value and any supplied args and return the
|
|
165
|
+
new value, and returns a new structure."
|
|
166
|
+
[m k f & args]
|
|
167
|
+
(let [target (if (nil? m) {} m)]
|
|
168
|
+
(assoc target k (if (nil? args)
|
|
169
|
+
(f (get target k))
|
|
170
|
+
(apply f (get target k) args)))))
|
|
171
|
+
|
|
172
|
+
(defn get-in
|
|
173
|
+
"Returns the value in a nested associative structure, where ks is a
|
|
174
|
+
sequence of keys. Returns nil if the key is not present, or the not-found
|
|
175
|
+
value if supplied."
|
|
176
|
+
([m ks]
|
|
177
|
+
(reduce get m ks))
|
|
178
|
+
([m ks not-found]
|
|
179
|
+
(loop [m m, ks (seq ks)]
|
|
180
|
+
(if (nil? ks)
|
|
181
|
+
m
|
|
182
|
+
(if (contains? m (first ks))
|
|
183
|
+
(recur (get m (first ks)) (next ks))
|
|
184
|
+
not-found)))))
|
|
185
|
+
|
|
186
|
+
(defn assoc-in
|
|
187
|
+
"Associates a value in a nested associative structure, where ks is a
|
|
188
|
+
sequence of keys and v is the new value. Returns a new nested structure."
|
|
189
|
+
[m [k & ks] v]
|
|
190
|
+
(if ks
|
|
191
|
+
(assoc m k (assoc-in (get m k) ks v))
|
|
192
|
+
(assoc m k v)))
|
|
193
|
+
|
|
194
|
+
(defn update-in
|
|
195
|
+
"Updates a value in a nested associative structure, where ks is a
|
|
196
|
+
sequence of keys and f is a function that will take the old value and any
|
|
197
|
+
supplied args and return the new value. Returns a new nested structure."
|
|
198
|
+
[m ks f & args]
|
|
199
|
+
(assoc-in m ks (apply f (get-in m ks) args)))
|
|
200
|
+
|
|
201
|
+
(defn fnil
|
|
202
|
+
"Takes a function f, and returns a function that calls f, replacing
|
|
203
|
+
a nil first argument with x, optionally nil second with y, nil third with z."
|
|
204
|
+
([f x]
|
|
205
|
+
(fn [a & more]
|
|
206
|
+
(apply f (if (nil? a) x a) more)))
|
|
207
|
+
([f x y]
|
|
208
|
+
(fn [a b & more]
|
|
209
|
+
(apply f (if (nil? a) x a) (if (nil? b) y b) more)))
|
|
210
|
+
([f x y z]
|
|
211
|
+
(fn [a b c & more]
|
|
212
|
+
(apply f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c) more))))
|
|
213
|
+
|
|
214
|
+
(defn frequencies
|
|
215
|
+
"Returns a map from distinct items in coll to the number of times they appear."
|
|
216
|
+
[coll]
|
|
217
|
+
(if (nil? coll)
|
|
218
|
+
{}
|
|
219
|
+
(reduce
|
|
220
|
+
(fn [counts item]
|
|
221
|
+
(assoc counts item (inc (get counts item 0))))
|
|
222
|
+
{}
|
|
223
|
+
coll)))
|
|
224
|
+
|
|
225
|
+
(defn group-by
|
|
226
|
+
"Returns a map of the elements of coll keyed by the result of f on each
|
|
227
|
+
element. The value at each key is a vector of matching elements."
|
|
228
|
+
[f coll]
|
|
229
|
+
(if (nil? coll)
|
|
230
|
+
{}
|
|
231
|
+
(reduce
|
|
232
|
+
(fn [acc item]
|
|
233
|
+
(let [k (f item)]
|
|
234
|
+
(assoc acc k (conj (get acc k []) item))))
|
|
235
|
+
{}
|
|
236
|
+
coll)))
|
|
237
|
+
|
|
238
|
+
(defn distinct
|
|
239
|
+
"Returns a vector of the elements of coll with duplicates removed,
|
|
240
|
+
preserving first-seen order."
|
|
241
|
+
[coll]
|
|
242
|
+
(if (nil? coll)
|
|
243
|
+
[]
|
|
244
|
+
(get
|
|
245
|
+
(reduce
|
|
246
|
+
(fn [state item]
|
|
247
|
+
(let [seen (get state 0)
|
|
248
|
+
out (get state 1)]
|
|
249
|
+
(if (get seen item false)
|
|
250
|
+
state
|
|
251
|
+
[(assoc seen item true) (conj out item)])))
|
|
252
|
+
[{} []]
|
|
253
|
+
coll)
|
|
254
|
+
1)))
|
|
255
|
+
|
|
256
|
+
(defn flatten-step
|
|
257
|
+
"Internal helper for flatten."
|
|
258
|
+
[v]
|
|
259
|
+
(if (or (list? v) (vector? v))
|
|
260
|
+
(reduce
|
|
261
|
+
(fn [acc item]
|
|
262
|
+
(into acc (flatten-step item)))
|
|
263
|
+
[]
|
|
264
|
+
v)
|
|
265
|
+
[v]))
|
|
266
|
+
|
|
267
|
+
(defn flatten
|
|
268
|
+
"Takes any nested combination of sequential things (lists/vectors) and
|
|
269
|
+
returns their contents as a single flat vector."
|
|
270
|
+
[x]
|
|
271
|
+
(if (nil? x)
|
|
272
|
+
[]
|
|
273
|
+
(flatten-step x)))
|
|
274
|
+
|
|
275
|
+
(defn reduce-kv
|
|
276
|
+
"Reduces an associative structure. f should be a function of 3
|
|
277
|
+
arguments: accumulator, key/index, value."
|
|
278
|
+
[f init coll]
|
|
279
|
+
(cond
|
|
280
|
+
(map? coll)
|
|
281
|
+
(reduce
|
|
282
|
+
(fn [acc entry]
|
|
283
|
+
(f acc (first entry) (second entry)))
|
|
284
|
+
init
|
|
285
|
+
coll)
|
|
286
|
+
|
|
287
|
+
(vector? coll)
|
|
288
|
+
(loop [idx 0
|
|
289
|
+
acc init]
|
|
290
|
+
(if (< idx (count coll))
|
|
291
|
+
(recur (inc idx) (f acc idx (nth coll idx)))
|
|
292
|
+
acc))
|
|
293
|
+
|
|
294
|
+
:else
|
|
295
|
+
(throw
|
|
296
|
+
(ex-info
|
|
297
|
+
"reduce-kv expects a map or vector"
|
|
298
|
+
{:coll coll}))))
|
|
299
|
+
|
|
300
|
+
(defn sort-compare
|
|
301
|
+
"Internal helper: normalizes comparator results."
|
|
302
|
+
[cmp a b]
|
|
303
|
+
(let [r (cmp a b)]
|
|
304
|
+
(if (number? r)
|
|
305
|
+
(< r 0)
|
|
306
|
+
r)))
|
|
307
|
+
|
|
308
|
+
(defn insert-sorted
|
|
309
|
+
"Internal helper for insertion-sort based sort implementation."
|
|
310
|
+
[cmp x sorted]
|
|
311
|
+
(loop [left []
|
|
312
|
+
right sorted]
|
|
313
|
+
(if (nil? (seq right))
|
|
314
|
+
(conj left x)
|
|
315
|
+
(let [y (first right)]
|
|
316
|
+
(if (sort-compare cmp x y)
|
|
317
|
+
(into (conj left x) right)
|
|
318
|
+
(recur (conj left y) (rest right)))))))
|
|
319
|
+
|
|
320
|
+
(defn sort
|
|
321
|
+
"Returns the items in coll in sorted order. With no comparator, sorts
|
|
322
|
+
ascending using <. Comparator may return boolean or number."
|
|
323
|
+
([coll] (sort < coll))
|
|
324
|
+
([cmp coll]
|
|
325
|
+
(if (nil? coll)
|
|
326
|
+
[]
|
|
327
|
+
(reduce
|
|
328
|
+
(fn [acc item]
|
|
329
|
+
(insert-sorted cmp item acc))
|
|
330
|
+
[]
|
|
331
|
+
coll))))
|
|
332
|
+
|
|
333
|
+
(defn sort-by
|
|
334
|
+
"Returns a sorted sequence of items in coll, where the sort order is
|
|
335
|
+
determined by comparing (keyfn item)."
|
|
336
|
+
([keyfn coll] (sort-by keyfn < coll))
|
|
337
|
+
([keyfn cmp coll]
|
|
338
|
+
(sort
|
|
339
|
+
(fn [a b]
|
|
340
|
+
(cmp (keyfn a) (keyfn b)))
|
|
341
|
+
coll)))
|
|
342
|
+
|
|
343
|
+
(def not-any? (comp not some))
|
|
344
|
+
|
|
345
|
+
(defn not-every?
|
|
346
|
+
"Returns false if (pred x) is logical true for every x in
|
|
347
|
+
coll, else true."
|
|
348
|
+
[pred coll] (not (every? pred coll)))
|
|
349
|
+
|
|
350
|
+
;; ── Transducer protocol ──────────────────────────────────────────────────────
|
|
351
|
+
|
|
352
|
+
;; into: 2-arity uses reduce+conj; 3-arity uses transduce
|
|
353
|
+
(defn into
|
|
354
|
+
"Returns a new coll consisting of to-coll with all of the items of
|
|
355
|
+
from-coll conjoined. A transducer may be supplied."
|
|
356
|
+
([to from] (reduce conj to from))
|
|
357
|
+
([to xf from] (transduce xf conj to from)))
|
|
358
|
+
|
|
359
|
+
;; sequence: materialise a transducer over a collection into a seq (list)
|
|
360
|
+
(defn sequence
|
|
361
|
+
"Coerces coll to a (possibly empty) sequence, if it is not already
|
|
362
|
+
one. Will not force a seq. (sequence nil) yields (), When a
|
|
363
|
+
transducer is supplied, returns a lazy sequence of applications of
|
|
364
|
+
the transform to the items in coll"
|
|
365
|
+
([coll] (apply list (into [] coll)))
|
|
366
|
+
([xf coll] (apply list (into [] xf coll))))
|
|
367
|
+
|
|
368
|
+
(defn completing
|
|
369
|
+
"Takes a reducing function f of 2 args and returns a fn suitable for
|
|
370
|
+
transduce by adding an arity-1 signature that calls cf (default -
|
|
371
|
+
identity) on the result argument."
|
|
372
|
+
([f] (completing f identity))
|
|
373
|
+
([f cf]
|
|
374
|
+
(fn
|
|
375
|
+
([] (f))
|
|
376
|
+
([x] (cf x))
|
|
377
|
+
([x y] (f x y)))))
|
|
378
|
+
|
|
379
|
+
;; map: 1-arg returns transducer; 2-arg is eager; 3+-arg zips collections
|
|
380
|
+
(defn map
|
|
381
|
+
"Returns a sequence consisting of the result of applying f to the set
|
|
382
|
+
of first items of each coll, followed by applying f to the set of
|
|
383
|
+
second items in each coll, until any one of the colls is exhausted.
|
|
384
|
+
Any remaining items in other colls are ignored. Returns a transducer
|
|
385
|
+
when no collection is provided."
|
|
386
|
+
([f]
|
|
387
|
+
(fn [rf]
|
|
388
|
+
(fn
|
|
389
|
+
([] (rf))
|
|
390
|
+
([result] (rf result))
|
|
391
|
+
([result input] (rf result (f input))))))
|
|
392
|
+
([f coll]
|
|
393
|
+
(sequence (map f) coll))
|
|
394
|
+
([f c1 c2]
|
|
395
|
+
(loop [s1 (seq c1)
|
|
396
|
+
s2 (seq c2)
|
|
397
|
+
acc []]
|
|
398
|
+
(if (or (nil? s1) (nil? s2))
|
|
399
|
+
acc
|
|
400
|
+
(recur
|
|
401
|
+
(next s1)
|
|
402
|
+
(next s2)
|
|
403
|
+
(conj acc (f (first s1) (first s2)))))))
|
|
404
|
+
([f c1 c2 & colls]
|
|
405
|
+
(loop [seqs (map seq (cons c1 (cons c2 colls)))
|
|
406
|
+
acc []]
|
|
407
|
+
(if (some nil? seqs)
|
|
408
|
+
acc
|
|
409
|
+
(recur (map next seqs) (conj acc (apply f (map first seqs))))))))
|
|
410
|
+
|
|
411
|
+
;; filter: 1-arg returns transducer; 2-arg is eager
|
|
412
|
+
(defn filter
|
|
413
|
+
"Returns a sequence of the items in coll for which
|
|
414
|
+
(pred item) returns logical true. pred must be free of side-effects.
|
|
415
|
+
Returns a transducer when no collection is provided."
|
|
416
|
+
([pred]
|
|
417
|
+
(fn [rf]
|
|
418
|
+
(fn
|
|
419
|
+
([] (rf))
|
|
420
|
+
([result] (rf result))
|
|
421
|
+
([result input]
|
|
422
|
+
(if (pred input)
|
|
423
|
+
(rf result input)
|
|
424
|
+
result)))))
|
|
425
|
+
([pred coll]
|
|
426
|
+
(sequence (filter pred) coll)))
|
|
427
|
+
|
|
428
|
+
(defn remove
|
|
429
|
+
"Returns a lazy sequence of the items in coll for which
|
|
430
|
+
(pred item) returns logical false. pred must be free of side-effects.
|
|
431
|
+
Returns a transducer when no collection is provided."
|
|
432
|
+
([pred] (filter (complement pred)))
|
|
433
|
+
([pred coll]
|
|
434
|
+
(filter (complement pred) coll)))
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
;; take: stateful transducer; signals early termination after n items
|
|
439
|
+
;; r > 0 → keep going; r = 0 → take last item and stop; r < 0 → already past limit, stop
|
|
440
|
+
(defn take
|
|
441
|
+
"Returns a sequence of the first n items in coll, or all items if
|
|
442
|
+
there are fewer than n. Returns a stateful transducer when
|
|
443
|
+
no collection is provided."
|
|
444
|
+
([n]
|
|
445
|
+
(fn [rf]
|
|
446
|
+
(let [remaining (volatile! n)]
|
|
447
|
+
(fn
|
|
448
|
+
([] (rf))
|
|
449
|
+
([result] (rf result))
|
|
450
|
+
([result input]
|
|
451
|
+
(let [n @remaining
|
|
452
|
+
nrem (vswap! remaining dec)
|
|
453
|
+
result (if (pos? n)
|
|
454
|
+
(rf result input)
|
|
455
|
+
result)]
|
|
456
|
+
(if (not (pos? nrem))
|
|
457
|
+
(ensure-reduced result)
|
|
458
|
+
result)))))))
|
|
459
|
+
([n coll]
|
|
460
|
+
(sequence (take n) coll)))
|
|
461
|
+
|
|
462
|
+
;; take-while: stateless transducer; emits reduced when pred fails
|
|
463
|
+
(defn take-while
|
|
464
|
+
"Returns a sequence of successive items from coll while
|
|
465
|
+
(pred item) returns logical true. pred must be free of side-effects.
|
|
466
|
+
Returns a transducer when no collection is provided."
|
|
467
|
+
([pred]
|
|
468
|
+
(fn [rf]
|
|
469
|
+
(fn
|
|
470
|
+
([] (rf))
|
|
471
|
+
([result] (rf result))
|
|
472
|
+
([result input]
|
|
473
|
+
(if (pred input)
|
|
474
|
+
(rf result input)
|
|
475
|
+
(reduced result))))))
|
|
476
|
+
([pred coll]
|
|
477
|
+
(sequence (take-while pred) coll)))
|
|
478
|
+
|
|
479
|
+
;; drop: stateful transducer; skips first n items
|
|
480
|
+
;; r >= 0 → still skipping; r < 0 → past the drop zone, start taking
|
|
481
|
+
(defn drop
|
|
482
|
+
"Returns a sequence of all but the first n items in coll.
|
|
483
|
+
Returns a stateful transducer when no collection is provided."
|
|
484
|
+
([n]
|
|
485
|
+
(fn [rf]
|
|
486
|
+
(let [remaining (volatile! n)]
|
|
487
|
+
(fn
|
|
488
|
+
([] (rf))
|
|
489
|
+
([result] (rf result))
|
|
490
|
+
([result input]
|
|
491
|
+
(let [rem @remaining]
|
|
492
|
+
(vswap! remaining dec)
|
|
493
|
+
(if (pos? rem)
|
|
494
|
+
result
|
|
495
|
+
(rf result input))))))))
|
|
496
|
+
([n coll]
|
|
497
|
+
(sequence (drop n) coll)))
|
|
498
|
+
|
|
499
|
+
(defn drop-last
|
|
500
|
+
"Return a sequence of all but the last n (default 1) items in coll"
|
|
501
|
+
([coll] (drop-last 1 coll))
|
|
502
|
+
([n coll] (map (fn [x _] x) coll (drop n coll))))
|
|
503
|
+
|
|
504
|
+
(defn take-last
|
|
505
|
+
"Returns a sequence of the last n items in coll. Depending on the type
|
|
506
|
+
of coll may be no better than linear time. For vectors, see also subvec."
|
|
507
|
+
[n coll]
|
|
508
|
+
(loop [s (seq coll), lead (seq (drop n coll))]
|
|
509
|
+
(if lead
|
|
510
|
+
(recur (next s) (next lead))
|
|
511
|
+
s)))
|
|
512
|
+
|
|
513
|
+
;; drop-while: stateful transducer; passes through once pred fails
|
|
514
|
+
(defn drop-while
|
|
515
|
+
"Returns a sequence of the items in coll starting from the
|
|
516
|
+
first item for which (pred item) returns logical false. Returns a
|
|
517
|
+
stateful transducer when no collection is provided."
|
|
518
|
+
([pred]
|
|
519
|
+
(fn [rf]
|
|
520
|
+
(let [dropping (volatile! true)]
|
|
521
|
+
(fn
|
|
522
|
+
([] (rf))
|
|
523
|
+
([result] (rf result))
|
|
524
|
+
([result input]
|
|
525
|
+
(if (and @dropping (pred input))
|
|
526
|
+
result
|
|
527
|
+
(do
|
|
528
|
+
(vreset! dropping false)
|
|
529
|
+
(rf result input))))))))
|
|
530
|
+
([pred coll]
|
|
531
|
+
(sequence (drop-while pred) coll)))
|
|
532
|
+
|
|
533
|
+
;; map-indexed: stateful transducer; passes index and item to f
|
|
534
|
+
(defn map-indexed
|
|
535
|
+
"Returns a sequence consisting of the result of applying f to 0
|
|
536
|
+
and the first item of coll, followed by applying f to 1 and the second
|
|
537
|
+
item in coll, etc, until coll is exhausted. Thus function f should
|
|
538
|
+
accept 2 arguments, index and item. Returns a stateful transducer when
|
|
539
|
+
no collection is provided."
|
|
540
|
+
([f]
|
|
541
|
+
(fn [rf]
|
|
542
|
+
(let [i (volatile! -1)]
|
|
543
|
+
(fn
|
|
544
|
+
([] (rf))
|
|
545
|
+
([result] (rf result))
|
|
546
|
+
([result input]
|
|
547
|
+
(rf result (f (vswap! i inc) input)))))))
|
|
548
|
+
([f coll]
|
|
549
|
+
(sequence (map-indexed f) coll)))
|
|
550
|
+
|
|
551
|
+
;; dedupe: stateful transducer; removes consecutive duplicates
|
|
552
|
+
(defn dedupe
|
|
553
|
+
"Returns a sequence removing consecutive duplicates in coll.
|
|
554
|
+
Returns a transducer when no collection is provided."
|
|
555
|
+
([]
|
|
556
|
+
(fn [rf]
|
|
557
|
+
(let [pv (volatile! ::none)]
|
|
558
|
+
(fn
|
|
559
|
+
([] (rf))
|
|
560
|
+
([result] (rf result))
|
|
561
|
+
([result input]
|
|
562
|
+
(let [prior @pv]
|
|
563
|
+
(vreset! pv input)
|
|
564
|
+
(if (= prior input)
|
|
565
|
+
result
|
|
566
|
+
(rf result input))))))))
|
|
567
|
+
([coll]
|
|
568
|
+
(sequence (dedupe) coll)))
|
|
569
|
+
|
|
570
|
+
;; partition-all: stateful transducer; groups items into vectors of size n
|
|
571
|
+
(defn partition-all
|
|
572
|
+
"Returns a sequence of lists like partition, but may include
|
|
573
|
+
partitions with fewer than n items at the end. Returns a stateful
|
|
574
|
+
transducer when no collection is provided."
|
|
575
|
+
([n]
|
|
576
|
+
(fn [rf]
|
|
577
|
+
(let [buf (volatile! [])]
|
|
578
|
+
(fn
|
|
579
|
+
([] (rf))
|
|
580
|
+
([result]
|
|
581
|
+
(let [b @buf]
|
|
582
|
+
(vreset! buf [])
|
|
583
|
+
(if (empty? b)
|
|
584
|
+
(rf result)
|
|
585
|
+
(rf (unreduced (rf result b))))))
|
|
586
|
+
([result input]
|
|
587
|
+
(let [nb (conj @buf input)]
|
|
588
|
+
(if (= (count nb) n)
|
|
589
|
+
(do
|
|
590
|
+
(vreset! buf [])
|
|
591
|
+
(rf result nb))
|
|
592
|
+
(do
|
|
593
|
+
(vreset! buf nb)
|
|
594
|
+
result))))))))
|
|
595
|
+
([n coll]
|
|
596
|
+
(sequence (partition-all n) coll)))
|
|
597
|
+
|
|
598
|
+
;; ── Documentation ────────────────────────────────────────────────────────────
|
|
599
|
+
|
|
600
|
+
(defmacro doc [sym]
|
|
601
|
+
`(let [v# ~sym
|
|
602
|
+
m# (meta v#)
|
|
603
|
+
d# (:doc m#)
|
|
604
|
+
args# (:arglists m#)
|
|
605
|
+
args-str# (when args#
|
|
606
|
+
(reduce
|
|
607
|
+
(fn [acc# a#]
|
|
608
|
+
(if (= acc# "")
|
|
609
|
+
(str "(" a# ")")
|
|
610
|
+
(str acc# "\n" "(" a# ")")))
|
|
611
|
+
""
|
|
612
|
+
args#))]
|
|
613
|
+
(println (str (if args-str# (str args-str# "\n\n") "")
|
|
614
|
+
(or d# "No documentation available.")))))
|
|
615
|
+
|
|
616
|
+
(defn err
|
|
617
|
+
"Creates an error map with type, message, data and optionally cause"
|
|
618
|
+
([type message] (err type message nil nil))
|
|
619
|
+
([type message data] (err type message data nil))
|
|
620
|
+
([type message data cause] {:type type :message message :data data :cause cause}))
|