summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfogus <mefogus@gmail.com>2011-03-02 08:31:13 -0500
committerStuart Halloway <stu@Orolo-2.local>2011-03-20 09:33:51 -0400
commit8c783f1c1a6fb0cf9c50e4737596e92bceb8012b (patch)
treea703d4c1d82315ee65f53babf2f600325ddc513d /src
parentecae8ff08a298777c365a261001adfe9bfa4d83c (diff)
Adds the every-pred and some-fn combinators and their tests. refs. CLJ-729
Signed-off-by: Stuart Halloway <stu@Orolo-2.local>
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 0f6a332a..4a6f7761 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -6204,6 +6204,86 @@
([a b c] (f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c)))
([a b c & ds] (apply f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c) ds)))))
+(defn every-pred
+ "Takes a set of predicates and returns a function f that returns true if all of its
+ composing predicates return a logical true value against all of its arguments, else it returns
+ false. Note that f is short-circuiting in that it will stop execution on the first
+ argument that triggers a logical false result against the original predicates."
+ {:added "1.3"}
+ ([p]
+ (fn ep1
+ ([] true)
+ ([x] (boolean (p x)))
+ ([x y] (boolean (and (p x) (p y))))
+ ([x y z] (boolean (and (p x) (p y) (p z))))
+ ([x y z & args] (boolean (and (ep1 x y z)
+ (every? p args))))))
+ ([p1 p2]
+ (fn ep2
+ ([] true)
+ ([x] (boolean (and (p1 x) (p2 x))))
+ ([x y] (boolean (and (p1 x) (p1 y) (p2 x) (p2 y))))
+ ([x y z] (boolean (and (p1 x) (p1 y) (p1 z) (p2 x) (p2 y) (p2 z))))
+ ([x y z & args] (boolean (and (ep2 x y z)
+ (every? #(and (p1 %) (p2 %)) args))))))
+ ([p1 p2 p3]
+ (fn ep3
+ ([] true)
+ ([x] (boolean (and (p1 x) (p2 x) (p3 x))))
+ ([x y] (boolean (and (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y))))
+ ([x y z] (boolean (and (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y) (p1 z) (p2 z) (p3 z))))
+ ([x y z & args] (boolean (and (ep3 x y z)
+ (every? #(and (p1 %) (p2 %) (p3 %)) args))))))
+ ([p1 p2 p3 & ps]
+ (let [ps (list* p1 p2 p3 ps)]
+ (fn epn
+ ([] true)
+ ([x] (every? #(% x) ps))
+ ([x y] (every? #(and (% x) (% y)) ps))
+ ([x y z] (every? #(and (% x) (% y) (% z)) ps))
+ ([x y z & args] (boolean (and (epn x y z)
+ (every? #(every? % args) ps))))))))
+
+(defn some-fn
+ "Takes a set of predicates and returns a function f that returns the first logical true value
+ returned by one of its composing predicates against any of its arguments, else it returns
+ logical false. Note that f is short-circuiting in that it will stop execution on the first
+ argument that triggers a logical true result against the original predicates."
+ {:added "1.3"}
+ ([p]
+ (fn sp1
+ ([] nil)
+ ([x] (p x))
+ ([x y] (or (p x) (p y)))
+ ([x y z] (or (p x) (p y) (p z)))
+ ([x y z & args] (or (sp1 x y z)
+ (some p args)))))
+ ([p1 p2]
+ (fn sp2
+ ([] nil)
+ ([x] (or (p1 x) (p2 x)))
+ ([x y] (or (p1 x) (p1 y) (p2 x) (p2 y)))
+ ([x y z] (or (p1 x) (p1 y) (p1 z) (p2 x) (p2 y) (p2 z)))
+ ([x y z & args] (or (sp2 x y z)
+ (some #(or (p1 %) (p2 %)) args)))))
+ ([p1 p2 p3]
+ (fn sp3
+ ([] nil)
+ ([x] (or (p1 x) (p2 x) (p3 x)))
+ ([x y] (or (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y)))
+ ([x y z] (or (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y) (p1 z) (p2 z) (p3 z)))
+ ([x y z & args] (or (sp3 x y z)
+ (some #(or (p1 %) (p2 %) (p3 %)) args)))))
+ ([p1 p2 p3 & ps]
+ (let [ps (list* p1 p2 p3 ps)]
+ (fn spn
+ ([] nil)
+ ([x] (some #(% x) ps))
+ ([x y] (some #(or (% x) (% y)) ps))
+ ([x y z] (some #(or (% x) (% y) (% z)) ps))
+ ([x y z & args] (or (spn x y z)
+ (some #(some % args) ps)))))))
+
(defn- ^{:dynamic true} assert-valid-fdecl
"A good fdecl looks like (([a] ...) ([a b] ...)) near the end of defn."
[fdecl]