1.3.0 permalink Arrow_down_16x16
  • (comp)
  • (comp f)
  • (comp f g)
  • (comp f g h)
  • (comp f1 f2 f3 & fs)
Takes a set of functions and returns a fn that is the composition
of those fns. The returned fn takes a variable number of args,
applies the rightmost of fns to the args, the next
fn (right-to-left) to the result, etc.

7 Examples top

  • user=> (def negative-quotient (comp - /))
    #'user/negative-quotient
    
    user=> (negative-quotient 8 3)           
    -8/3
    
    
    user=> (def concat-and-reverse (comp (partial apply str) reverse str)) 
    #'user/concat-and-reverse
    
    user=> (concat-and-reverse "hello" "clojuredocs")
    "scoderujolcolleh"
    
  • user=> ((comp str +) 8 8 8)
    "24"
  • user=> (map
             (comp - (partial + 3) (partial * 2))
             [1 2 3 4])
    ; returns
    (-5 -7 -9 -11)
  • user=> (filter (comp not zero?) [0 1 0 2 0 3 0 4])
    (1 2 3 4)
  • ;; make a struct 'goods'. it assumes that every goods has
    ;; its id number and price.
    (defstruct goods :id :price)
    
    ;; generate data.
    (def data (map #(struct goods %1 %2)
    	       (shuffle (range 0 10)) (shuffle
    				       (into (range 100 500 100)
    					     (range 100 500 100)))))
    
    (defn comp-goods-price
      "a compare function by :price of the struct 'goods.' the sort order 
       is that the lower price is superior to the higher one and if the 
       price is same, the lower id is superior to the higher one."
      [el1 el2]
      (if (or  (< (:price el1) (:price el2))
               (and (= (:price el1) (:price el2))(< (:id el1) (:id el2))))
        true
        false))
    
    user> data
    ({:id 1, :price 300} {:id 6, :price 100} {:id 3, :price 100} {:id 4, :price 400} {:id 0, :price 300} {:id 2, :price 200} {:id 5, :price 200} {:id 8, :price 400})
    user> (sort (comp comp-goods-price) data)
    ({:id 3, :price 100} {:id 6, :price 100} {:id 2, :price 200} {:id 5, :price 200} {:id 0, :price 300} {:id 1, :price 300} {:id 4, :price 400} {:id 8, :price 400})
    user> (sort-by :price < data) ; compare this with the above.
    ({:id 6, :price 100} {:id 3, :price 100} {:id 2, :price 200} {:id 5, :price 200} {:id 1, :price 300} {:id 0, :price 300} {:id 4, :price 400} {:id 8, :price 400})
    
    ;; Yet another example of 'comp' by PriorityBlockingQueue.
    
    user> (import [java.util.concurrent PriorityBlockingQueue])
    java.util.concurrent.PriorityBlockingQueue
    user> (def pqdata (new PriorityBlockingQueue 8
    		       (comp comp-goods-price)))
    #'user/pqdata
    user> (doseq [x data]
    	     (.add pqdata x))
    nil
    user> (dotimes [_ 8]
    	       (println (.poll pqdata)))
    {:id 3, :price 100}
    {:id 6, :price 100}
    {:id 2, :price 200}
    {:id 5, :price 200}
    {:id 0, :price 300}
    {:id 1, :price 300}
    {:id 4, :price 400}
    {:id 8, :price 400}
    nil
    user> 
  • user=> (def countif (comp count filter))
    #'user/countif
    user=> (countif even? [2 3 1 5 4])
    2
  • ; Get 2nd to last element from a list
    user=> ( (comp second reverse) '("a" 2 7 "b"))
    7
Log in to add / edit an example.

See Also top

Log in to add a see also.

Plus_12x12 Minus_12x12 Source clojure/core.clj:2265 top

(defn comp
  "Takes a set of functions and returns a fn that is the composition
  of those fns.  The returned fn takes a variable number of args,
  applies the rightmost of fns to the args, the next
  fn (right-to-left) to the result, etc."
  {:added "1.0"
   :static true}
  ([] 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))))))
Vars in clojure.core/comp:
Used in 0 other vars

Comments top

No comments for comp. Log in to add a comment.