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