rlm@10: ; Copyright (c) Laurent Petit and others, March 2009. All rights reserved. rlm@10: rlm@10: ; The use and distribution terms for this software are covered by the rlm@10: ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) rlm@10: ; which can be found in the file epl-v10.html at the root of this rlm@10: ; distribution. rlm@10: ; By using this software in any fashion, you are agreeing to be bound by rlm@10: ; the terms of this license. rlm@10: ; You must not remove this notice, or any other, from this software. rlm@10: rlm@10: ;; functions/macros variants of the ones that can be found in clojure.core rlm@10: rlm@10: ;; note to other contrib members: feel free to add to this lib rlm@10: rlm@10: (ns rlm@10: ^{:author "Laurent Petit (and others)" rlm@10: :doc "Functions/macros variants of the ones that can be found in clojure.core rlm@10: (note to other contrib members: feel free to add to this lib)"} rlm@10: clojure.contrib.core rlm@10: (:use clojure.contrib.def)) rlm@10: rlm@10: (defmacro- defnilsafe [docstring non-safe-name nil-safe-name] rlm@10: `(defmacro ~nil-safe-name ~docstring rlm@10: {:arglists '([~'x ~'form] [~'x ~'form ~'& ~'forms])} rlm@10: ([x# form#] rlm@10: `(let [~'i# ~x#] (when-not (nil? ~'i#) (~'~non-safe-name ~'i# ~form#)))) rlm@10: ([x# form# & more#] rlm@10: `(~'~nil-safe-name (~'~nil-safe-name ~x# ~form#) ~@more#)))) rlm@10: rlm@10: (defnilsafe rlm@10: "Same as clojure.core/-> but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). rlm@10: Examples : rlm@10: (-?> \"foo\" .toUpperCase (.substring 1)) returns \"OO\" rlm@10: (-?> nil .toUpperCase (.substring 1)) returns nil rlm@10: " rlm@10: -> -?>) rlm@10: rlm@10: (defnilsafe rlm@10: "Same as clojure.core/.. but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). rlm@10: Examples : rlm@10: (.?. \"foo\" .toUpperCase (.substring 1)) returns \"OO\" rlm@10: (.?. nil .toUpperCase (.substring 1)) returns nil rlm@10: " rlm@10: .. .?.) rlm@10: rlm@10: (defnilsafe rlm@10: "Same as clojure.core/->> but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). rlm@10: Examples : rlm@10: (-?>> (range 5) (map inc)) returns (1 2 3 4 5) rlm@10: (-?>> [] seq (map inc)) returns nil rlm@10: " rlm@10: ->> -?>>) rlm@10: rlm@10: ;; ---------------------------------------------------------------------- rlm@10: ;; scgilardi at gmail rlm@10: rlm@10: (defn dissoc-in rlm@10: "Dissociates an entry from a nested associative structure returning a new rlm@10: nested structure. keys is a sequence of keys. Any empty maps that result rlm@10: will not be present in the new structure." rlm@10: [m [k & ks :as keys]] rlm@10: (if ks rlm@10: (if-let [nextmap (get m k)] rlm@10: (let [newmap (dissoc-in nextmap ks)] rlm@10: (if (seq newmap) rlm@10: (assoc m k newmap) rlm@10: (dissoc m k))) rlm@10: m) rlm@10: (dissoc m k))) rlm@10: rlm@10: (defn new-by-name rlm@10: "Constructs a Java object whose class is specified by a String." rlm@10: [class-name & args] rlm@10: (clojure.lang.Reflector/invokeConstructor rlm@10: (clojure.lang.RT/classForName class-name) rlm@10: (into-array Object args))) rlm@10: rlm@10: (defn seqable? rlm@10: "Returns true if (seq x) will succeed, false otherwise." rlm@10: [x] rlm@10: (or (seq? x) rlm@10: (instance? clojure.lang.Seqable x) rlm@10: (nil? x) rlm@10: (instance? Iterable x) rlm@10: (-> x .getClass .isArray) rlm@10: (string? x) rlm@10: (instance? java.util.Map x))) rlm@10: rlm@10: ;; ----------------------------------------------------------------------