Skip to content
Browse files

added fnil to supply default values #257

Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
  • Loading branch information...
1 parent eb4502c commit 24442426af1fe643d904b4adfcf62fd7a1cf3ff7 @timothypratley timothypratley committed with stuarthalloway
Showing with 34 additions and 0 deletions.
  1. +23 −0 src/clj/clojure/core.clj
  2. +11 −0 test/clojure/test_clojure/other_functions.clj
View
23 src/clj/clojure/core.clj
@@ -5669,6 +5669,29 @@
(cons x (keepi (inc idx) (rest s)))))))))]
(keepi 0 coll))))
+(defn fnil
+ "Takes a function f, and returns a function that calls f, replacing
+ a nil first argument to f with the supplied value x. Higher arity
+ versions can replace arguments in the second and third
+ positions (y, z). Note that the function f can take any number of
+ arguments, not just the one(s) being nil-patched."
+ ([f x]
+ (fn
+ ([a] (f (if (nil? a) x a)))
+ ([a b] (f (if (nil? a) x a) b))
+ ([a b c] (f (if (nil? a) x a) b c))
+ ([a b c & ds] (apply f (if (nil? a) x a) b c ds))))
+ ([f x y]
+ (fn
+ ([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
+ ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) c))
+ ([a b c & ds] (apply f (if (nil? a) x a) (if (nil? b) y b) c ds))))
+ ([f x y z]
+ (fn
+ ([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
+ ([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- ^{:dynamic true} assert-valid-fdecl
"A good fdecl looks like (([a] ...) ([a b] ...)) near the end of defn."
[fdecl]
View
11 test/clojure/test_clojure/other_functions.clj
@@ -50,6 +50,17 @@
"bar" 'bar
"quux" "quux"))
+(deftest test-fnil
+ (are [x y] (= x y)
+ ((fnil + 0) nil 42) 42
+ ((fnil conj []) nil 42) [42]
+ (reduce #(update-in %1 [%2] (fnil inc 0)) {}
+ ["fun" "counting" "words" "fun"])
+ {"words" 1, "counting" 1, "fun" 2}
+ (reduce #(update-in %1 [(first %2)] (fnil conj []) (second %2)) {}
+ [[:a 1] [:a 2] [:b 3]])
+ {:b [3], :a [1 2]}))
+
; time assert comment doc
; partial

0 comments on commit 2444242

Please sign in to comment.
Something went wrong with that request. Please try again.