conjure-js 0.0.11 → 0.0.13
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/dist-cli/conjure-js.mjs +9336 -5028
- package/dist-vite-plugin/index.mjs +10455 -0
- package/package.json +9 -2
- package/src/bin/cli.ts +2 -2
- package/src/bin/nrepl-symbol.ts +150 -0
- package/src/bin/nrepl.ts +301 -157
- package/src/bin/version.ts +1 -1
- package/src/clojure/core.clj +764 -29
- package/src/clojure/core.clj.d.ts +76 -4
- package/src/clojure/demo/math.clj +5 -1
- package/src/clojure/generated/builtin-namespace-registry.ts +4 -0
- package/src/clojure/generated/clojure-core-source.ts +765 -29
- package/src/clojure/generated/clojure-set-source.ts +136 -0
- package/src/clojure/generated/clojure-walk-source.ts +72 -0
- package/src/clojure/set.clj +132 -0
- package/src/clojure/set.clj.d.ts +20 -0
- package/src/clojure/string.clj.d.ts +14 -0
- package/src/clojure/walk.clj +68 -0
- package/src/clojure/walk.clj.d.ts +7 -0
- package/src/core/assertions.ts +114 -6
- package/src/core/bootstrap.ts +337 -0
- package/src/core/conversions.ts +48 -31
- package/src/core/core-module.ts +303 -0
- package/src/core/env.ts +42 -7
- package/src/core/errors.ts +8 -0
- package/src/core/evaluator/apply.ts +40 -25
- package/src/core/evaluator/arity.ts +8 -8
- package/src/core/evaluator/async-evaluator.ts +565 -0
- package/src/core/evaluator/collections.ts +30 -4
- package/src/core/evaluator/destructure.ts +180 -69
- package/src/core/evaluator/dispatch.ts +24 -14
- package/src/core/evaluator/evaluate.ts +22 -20
- package/src/core/evaluator/expand.ts +45 -15
- package/src/core/evaluator/form-parsers.ts +178 -0
- package/src/core/evaluator/index.ts +7 -9
- package/src/core/evaluator/js-interop.ts +189 -0
- package/src/core/evaluator/quasiquote.ts +14 -8
- package/src/core/evaluator/recur-check.ts +6 -6
- package/src/core/evaluator/special-forms.ts +380 -173
- package/src/core/factories.ts +182 -3
- package/src/core/index.ts +55 -5
- package/src/core/module.ts +136 -0
- package/src/core/ns-forms.ts +107 -0
- package/src/core/positions.ts +9 -2
- package/src/core/printer.ts +371 -11
- package/src/core/reader.ts +127 -29
- package/src/core/registry.ts +209 -0
- package/src/core/runtime.ts +376 -0
- package/src/core/session.ts +263 -478
- package/src/core/stdlib/arithmetic.ts +516 -215
- package/src/core/stdlib/async-fns.ts +132 -0
- package/src/core/stdlib/atoms.ts +286 -63
- package/src/core/stdlib/errors.ts +54 -50
- package/src/core/stdlib/hof.ts +74 -173
- package/src/core/stdlib/js-namespace.ts +344 -0
- package/src/core/stdlib/lazy.ts +34 -0
- package/src/core/stdlib/maps-sets.ts +322 -0
- package/src/core/stdlib/meta.ts +109 -28
- package/src/core/stdlib/predicates.ts +322 -196
- package/src/core/stdlib/regex.ts +126 -98
- package/src/core/stdlib/seq.ts +564 -0
- package/src/core/stdlib/strings.ts +164 -135
- package/src/core/stdlib/transducers.ts +95 -100
- package/src/core/stdlib/utils.ts +283 -147
- package/src/core/stdlib/vars.ts +27 -27
- package/src/core/stdlib/vectors.ts +122 -0
- package/src/core/tokenizer.ts +13 -3
- package/src/core/transformations.ts +117 -9
- package/src/core/types.ts +118 -6
- package/src/host/node-host-module.ts +74 -0
- package/src/nrepl/relay.ts +432 -0
- package/src/vite-plugin-clj/codegen.ts +87 -95
- package/src/vite-plugin-clj/index.ts +242 -18
- package/src/vite-plugin-clj/namespace-utils.ts +39 -0
- package/src/vite-plugin-clj/static-analysis.ts +211 -0
- package/src/clojure/demo.clj +0 -63
- package/src/clojure/demo.clj.d.ts +0 -0
- package/src/core/core-env.ts +0 -60
- package/src/core/stdlib/collections.ts +0 -784
- package/src/host/node.ts +0 -55
package/src/clojure/core.clj
CHANGED
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
(ns clojure.core)
|
|
2
2
|
|
|
3
|
+
;; Host shims, for autocomplete only
|
|
4
|
+
(def all)
|
|
5
|
+
(def async)
|
|
6
|
+
(def catch*)
|
|
7
|
+
(def then)
|
|
8
|
+
|
|
3
9
|
(defmacro defn [name & fdecl]
|
|
4
10
|
(let [doc (if (string? (first fdecl)) (first fdecl) nil)
|
|
5
11
|
rest-decl (if doc (rest fdecl) fdecl)
|
|
6
12
|
arglists (if (vector? (first rest-decl))
|
|
7
13
|
(vector (first rest-decl))
|
|
8
|
-
(reduce (fn [acc arity] (conj acc (first arity))) [] rest-decl))
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
(reduce (fn [acc arity] (conj acc (first arity))) [] rest-decl))
|
|
15
|
+
meta-map (let [m (if doc {:doc doc :arglists arglists} {:arglists arglists})]
|
|
16
|
+
(if (:private (meta name)) (assoc m :private true) m))]
|
|
17
|
+
`(def ~(with-meta name meta-map) (fn ~@rest-decl))))
|
|
18
|
+
|
|
19
|
+
(defmacro defn-
|
|
20
|
+
"Same as defn, but marks the var as private."
|
|
21
|
+
[name & fdecl]
|
|
22
|
+
(list* 'defn (with-meta name (assoc (meta name) :private true)) fdecl))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
(defn vary-meta
|
|
26
|
+
"Returns an object of the same type and value as obj, with
|
|
27
|
+
(apply f (meta obj) args) as its metadata."
|
|
28
|
+
[obj f & args]
|
|
29
|
+
(with-meta obj (apply f (meta obj) args)))
|
|
12
30
|
|
|
13
31
|
(defn next
|
|
14
32
|
"Returns a seq of the items after the first. Calls seq on its
|
|
@@ -26,10 +44,14 @@
|
|
|
26
44
|
(first (next coll)))
|
|
27
45
|
|
|
28
46
|
|
|
29
|
-
(defmacro when
|
|
47
|
+
(defmacro when
|
|
48
|
+
"Executes body when condition is true, otherwise returns nil."
|
|
49
|
+
[condition & body]
|
|
30
50
|
`(if ~condition (do ~@body) nil))
|
|
31
51
|
|
|
32
|
-
(defmacro when-not
|
|
52
|
+
(defmacro when-not
|
|
53
|
+
"Executes body when condition is false, otherwise returns nil."
|
|
54
|
+
[condition & body]
|
|
33
55
|
`(if ~condition nil (do ~@body)))
|
|
34
56
|
|
|
35
57
|
(defmacro if-let
|
|
@@ -90,9 +112,67 @@
|
|
|
90
112
|
`(->> ~threaded ~@more))))
|
|
91
113
|
|
|
92
114
|
(defmacro comment
|
|
93
|
-
|
|
115
|
+
"Ignores body, yields nil"
|
|
94
116
|
[& body])
|
|
95
117
|
|
|
118
|
+
(defmacro as->
|
|
119
|
+
[expr name & forms]
|
|
120
|
+
`(let [~name ~expr
|
|
121
|
+
~@(reduce (fn [acc form] (conj acc name form)) [] forms)]
|
|
122
|
+
~name))
|
|
123
|
+
|
|
124
|
+
(defmacro cond->
|
|
125
|
+
[expr & clauses]
|
|
126
|
+
(let [g (gensym "cv")
|
|
127
|
+
steps (reduce
|
|
128
|
+
(fn [acc pair]
|
|
129
|
+
(let [test (first pair)
|
|
130
|
+
form (second pair)
|
|
131
|
+
threaded (if (list? form)
|
|
132
|
+
`(~(first form) ~g ~@(rest form))
|
|
133
|
+
`(~form ~g))]
|
|
134
|
+
(conj acc `(if ~test ~threaded ~g))))
|
|
135
|
+
[]
|
|
136
|
+
(partition-all 2 clauses))]
|
|
137
|
+
`(let [~g ~expr
|
|
138
|
+
~@(reduce (fn [acc step] (conj acc g step)) [] steps)]
|
|
139
|
+
~g)))
|
|
140
|
+
|
|
141
|
+
(defmacro cond->>
|
|
142
|
+
[expr & clauses]
|
|
143
|
+
(let [g (gensym "cv")
|
|
144
|
+
steps (reduce
|
|
145
|
+
(fn [acc pair]
|
|
146
|
+
(let [test (first pair)
|
|
147
|
+
form (second pair)
|
|
148
|
+
threaded (if (list? form)
|
|
149
|
+
`(~(first form) ~@(rest form) ~g)
|
|
150
|
+
`(~form ~g))]
|
|
151
|
+
(conj acc `(if ~test ~threaded ~g))))
|
|
152
|
+
[]
|
|
153
|
+
(partition-all 2 clauses))]
|
|
154
|
+
`(let [~g ~expr
|
|
155
|
+
~@(reduce (fn [acc step] (conj acc g step)) [] steps)]
|
|
156
|
+
~g)))
|
|
157
|
+
|
|
158
|
+
(defmacro some->
|
|
159
|
+
[expr & forms]
|
|
160
|
+
(if (nil? forms)
|
|
161
|
+
expr
|
|
162
|
+
`(let [v# ~expr]
|
|
163
|
+
(if (nil? v#)
|
|
164
|
+
nil
|
|
165
|
+
(some-> (-> v# ~(first forms)) ~@(rest forms))))))
|
|
166
|
+
|
|
167
|
+
(defmacro some->>
|
|
168
|
+
[expr & forms]
|
|
169
|
+
(if (nil? forms)
|
|
170
|
+
expr
|
|
171
|
+
`(let [v# ~expr]
|
|
172
|
+
(if (nil? v#)
|
|
173
|
+
nil
|
|
174
|
+
(some->> (->> v# ~(first forms)) ~@(rest forms))))))
|
|
175
|
+
|
|
96
176
|
(defn constantly
|
|
97
177
|
"Returns a function that takes any number of arguments and returns x."
|
|
98
178
|
[x] (fn [& _] x))
|
|
@@ -390,7 +470,9 @@
|
|
|
390
470
|
([result] (rf result))
|
|
391
471
|
([result input] (rf result (f input))))))
|
|
392
472
|
([f coll]
|
|
393
|
-
(
|
|
473
|
+
(lazy-seq
|
|
474
|
+
(when-let [s (seq coll)]
|
|
475
|
+
(cons (f (first s)) (map f (rest s))))))
|
|
394
476
|
([f c1 c2]
|
|
395
477
|
(loop [s1 (seq c1)
|
|
396
478
|
s2 (seq c2)
|
|
@@ -423,7 +505,11 @@
|
|
|
423
505
|
(rf result input)
|
|
424
506
|
result)))))
|
|
425
507
|
([pred coll]
|
|
426
|
-
(
|
|
508
|
+
(lazy-seq
|
|
509
|
+
(when-let [s (seq coll)]
|
|
510
|
+
(if (pred (first s))
|
|
511
|
+
(cons (first s) (filter pred (rest s)))
|
|
512
|
+
(filter pred (rest s)))))))
|
|
427
513
|
|
|
428
514
|
(defn remove
|
|
429
515
|
"Returns a lazy sequence of the items in coll for which
|
|
@@ -457,7 +543,10 @@
|
|
|
457
543
|
(ensure-reduced result)
|
|
458
544
|
result)))))))
|
|
459
545
|
([n coll]
|
|
460
|
-
(
|
|
546
|
+
(lazy-seq
|
|
547
|
+
(when (pos? n)
|
|
548
|
+
(when-let [s (seq coll)]
|
|
549
|
+
(cons (first s) (take (dec n) (rest s))))))))
|
|
461
550
|
|
|
462
551
|
;; take-while: stateless transducer; emits reduced when pred fails
|
|
463
552
|
(defn take-while
|
|
@@ -474,7 +563,10 @@
|
|
|
474
563
|
(rf result input)
|
|
475
564
|
(reduced result))))))
|
|
476
565
|
([pred coll]
|
|
477
|
-
(
|
|
566
|
+
(lazy-seq
|
|
567
|
+
(when-let [s (seq coll)]
|
|
568
|
+
(when (pred (first s))
|
|
569
|
+
(cons (first s) (take-while pred (rest s))))))))
|
|
478
570
|
|
|
479
571
|
;; drop: stateful transducer; skips first n items
|
|
480
572
|
;; r >= 0 → still skipping; r < 0 → past the drop zone, start taking
|
|
@@ -494,7 +586,9 @@
|
|
|
494
586
|
result
|
|
495
587
|
(rf result input))))))))
|
|
496
588
|
([n coll]
|
|
497
|
-
(
|
|
589
|
+
(if (pos? n)
|
|
590
|
+
(lazy-seq (drop (dec n) (rest coll)))
|
|
591
|
+
(lazy-seq (seq coll)))))
|
|
498
592
|
|
|
499
593
|
(defn drop-last
|
|
500
594
|
"Return a sequence of all but the last n (default 1) items in coll"
|
|
@@ -528,7 +622,11 @@
|
|
|
528
622
|
(vreset! dropping false)
|
|
529
623
|
(rf result input))))))))
|
|
530
624
|
([pred coll]
|
|
531
|
-
(
|
|
625
|
+
(lazy-seq
|
|
626
|
+
(let [s (seq coll)]
|
|
627
|
+
(if (and s (pred (first s)))
|
|
628
|
+
(drop-while pred (rest s))
|
|
629
|
+
s)))))
|
|
532
630
|
|
|
533
631
|
;; map-indexed: stateful transducer; passes index and item to f
|
|
534
632
|
(defn map-indexed
|
|
@@ -546,7 +644,11 @@
|
|
|
546
644
|
([result input]
|
|
547
645
|
(rf result (f (vswap! i inc) input)))))))
|
|
548
646
|
([f coll]
|
|
549
|
-
(
|
|
647
|
+
(letfn [(step [i s]
|
|
648
|
+
(lazy-seq
|
|
649
|
+
(when-let [xs (seq s)]
|
|
650
|
+
(cons (f i (first xs)) (step (inc i) (rest xs))))))]
|
|
651
|
+
(step 0 coll))))
|
|
550
652
|
|
|
551
653
|
;; dedupe: stateful transducer; removes consecutive duplicates
|
|
552
654
|
(defn dedupe
|
|
@@ -598,23 +700,656 @@
|
|
|
598
700
|
;; ── Documentation ────────────────────────────────────────────────────────────
|
|
599
701
|
|
|
600
702
|
(defmacro doc [sym]
|
|
601
|
-
`(let [v# ~sym
|
|
703
|
+
`(let [v# (var ~sym)
|
|
602
704
|
m# (meta v#)
|
|
603
705
|
d# (:doc m#)
|
|
604
706
|
args# (:arglists m#)
|
|
605
707
|
args-str# (when args#
|
|
606
|
-
(
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
(
|
|
708
|
+
(str "("
|
|
709
|
+
(reduce
|
|
710
|
+
(fn [acc# a#]
|
|
711
|
+
(if (= acc# "")
|
|
712
|
+
(str a#)
|
|
713
|
+
(str acc# " \n " a#)))
|
|
714
|
+
""
|
|
715
|
+
args#)
|
|
716
|
+
")"))]
|
|
717
|
+
(println (str "-------------------------\n"
|
|
718
|
+
~(str sym) "\n"
|
|
719
|
+
(if args-str# (str args-str# "\n") "")
|
|
720
|
+
" " (or d# "No documentation available.")))))
|
|
721
|
+
|
|
722
|
+
(defn make-err
|
|
617
723
|
"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}))
|
|
724
|
+
([type message] (make-err type message nil nil))
|
|
725
|
+
([type message data] (make-err type message data nil))
|
|
726
|
+
([type message data cause] {:type type :message message :data data :cause cause}))
|
|
727
|
+
|
|
728
|
+
;; ── Sequence utilities ──────────────────────────────────────────────────────
|
|
729
|
+
|
|
730
|
+
(defn butlast
|
|
731
|
+
"Return a seq of all but the last item in coll, in linear time"
|
|
732
|
+
[coll]
|
|
733
|
+
(loop [ret [] s (seq coll)]
|
|
734
|
+
(if (next s)
|
|
735
|
+
(recur (conj ret (first s)) (next s))
|
|
736
|
+
(seq ret))))
|
|
737
|
+
|
|
738
|
+
(defn fnext
|
|
739
|
+
"Same as (first (next x))"
|
|
740
|
+
[x] (first (next x)))
|
|
741
|
+
|
|
742
|
+
(defn nfirst
|
|
743
|
+
"Same as (next (first x))"
|
|
744
|
+
[x] (next (first x)))
|
|
745
|
+
|
|
746
|
+
(defn nnext
|
|
747
|
+
"Same as (next (next x))"
|
|
748
|
+
[x] (next (next x)))
|
|
749
|
+
|
|
750
|
+
(defn nthrest
|
|
751
|
+
"Returns the nth rest of coll, coll when n is 0."
|
|
752
|
+
[coll n]
|
|
753
|
+
(loop [n n xs coll]
|
|
754
|
+
(if (and (pos? n) (seq xs))
|
|
755
|
+
(recur (dec n) (rest xs))
|
|
756
|
+
xs)))
|
|
757
|
+
|
|
758
|
+
(defn nthnext
|
|
759
|
+
"Returns the nth next of coll, (seq coll) when n is 0."
|
|
760
|
+
[coll n]
|
|
761
|
+
(loop [n n xs (seq coll)]
|
|
762
|
+
(if (and (pos? n) xs)
|
|
763
|
+
(recur (dec n) (next xs))
|
|
764
|
+
xs)))
|
|
765
|
+
|
|
766
|
+
(defn list*
|
|
767
|
+
"Creates a new seq containing the items prepended to the rest, the
|
|
768
|
+
last of which will be treated as a sequence."
|
|
769
|
+
([args] (seq args))
|
|
770
|
+
([a args] (cons a args))
|
|
771
|
+
([a b args] (cons a (cons b args)))
|
|
772
|
+
([a b c args] (cons a (cons b (cons c args))))
|
|
773
|
+
([a b c d & more]
|
|
774
|
+
(cons a (cons b (cons c (apply list* d more))))))
|
|
775
|
+
|
|
776
|
+
(defn mapv
|
|
777
|
+
"Returns a vector consisting of the result of applying f to the
|
|
778
|
+
set of first items of each coll, followed by applying f to the set
|
|
779
|
+
of second items in each coll, until any one of the colls is exhausted."
|
|
780
|
+
([f coll] (into [] (map f) coll))
|
|
781
|
+
([f c1 c2] (into [] (map f c1 c2)))
|
|
782
|
+
([f c1 c2 c3] (into [] (map f c1 c2 c3)))
|
|
783
|
+
([f c1 c2 c3 & colls] (into [] (apply map f c1 c2 c3 colls))))
|
|
784
|
+
|
|
785
|
+
(defn filterv
|
|
786
|
+
"Returns a vector of the items in coll for which
|
|
787
|
+
(pred item) returns logical true."
|
|
788
|
+
[pred coll]
|
|
789
|
+
(into [] (filter pred) coll))
|
|
790
|
+
|
|
791
|
+
(defn run!
|
|
792
|
+
"Runs the supplied procedure (via reduce), for purposes of side
|
|
793
|
+
effects, on successive items in the collection. Returns nil."
|
|
794
|
+
[proc coll]
|
|
795
|
+
(reduce (fn [_ x] (proc x) nil) nil coll))
|
|
796
|
+
|
|
797
|
+
(defn keep
|
|
798
|
+
"Returns a sequence of the non-nil results of (f item). Note,
|
|
799
|
+
this means false return values will be included. f must be free of
|
|
800
|
+
side-effects. Returns a transducer when no collection is provided."
|
|
801
|
+
([f]
|
|
802
|
+
(fn [rf]
|
|
803
|
+
(fn
|
|
804
|
+
([] (rf))
|
|
805
|
+
([result] (rf result))
|
|
806
|
+
([result input]
|
|
807
|
+
(let [v (f input)]
|
|
808
|
+
(if (nil? v)
|
|
809
|
+
result
|
|
810
|
+
(rf result v)))))))
|
|
811
|
+
([f coll]
|
|
812
|
+
(lazy-seq
|
|
813
|
+
(when-let [s (seq coll)]
|
|
814
|
+
(let [v (f (first s))]
|
|
815
|
+
(if (nil? v)
|
|
816
|
+
(keep f (rest s))
|
|
817
|
+
(cons v (keep f (rest s)))))))))
|
|
818
|
+
|
|
819
|
+
(defn keep-indexed
|
|
820
|
+
"Returns a sequence of the non-nil results of (f index item). Note,
|
|
821
|
+
this means false return values will be included. f must be free of
|
|
822
|
+
side-effects. Returns a stateful transducer when no collection is provided."
|
|
823
|
+
([f]
|
|
824
|
+
(fn [rf]
|
|
825
|
+
(let [i (volatile! -1)]
|
|
826
|
+
(fn
|
|
827
|
+
([] (rf))
|
|
828
|
+
([result] (rf result))
|
|
829
|
+
([result input]
|
|
830
|
+
(let [v (f (vswap! i inc) input)]
|
|
831
|
+
(if (nil? v)
|
|
832
|
+
result
|
|
833
|
+
(rf result v))))))))
|
|
834
|
+
([f coll]
|
|
835
|
+
(letfn [(step [i s]
|
|
836
|
+
(lazy-seq
|
|
837
|
+
(when-let [xs (seq s)]
|
|
838
|
+
(let [v (f i (first xs))]
|
|
839
|
+
(if (nil? v)
|
|
840
|
+
(step (inc i) (rest xs))
|
|
841
|
+
(cons v (step (inc i) (rest xs))))))))]
|
|
842
|
+
(step 0 coll))))
|
|
843
|
+
|
|
844
|
+
(defn mapcat
|
|
845
|
+
"Returns the result of applying concat to the result of applying map
|
|
846
|
+
to f and colls. Thus function f should return a collection. Returns
|
|
847
|
+
a transducer when no collections are provided."
|
|
848
|
+
([f]
|
|
849
|
+
(fn [rf]
|
|
850
|
+
(let [inner ((map f) (fn
|
|
851
|
+
([] (rf))
|
|
852
|
+
([result] (rf result))
|
|
853
|
+
([result input]
|
|
854
|
+
(reduce rf result input))))]
|
|
855
|
+
inner)))
|
|
856
|
+
([f coll]
|
|
857
|
+
(lazy-seq
|
|
858
|
+
(when-let [s (seq coll)]
|
|
859
|
+
(concat (f (first s)) (mapcat f (rest s))))))
|
|
860
|
+
([f coll & more]
|
|
861
|
+
(apply concat (apply map f coll more))))
|
|
862
|
+
|
|
863
|
+
(defn interleave
|
|
864
|
+
"Returns a lazy sequence of the first item in each coll, then the second etc.
|
|
865
|
+
Stops as soon as any coll is exhausted."
|
|
866
|
+
([c1 c2]
|
|
867
|
+
(lazy-seq
|
|
868
|
+
(let [s1 (seq c1) s2 (seq c2)]
|
|
869
|
+
(when (and s1 s2)
|
|
870
|
+
(cons (first s1) (cons (first s2) (interleave (rest s1) (rest s2))))))))
|
|
871
|
+
([c1 c2 & colls]
|
|
872
|
+
(lazy-seq
|
|
873
|
+
(let [seqs (map seq (cons c1 (cons c2 colls)))]
|
|
874
|
+
(when (every? some? seqs)
|
|
875
|
+
(concat (map first seqs) (apply interleave (map rest seqs))))))))
|
|
876
|
+
|
|
877
|
+
(defn interpose
|
|
878
|
+
"Returns a sequence of the elements of coll separated by sep.
|
|
879
|
+
Returns a transducer when no collection is provided."
|
|
880
|
+
([sep]
|
|
881
|
+
(fn [rf]
|
|
882
|
+
(let [started (volatile! false)]
|
|
883
|
+
(fn
|
|
884
|
+
([] (rf))
|
|
885
|
+
([result] (rf result))
|
|
886
|
+
([result input]
|
|
887
|
+
(if @started
|
|
888
|
+
(let [sepr (rf result sep)]
|
|
889
|
+
(if (reduced? sepr)
|
|
890
|
+
sepr
|
|
891
|
+
(rf sepr input)))
|
|
892
|
+
(do
|
|
893
|
+
(vreset! started true)
|
|
894
|
+
(rf result input))))))))
|
|
895
|
+
([sep coll]
|
|
896
|
+
(drop 1 (interleave (repeat sep) coll))))
|
|
897
|
+
|
|
898
|
+
;; ── Lazy concat (shadows native eager concat) ──────────────────────────────
|
|
899
|
+
(defn concat
|
|
900
|
+
"Returns a lazy seq representing the concatenation of the elements in the
|
|
901
|
+
supplied colls."
|
|
902
|
+
([] nil)
|
|
903
|
+
([x] (lazy-seq (seq x)))
|
|
904
|
+
([x y]
|
|
905
|
+
(lazy-seq
|
|
906
|
+
(let [s (seq x)]
|
|
907
|
+
(if s
|
|
908
|
+
(cons (first s) (concat (rest s) y))
|
|
909
|
+
(seq y)))))
|
|
910
|
+
([x y & zs]
|
|
911
|
+
(let [cat (fn cat [xy zs]
|
|
912
|
+
(lazy-seq
|
|
913
|
+
(let [xys (seq xy)]
|
|
914
|
+
(if xys
|
|
915
|
+
(cons (first xys) (cat (rest xys) zs))
|
|
916
|
+
(when (seq zs)
|
|
917
|
+
(cat (first zs) (next zs)))))))]
|
|
918
|
+
(cat (concat x y) zs))))
|
|
919
|
+
|
|
920
|
+
(defn iterate
|
|
921
|
+
"Returns a lazy sequence of x, (f x), (f (f x)) etc.
|
|
922
|
+
With 3 args, returns a finite sequence of n items (backwards compat)."
|
|
923
|
+
([f x]
|
|
924
|
+
(lazy-seq (cons x (iterate f (f x)))))
|
|
925
|
+
([f x n]
|
|
926
|
+
(loop [i 0 v x acc []]
|
|
927
|
+
(if (< i n)
|
|
928
|
+
(recur (inc i) (f v) (conj acc v))
|
|
929
|
+
acc))))
|
|
930
|
+
|
|
931
|
+
(defn repeatedly
|
|
932
|
+
"Takes a function of no args, presumably with side effects, and
|
|
933
|
+
returns a lazy infinite sequence of calls to it.
|
|
934
|
+
With 2 args (n f), returns a finite sequence of n calls."
|
|
935
|
+
([f] (lazy-seq (cons (f) (repeatedly f))))
|
|
936
|
+
([n f]
|
|
937
|
+
(loop [i 0 acc []]
|
|
938
|
+
(if (< i n)
|
|
939
|
+
(recur (inc i) (conj acc (f)))
|
|
940
|
+
acc))))
|
|
941
|
+
|
|
942
|
+
(defn cycle
|
|
943
|
+
"Returns a lazy infinite sequence of repetitions of the items in coll.
|
|
944
|
+
With 2 args (n coll), returns a finite sequence (backwards compat)."
|
|
945
|
+
([coll]
|
|
946
|
+
(lazy-seq
|
|
947
|
+
(when (seq coll)
|
|
948
|
+
(concat coll (cycle coll)))))
|
|
949
|
+
([n coll]
|
|
950
|
+
(let [s (into [] coll)]
|
|
951
|
+
(loop [i 0 acc []]
|
|
952
|
+
(if (< i n)
|
|
953
|
+
(recur (inc i) (into acc s))
|
|
954
|
+
acc)))))
|
|
955
|
+
|
|
956
|
+
(defn repeat
|
|
957
|
+
"Returns a lazy infinite sequence of xs.
|
|
958
|
+
With 2 args (n x), returns a finite sequence of n copies."
|
|
959
|
+
([x] (lazy-seq (cons x (repeat x))))
|
|
960
|
+
([n x] (repeat* n x)))
|
|
961
|
+
|
|
962
|
+
(defn range
|
|
963
|
+
"Returns a lazy infinite sequence of integers from 0.
|
|
964
|
+
With args, returns a finite sequence (delegates to native range*)."
|
|
965
|
+
([] (iterate inc 0))
|
|
966
|
+
([end] (range* end))
|
|
967
|
+
([start end] (range* start end))
|
|
968
|
+
([start end step] (range* start end step)))
|
|
969
|
+
|
|
970
|
+
(defn newline
|
|
971
|
+
"Writes a newline to *out*."
|
|
972
|
+
[] (println ""))
|
|
973
|
+
|
|
974
|
+
(defn dorun
|
|
975
|
+
"Forces realization of a (possibly lazy) sequence. Walks the sequence
|
|
976
|
+
without retaining the head. Returns nil."
|
|
977
|
+
[coll]
|
|
978
|
+
(when (seq coll)
|
|
979
|
+
(recur (rest coll))))
|
|
980
|
+
|
|
981
|
+
(defn doall
|
|
982
|
+
"Forces realization of a (possibly lazy) sequence. Unlike dorun,
|
|
983
|
+
retains the head and returns the seq."
|
|
984
|
+
[coll]
|
|
985
|
+
(dorun coll)
|
|
986
|
+
coll)
|
|
987
|
+
|
|
988
|
+
(defn take-nth
|
|
989
|
+
"Returns a sequence of every nth item in coll. Returns a stateful
|
|
990
|
+
transducer when no collection is provided."
|
|
991
|
+
([n]
|
|
992
|
+
(fn [rf]
|
|
993
|
+
(let [i (volatile! -1)]
|
|
994
|
+
(fn
|
|
995
|
+
([] (rf))
|
|
996
|
+
([result] (rf result))
|
|
997
|
+
([result input]
|
|
998
|
+
(let [idx (vswap! i inc)]
|
|
999
|
+
(if (zero? (mod idx n))
|
|
1000
|
+
(rf result input)
|
|
1001
|
+
result)))))))
|
|
1002
|
+
([n coll]
|
|
1003
|
+
(sequence (take-nth n) coll)))
|
|
1004
|
+
|
|
1005
|
+
(defn partition
|
|
1006
|
+
"Returns a sequence of lists of n items each, at offsets step
|
|
1007
|
+
apart. If step is not supplied, defaults to n, i.e. the partitions
|
|
1008
|
+
do not overlap. If a pad collection is supplied, use its elements as
|
|
1009
|
+
necessary to complete last partition up to n items. In case there are
|
|
1010
|
+
not enough padding elements, return a partition with less than n items."
|
|
1011
|
+
([n coll] (partition n n coll))
|
|
1012
|
+
([n step coll]
|
|
1013
|
+
(loop [s (seq coll) acc []]
|
|
1014
|
+
(if (nil? s)
|
|
1015
|
+
acc
|
|
1016
|
+
(let [p (into [] (take n) s)]
|
|
1017
|
+
(if (< (count p) n)
|
|
1018
|
+
acc
|
|
1019
|
+
(recur (seq (drop step s)) (conj acc p)))))))
|
|
1020
|
+
([n step pad coll]
|
|
1021
|
+
(loop [s (seq coll) acc []]
|
|
1022
|
+
(if (nil? s)
|
|
1023
|
+
acc
|
|
1024
|
+
(let [p (into [] (take n) s)]
|
|
1025
|
+
(if (< (count p) n)
|
|
1026
|
+
(conj acc (into [] (take n) (concat p pad)))
|
|
1027
|
+
(recur (seq (drop step s)) (conj acc p))))))))
|
|
1028
|
+
|
|
1029
|
+
(defn partition-by
|
|
1030
|
+
"Applies f to each value in coll, splitting it each time f returns a
|
|
1031
|
+
new value. Returns a sequence of partitions. Returns a stateful
|
|
1032
|
+
transducer when no collection is provided."
|
|
1033
|
+
([f]
|
|
1034
|
+
(fn [rf]
|
|
1035
|
+
(let [pv (volatile! ::none)
|
|
1036
|
+
buf (volatile! [])]
|
|
1037
|
+
(fn
|
|
1038
|
+
([] (rf))
|
|
1039
|
+
([result]
|
|
1040
|
+
(let [b @buf]
|
|
1041
|
+
(vreset! buf [])
|
|
1042
|
+
(if (empty? b)
|
|
1043
|
+
(rf result)
|
|
1044
|
+
(rf (unreduced (rf result b))))))
|
|
1045
|
+
([result input]
|
|
1046
|
+
(let [v (f input)
|
|
1047
|
+
p @pv]
|
|
1048
|
+
(vreset! pv v)
|
|
1049
|
+
(if (or (= p ::none) (= v p))
|
|
1050
|
+
(do (vswap! buf conj input) result)
|
|
1051
|
+
(let [b @buf]
|
|
1052
|
+
(vreset! buf [input])
|
|
1053
|
+
(rf result b)))))))))
|
|
1054
|
+
([f coll]
|
|
1055
|
+
(lazy-seq
|
|
1056
|
+
(when-let [s (seq coll)]
|
|
1057
|
+
(let [fv (f (first s))
|
|
1058
|
+
run (into [] (cons (first s) (take-while #(= (f %) fv) (next s))))
|
|
1059
|
+
remaining (drop-while #(= (f %) fv) (next s))]
|
|
1060
|
+
(cons run (partition-by f remaining)))))))
|
|
1061
|
+
|
|
1062
|
+
(defn reductions
|
|
1063
|
+
"Returns a sequence of the intermediate values of the reduction (as
|
|
1064
|
+
by reduce) of coll by f, starting with init."
|
|
1065
|
+
([f coll]
|
|
1066
|
+
(if (empty? coll)
|
|
1067
|
+
(list (f))
|
|
1068
|
+
(reductions f (first coll) (rest coll))))
|
|
1069
|
+
([f init coll]
|
|
1070
|
+
(loop [acc [init] val init s (seq coll)]
|
|
1071
|
+
(if (nil? s)
|
|
1072
|
+
acc
|
|
1073
|
+
(let [nval (f val (first s))]
|
|
1074
|
+
(if (reduced? nval)
|
|
1075
|
+
(conj acc (unreduced nval))
|
|
1076
|
+
(recur (conj acc nval) nval (next s))))))))
|
|
1077
|
+
|
|
1078
|
+
(defn split-at
|
|
1079
|
+
"Returns a vector of [(take n coll) (drop n coll)]"
|
|
1080
|
+
[n coll]
|
|
1081
|
+
[(into [] (take n) coll) (into [] (drop n) coll)])
|
|
1082
|
+
|
|
1083
|
+
(defn split-with
|
|
1084
|
+
"Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
|
|
1085
|
+
[pred coll]
|
|
1086
|
+
[(into [] (take-while pred) coll) (into [] (drop-while pred) coll)])
|
|
1087
|
+
|
|
1088
|
+
(defn merge-with
|
|
1089
|
+
"Returns a map that consists of the rest of the maps conj-ed onto
|
|
1090
|
+
the first. If a key occurs in more than one map, the mapping(s)
|
|
1091
|
+
from the latter (left-to-right) will be combined with the mapping in
|
|
1092
|
+
the result by calling (f val-in-result val-in-latter)."
|
|
1093
|
+
[f & maps]
|
|
1094
|
+
(reduce
|
|
1095
|
+
(fn [acc m]
|
|
1096
|
+
(if (nil? m)
|
|
1097
|
+
acc
|
|
1098
|
+
(reduce
|
|
1099
|
+
(fn [macc entry]
|
|
1100
|
+
(let [k (first entry)
|
|
1101
|
+
v (second entry)]
|
|
1102
|
+
(if (contains? macc k)
|
|
1103
|
+
(assoc macc k (f (get macc k) v))
|
|
1104
|
+
(assoc macc k v))))
|
|
1105
|
+
(or acc {})
|
|
1106
|
+
m)))
|
|
1107
|
+
nil
|
|
1108
|
+
maps))
|
|
1109
|
+
|
|
1110
|
+
(defn update-keys
|
|
1111
|
+
"m f => apply f to each key in m"
|
|
1112
|
+
[m f]
|
|
1113
|
+
(reduce
|
|
1114
|
+
(fn [acc entry]
|
|
1115
|
+
(assoc acc (f (first entry)) (second entry)))
|
|
1116
|
+
{}
|
|
1117
|
+
m))
|
|
1118
|
+
|
|
1119
|
+
(defn update-vals
|
|
1120
|
+
"m f => apply f to each val in m"
|
|
1121
|
+
[m f]
|
|
1122
|
+
(reduce
|
|
1123
|
+
(fn [acc entry]
|
|
1124
|
+
(assoc acc (first entry) (f (second entry))))
|
|
1125
|
+
{}
|
|
1126
|
+
m))
|
|
1127
|
+
|
|
1128
|
+
(defn not-empty
|
|
1129
|
+
"If coll is empty, returns nil, else coll"
|
|
1130
|
+
[coll]
|
|
1131
|
+
(when (seq coll) coll))
|
|
1132
|
+
|
|
1133
|
+
(defn memoize
|
|
1134
|
+
"Returns a memoized version of a referentially transparent function. The
|
|
1135
|
+
memoized version of the function keeps a cache of the mapping from arguments
|
|
1136
|
+
to results and, when calls with the same arguments are repeated often, has
|
|
1137
|
+
higher performance at the expense of higher memory use."
|
|
1138
|
+
[f]
|
|
1139
|
+
(let [mem (atom {})]
|
|
1140
|
+
(fn [& args]
|
|
1141
|
+
(let [cached (get @mem args ::not-found)]
|
|
1142
|
+
(if (= cached ::not-found)
|
|
1143
|
+
(let [ret (apply f args)]
|
|
1144
|
+
(swap! mem assoc args ret)
|
|
1145
|
+
ret)
|
|
1146
|
+
cached)))))
|
|
1147
|
+
|
|
1148
|
+
(defn trampoline
|
|
1149
|
+
"trampoline can be used to convert algorithms requiring mutual
|
|
1150
|
+
recursion without stack consumption. Calls f with supplied args, if
|
|
1151
|
+
any. If f returns a fn, calls that fn with no arguments, and
|
|
1152
|
+
continues to repeat, until the return value is not a fn, then
|
|
1153
|
+
returns that non-fn value."
|
|
1154
|
+
([f]
|
|
1155
|
+
(loop [ret (f)]
|
|
1156
|
+
(if (fn? ret)
|
|
1157
|
+
(recur (ret))
|
|
1158
|
+
ret)))
|
|
1159
|
+
([f & args]
|
|
1160
|
+
(loop [ret (apply f args)]
|
|
1161
|
+
(if (fn? ret)
|
|
1162
|
+
(recur (ret))
|
|
1163
|
+
ret))))
|
|
1164
|
+
|
|
1165
|
+
(defmacro with-redefs
|
|
1166
|
+
"binding => var-symbol temp-value-expr
|
|
1167
|
+
Temporarily redefines Vars while executing the body. The
|
|
1168
|
+
temp-value-exprs will be evaluated and each resulting value will
|
|
1169
|
+
replace in parallel the root value of its Var. Always restores
|
|
1170
|
+
the original values, even if body throws."
|
|
1171
|
+
[bindings & body]
|
|
1172
|
+
(let [pairs (partition 2 bindings)
|
|
1173
|
+
names (mapv first pairs)
|
|
1174
|
+
new-vals (mapv second pairs)
|
|
1175
|
+
orig-syms (mapv (fn [_] (gensym "orig")) names)]
|
|
1176
|
+
`(let [~@(interleave orig-syms (map (fn [n] `(var-get (var ~n))) names))]
|
|
1177
|
+
(try
|
|
1178
|
+
(do ~@(map (fn [n v] `(alter-var-root (var ~n) (constantly ~v))) names new-vals)
|
|
1179
|
+
~@body)
|
|
1180
|
+
(finally
|
|
1181
|
+
~@(map (fn [n o] `(alter-var-root (var ~n) (constantly ~o))) names orig-syms))))))
|
|
1182
|
+
|
|
1183
|
+
;; ── Macros: conditionals and control flow ───────────────────────────────────
|
|
1184
|
+
|
|
1185
|
+
(defmacro if-some
|
|
1186
|
+
"bindings => binding-form test
|
|
1187
|
+
If test is not nil, evaluates then with binding-form bound to the
|
|
1188
|
+
value of test, if not, yields else"
|
|
1189
|
+
([bindings then] `(if-some ~bindings ~then nil))
|
|
1190
|
+
([bindings then else]
|
|
1191
|
+
(let [form (first bindings)
|
|
1192
|
+
tst (second bindings)]
|
|
1193
|
+
`(let [temp# ~tst]
|
|
1194
|
+
(if (nil? temp#)
|
|
1195
|
+
~else
|
|
1196
|
+
(let [~form temp#]
|
|
1197
|
+
~then))))))
|
|
1198
|
+
|
|
1199
|
+
(defmacro when-some
|
|
1200
|
+
"bindings => binding-form test
|
|
1201
|
+
When test is not nil, evaluates body with binding-form bound to the
|
|
1202
|
+
value of test"
|
|
1203
|
+
[bindings & body]
|
|
1204
|
+
(let [form (first bindings)
|
|
1205
|
+
tst (second bindings)]
|
|
1206
|
+
`(let [temp# ~tst]
|
|
1207
|
+
(when (some? temp#)
|
|
1208
|
+
(let [~form temp#]
|
|
1209
|
+
~@body)))))
|
|
1210
|
+
|
|
1211
|
+
(defmacro when-first
|
|
1212
|
+
"bindings => x xs
|
|
1213
|
+
Roughly the same as (when (seq xs) (let [x (first xs)] body)) but xs is evaluated only once"
|
|
1214
|
+
[bindings & body]
|
|
1215
|
+
(let [x (first bindings)
|
|
1216
|
+
xs (second bindings)]
|
|
1217
|
+
`(let [temp# (seq ~xs)]
|
|
1218
|
+
(when temp#
|
|
1219
|
+
(let [~x (first temp#)]
|
|
1220
|
+
~@body)))))
|
|
1221
|
+
|
|
1222
|
+
(defn condp-emit [gpred gexpr clauses]
|
|
1223
|
+
(if (nil? clauses)
|
|
1224
|
+
`(throw (ex-info (str "No matching clause: " ~gexpr) {}))
|
|
1225
|
+
(if (nil? (next clauses))
|
|
1226
|
+
(first clauses)
|
|
1227
|
+
`(if (~gpred ~(first clauses) ~gexpr)
|
|
1228
|
+
~(second clauses)
|
|
1229
|
+
~(condp-emit gpred gexpr (next (next clauses)))))))
|
|
1230
|
+
|
|
1231
|
+
(defmacro condp
|
|
1232
|
+
"Takes a binary predicate, an expression, and a set of clauses.
|
|
1233
|
+
Each clause can take the form of either:
|
|
1234
|
+
test-expr result-expr
|
|
1235
|
+
The predicate is applied to each test-expr and the expression in turn."
|
|
1236
|
+
[pred expr & clauses]
|
|
1237
|
+
(let [gpred (gensym "pred__")
|
|
1238
|
+
gexpr (gensym "expr__")]
|
|
1239
|
+
`(let [~gpred ~pred
|
|
1240
|
+
~gexpr ~expr]
|
|
1241
|
+
~(condp-emit gpred gexpr clauses))))
|
|
1242
|
+
|
|
1243
|
+
(defn case-emit [ge clauses]
|
|
1244
|
+
(if (nil? clauses)
|
|
1245
|
+
`(throw (ex-info (str "No matching clause: " ~ge) {}))
|
|
1246
|
+
(if (nil? (next clauses))
|
|
1247
|
+
(first clauses)
|
|
1248
|
+
`(if (= ~ge ~(first clauses))
|
|
1249
|
+
~(second clauses)
|
|
1250
|
+
~(case-emit ge (next (next clauses)))))))
|
|
1251
|
+
|
|
1252
|
+
(defmacro case
|
|
1253
|
+
"Takes an expression, and a set of clauses. Each clause can take the form of
|
|
1254
|
+
either:
|
|
1255
|
+
test-constant result-expr
|
|
1256
|
+
If no clause matches, and there is an odd number of forms (a default), the
|
|
1257
|
+
last expression is returned."
|
|
1258
|
+
[e & clauses]
|
|
1259
|
+
(let [ge (gensym "case__")]
|
|
1260
|
+
`(let [~ge ~e]
|
|
1261
|
+
~(case-emit ge clauses))))
|
|
1262
|
+
|
|
1263
|
+
(defmacro dotimes
|
|
1264
|
+
"bindings => name n
|
|
1265
|
+
Repeatedly executes body (presumably for side-effects) with name
|
|
1266
|
+
bound to integers from 0 through n-1."
|
|
1267
|
+
[bindings & body]
|
|
1268
|
+
(let [i (first bindings)
|
|
1269
|
+
n (second bindings)]
|
|
1270
|
+
`(let [n# ~n]
|
|
1271
|
+
(loop [~i 0]
|
|
1272
|
+
(when (< ~i n#)
|
|
1273
|
+
~@body
|
|
1274
|
+
(recur (inc ~i)))))))
|
|
1275
|
+
|
|
1276
|
+
(defmacro while
|
|
1277
|
+
"Repeatedly executes body while test expression is true. Presumes
|
|
1278
|
+
some side-effect will cause test to become false/nil."
|
|
1279
|
+
[test & body]
|
|
1280
|
+
`(loop []
|
|
1281
|
+
(when ~test
|
|
1282
|
+
~@body
|
|
1283
|
+
(recur))))
|
|
1284
|
+
|
|
1285
|
+
(defmacro doseq
|
|
1286
|
+
"Repeatedly executes body (presumably for side-effects) with
|
|
1287
|
+
bindings. Supports :let, :when, and :while modifiers."
|
|
1288
|
+
[seq-exprs & body]
|
|
1289
|
+
(let [bindings (partition 2 seq-exprs)
|
|
1290
|
+
first-binding (first bindings)
|
|
1291
|
+
rest-bindings (next bindings)]
|
|
1292
|
+
(if (nil? first-binding)
|
|
1293
|
+
`(do ~@body nil)
|
|
1294
|
+
(let [k (first first-binding)
|
|
1295
|
+
v (second first-binding)]
|
|
1296
|
+
(cond
|
|
1297
|
+
(= k :let)
|
|
1298
|
+
`(let ~v (doseq ~(apply concat rest-bindings) ~@body))
|
|
1299
|
+
|
|
1300
|
+
(= k :when)
|
|
1301
|
+
`(when ~v (doseq ~(apply concat rest-bindings) ~@body))
|
|
1302
|
+
|
|
1303
|
+
(= k :while)
|
|
1304
|
+
`(if ~v (doseq ~(apply concat rest-bindings) ~@body) nil)
|
|
1305
|
+
|
|
1306
|
+
:else
|
|
1307
|
+
(if rest-bindings
|
|
1308
|
+
`(run! (fn [~k] (doseq ~(apply concat rest-bindings) ~@body)) ~v)
|
|
1309
|
+
`(run! (fn [~k] ~@body) ~v)))))))
|
|
1310
|
+
|
|
1311
|
+
(defmacro for
|
|
1312
|
+
"List comprehension. Takes a vector of one or more
|
|
1313
|
+
binding-form/collection-expr pairs, each followed by zero or more
|
|
1314
|
+
modifiers, and yields a sequence of evaluations of expr.
|
|
1315
|
+
Supported modifiers: :let, :when, :while."
|
|
1316
|
+
[seq-exprs & body]
|
|
1317
|
+
(let [bindings (partition 2 seq-exprs)
|
|
1318
|
+
first-binding (first bindings)
|
|
1319
|
+
rest-bindings (next bindings)]
|
|
1320
|
+
(if (nil? first-binding)
|
|
1321
|
+
`(list ~@body)
|
|
1322
|
+
(let [k (first first-binding)
|
|
1323
|
+
v (second first-binding)]
|
|
1324
|
+
(cond
|
|
1325
|
+
(= k :let)
|
|
1326
|
+
`(let ~v (for ~(apply concat rest-bindings) ~@body))
|
|
1327
|
+
|
|
1328
|
+
(= k :when)
|
|
1329
|
+
`(if ~v (for ~(apply concat rest-bindings) ~@body) (list))
|
|
1330
|
+
|
|
1331
|
+
(= k :while)
|
|
1332
|
+
`(if ~v (for ~(apply concat rest-bindings) ~@body) (list))
|
|
1333
|
+
|
|
1334
|
+
:else
|
|
1335
|
+
(if rest-bindings
|
|
1336
|
+
`(mapcat (fn [~k] (for ~(apply concat rest-bindings) ~@body)) ~v)
|
|
1337
|
+
`(map (fn [~k] ~@body) ~v)))))))
|
|
1338
|
+
|
|
1339
|
+
(defmacro with-out-str
|
|
1340
|
+
"Evaluates body in a context in which *out* is bound to a fresh string
|
|
1341
|
+
accumulator. Returns the string of all output produced by println, print,
|
|
1342
|
+
pr, prn, pprint and newline during the evaluation."
|
|
1343
|
+
[& body]
|
|
1344
|
+
`(let [buf# (atom "")]
|
|
1345
|
+
(binding [*out* (fn [s#] (swap! buf# str s#))]
|
|
1346
|
+
~@body)
|
|
1347
|
+
@buf#))
|
|
1348
|
+
|
|
1349
|
+
(defmacro with-err-str
|
|
1350
|
+
"Like with-out-str but captures *err* output (warn, etc.)."
|
|
1351
|
+
[& body]
|
|
1352
|
+
`(let [buf# (atom "")]
|
|
1353
|
+
(binding [*err* (fn [s#] (swap! buf# str s#))]
|
|
1354
|
+
~@body)
|
|
1355
|
+
@buf#))
|