A slight modification to Clojure’s comp function gives me more power:

(defn comp+
  ([] identity)
  ([f] f)
  ([f g] 
     (fn 
       ([] (f (g)))
       ([x] (f (g x)))
       ([x y] (f (g x y)))
       ([x y z] (f (g x y z)))
       ([x y z & args] (f (apply g x y z args)))))
  ([f g h] 
     (fn 
       ([] (f (g (h))))
       ([x] (f (g (h x))))
       ([x y] (f (g (h x y))))
       ([x y z] (f (g (h x y z))))
       ([x y z & args] (f (g (apply h x y z args))))))
  ([f1 f2 f3 & fs]
    (let [fs (reverse (list* f1 f2 f3 fs))]
      (fn [& args]
        (loop [ret (apply (first fs) args) fs (next fs)]
          (if fs
            (recur ((first fs) ret) (next fs))
            ret))))))

;; allowing
(require ‘clojure.string)

(for [f (map #(apply comp+ %)
             [[keyword name]
              []
              [name clojure.string/upper-case]])
      e '[foo bar]]
  (f e))

;=> (:foo :bar foo bar "FOO" "BAR")

I added a function body to comp+ handling the case where it’s given no function, returning the identity function. This let’s me use comp+ in more interesting ways without requiring that I handle the case of no arguments explicitly and without exploding when I don’t.

Just one of those little things I guess.

:f