Bobbi Towers / Jun 26 2019
Clojure Brave Chapter 3
Multi-arity
(defn no-params [] "I take no parameters!") (defn one-param [x] (str "I take one parameter: " x)) (defn two-params [x y] (str "Two parameters! That's nothing! Pah! I will smoosh them " "together to spite you! " x y))
user/two-params
(defn x-chop "Describe the kind of chop you're inflicting on someone" ([name chop-type] (str "I " chop-type " chop " name "! Take that!")) ([name] (x-chop name "karate"))) (x-chop "Kanye West" "slap") (x-chop "Kanye East")
"I karate chop Kanye East! Take that!"
Rest params
(defn codger-communication [whippersnapper] (str "Get off my lawn, " whippersnapper "!!!")) (defn codger [& whippersnappers] (map codger-communication whippersnappers)) (codger "Billy" "Anne-Marie" "The Incredible Bulk")
List(3) ("Get off my lawn, Billy!!!", "Get off my lawn, Anne-Marie!!!", "Get off my lawn, The Incredible Bulk!!!")
(defn favorite-things [name & things] (str "Hi, " name ", here are my favorite things: " (clojure.string/join ", " things))) (favorite-things "Doreen" "gum" "shoes" "kara-te")
"Hi, Doreen, here are my favorite things: gum, shoes, kara-te"
Destructuring
(defn chooser [[first-choice second-choice & unimportant-choices]] (println (str "Your first choice is: " first-choice)) (println (str "Your second choice is: " second-choice)) (println (str "We're ignoring the rest of your choices. " "Here they are in case you need to cry over them: " (clojure.string/join ", " unimportant-choices)))) (chooser ["Marmalade", "Handsome Jack", "Pigpen", "Aquaman"])
(defn announce-treasure-location [{lat :lat lng :lng}] (println (str "Treasure lat: " lat)) (println (str "Treasure lng: " lng))) (defn announce-treasure-location [{:keys [lat lng]}] (println (str "Treasure lat: " lat)) (println (str "Treasure lng: " lng))) (announce-treasure-location {:lat 28.22 :lng 81.33})
The Shire’s Next Top Model
(def asym-hobbit-body-parts [{:name "head" :size 3} {:name "left-eye" :size 1} {:name "left-ear" :size 1} {:name "mouth" :size 1} {:name "nose" :size 1} {:name "neck" :size 2} {:name "left-shoulder" :size 3} {:name "left-upper-arm" :size 3} {:name "chest" :size 10} {:name "back" :size 10} {:name "left-forearm" :size 3} {:name "abdomen" :size 6} {:name "left-kidney" :size 1} {:name "left-hand" :size 2} {:name "left-knee" :size 2} {:name "left-thigh" :size 4} {:name "left-lower-leg" :size 3} {:name "left-achilles" :size 1} {:name "left-foot" :size 2}])
user/asym-hobbit-body-parts
(defn matching-part [part] {:name (clojure.string/replace (:name part) "^left-" "right-") :size (:size part)}) (defn symmetrize-body-parts "Expects a seq of maps that have a :name and :size" [asym-body-parts] (loop [remaining-asym-parts asym-body-parts final-body-parts []] (if (empty? remaining-asym-parts) final-body-parts (let [[part & remaining] remaining-asym-parts] (recur remaining (into final-body-parts (set [part (matching-part part)]))))))) (symmetrize-body-parts asym-hobbit-body-parts)
Better Symmetrizer with reduce
;; sum with reduce (reduce + [1 2 3 4])
10
(+ (+ (+ 1 2) 3) 4)
10
(reduce + 15 [1 2 3 4])
25
(defn my-reduce ([f initial coll] (loop [result initial remaining coll] (if (empty? remaining) result (recur (f result (first remaining)) (rest remaining))))) ([f [head & tail]] (my-reduce f head tail))) (my-reduce + [1 2 3 4]) (my-reduce + 15 [1 2 3 4])
25
(defn better-symmetrize-body-parts "Expects a seq of maps that have a :name and :size" [asym-body-parts] (reduce (fn [final-body-parts part] (into final-body-parts (set [part (matching-part part)]))) [] asym-body-parts)) (defn hit [asym-body-parts] (let [sym-parts (better-symmetrize-body-parts asym-body-parts) body-part-size-sum (reduce + (map :size sym-parts)) target (rand body-part-size-sum)] (loop [[part & remaining] sym-parts accumulated-size (:size part)] (if (> accumulated-size target) part (recur remaining (+ accumulated-size (:size (first remaining)))))))) (hit asym-hobbit-body-parts)
Map {:name: "abdomen", :size: 6}