rlm@0: (ns rlm.clojure-example) rlm@0: rlm@0: (defn curry rlm@0: "takes a function with a fixed number of args and modifies rlm@0: it to that it will be automaticaly curried when called with rlm@0: less args" rlm@0: ([num-args f & eval-list] rlm@0: (if (= num-args (count eval-list)) rlm@0: (apply f eval-list) rlm@0: (fn [& args] rlm@0: (apply curry num-args f (concat eval-list args)))))) rlm@0: rlm@0: (defn mix rlm@0: "Takes any number of mathematically equal functions with rlm@0: possibly different run-times and returns a function that rlm@0: runs each in a separate thread, returns the result from rlm@0: the first thread which finishes, and cancels the other threads." rlm@0: {:author "Robert McIntyre"} rlm@0: ([& functions] rlm@0: (fn [& args] rlm@0: (let [result (promise) rlm@0: futures rlm@0: (doall (for [fun functions] rlm@0: (future (deliver result (apply fun args))))) rlm@0: answer @result] rlm@0: (dorun (map future-cancel futures)) rlm@0: answer)))) rlm@0: rlm@0: (defn memoize* rlm@0: "Returns a memoized version of a referentially transparent rlm@0: function. The memoized version of the function keeps a cache of the rlm@0: mapping from argument to results and, when calls with the same rlm@0: arguments are repeated often, has higher performance at the expense rlm@0: of higher memory use." rlm@0: {:added "1.0"} rlm@0: [f] rlm@0: (let [mem (atom {})] rlm@0: (fn [& args] rlm@0: (if-let [e (find @mem args)] rlm@0: (val e) rlm@0: (let [ret (apply f args)] rlm@0: (swap! mem assoc args ret) rlm@0: ret))))) rlm@0: rlm@0: ;;immutable data structures rlm@0: (def r {:a :a :b :b}) rlm@0: (def b (assoc r :c :c)) rlm@0: rlm@0: (defn collapse [coll & head] rlm@0: (if (= (count coll) 0) rlm@0: (first head) rlm@0: (let [x (first coll)] rlm@0: (if (list? x) rlm@0: (collapse (concat x (rest coll)) (first head)) rlm@0: (collapse (rest coll) (conj (vec (first head)) x)))))) rlm@0: ;;email clojure group about this rlm@0: rlm@0: rlm@0: (defn collapse* [coll] rlm@0: (loop [head [] body coll] rlm@0: (let [x (first body)] rlm@0: (cond (= (count body) 0) head rlm@0: (list? x) (recur head (concat x (next body))) rlm@0: true (recur (conj head x) (next body)))))) rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: