loop, recur and comp

Here is some code for a few functions that are mentioned in Chapter Five of Clojure For The Brave And True, along with a few modifications/experiments that I did.

 

;; sum with recur, based on Brave And True chapter 5
user> (defn sum
  ([vals]
   (sum vals 0))
  ([vals accumulating-total]
   (println "sum w/recur and vals: ", vals, " and accumulating-total: ", accumulating-total)
   (if (empty? vals)
     accumulating-total
     (recur (rest vals) (+ (first vals) accumulating-total)))))
#'user/sum
user> (sum [3 4 5])
sum w/recur and vals:  [3 4 5]  and accumulating-total:  0                                                                                                                        
sum w/recur and vals:  (4 5)  and accumulating-total:  3                                                                                                                          
sum w/recur and vals:  (5)  and accumulating-total:  7                                                                                                                            
sum w/recur and vals:  ()  and accumulating-total:  12                                                                                                                            
12

;; sum with loop/recur
user> (defn sum-loop
  ([vals]
   (sum-loop vals 0))
  ([vals accumulating-total]
   (println "sum-loop w/recur and vals: ", vals, " and accumulating-total: ", accumulating-total)
   (loop [loop-vals  vals
          loop-accum accumulating-total]
     (println "In loop with loop-vals: ", loop-vals, " and loop-accum: ", loop-accum)
       (if (empty? loop-vals)
         loop-accum
         (recur (rest loop-vals) (+ (first loop-vals) loop-accum))))))
#'user/sum-loop
user> (sum-loop [3 4 5])
sum-loop w/recur and vals:  [3 4 5]  and accumulating-total:  0                                                                                                                   
In loop with loop-vals:  [3 4 5]  and loop-accum:  0                                                                                                                              
In loop with loop-vals:  (4 5)  and loop-accum:  3                                                                                                                                
In loop with loop-vals:  (5)  and loop-accum:  7                                                                                                                                  
In loop with loop-vals:  ()  and loop-accum:  12                                                                                                                                  
12
user> 
;; so it looks like without "loop", "recur" will call the function each time
;; so loop/recur is a better use of memory

;; comp can combine functions to make new functions
user> ((comp inc *) 2 3)
7
;; the right-most function can accept multiple args
;; but rest in the chain must accept only one
user> ((comp * inc ) 2 3)
ArityException Wrong number of args (2) passed to: core/inc  clojure.lang.AFn.throwArity (AFn.java:429)                                                                           

;; you can combine more than two
user> ((comp integer? inc *) 2 3)
true

;; use of comp from Brave And True to view a map:
user> (def character
  {:name "Smooches McCutes"
   :attributes {:intelligence 10
                :strength 4
                :dexterity 5}})
(def c-int (comp :intelligence :attributes))
#'user/character
#'user/c-int
user> (c-int character)
10
;; "get-in" can do the same thing with a nested map, 
;; but is a bit less elegant in usage
user> (get-in character [:attributes :intelligence])
10

You’re welcome.

1 thought on “loop, recur and comp”

Comments are closed.