Skip to content

Commit

Permalink
finished koans
Browse files Browse the repository at this point in the history
  • Loading branch information
zackham committed Sep 15, 2011
1 parent 186e5f6 commit a174480
Show file tree
Hide file tree
Showing 19 changed files with 168 additions and 152 deletions.
12 changes: 6 additions & 6 deletions src/koans/atoms.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@

(meditations
"Atoms are like refs"
(= __ @atomic-clock)
(= 0 @atomic-clock)

"You can change at the swap meet"
(= __ (do
(= 1 (do
(swap! atomic-clock inc)
@atomic-clock))

"Keep taxes out of this: swapping requires no transaction"
(= 5 (do
__
(swap! atomic-clock * 5)
@atomic-clock))

"Any number of arguments might happen during a swap"
(= __ (do
(= 20 (do
(swap! atomic-clock + 1 2 3 4 5)
@atomic-clock))

"Atomic atoms are atomic"
(= __ (do
(= 20 (do
(compare-and-set! atomic-clock 100 :fin)
@atomic-clock))

"When your expectations are aligned with reality things, proceed that way"
(= :fin (do
(compare-and-set! __ __ __)
(compare-and-set! atomic-clock 20 :fin)
@atomic-clock))
)
20 changes: 10 additions & 10 deletions src/koans/conditionals.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,39 @@

(meditations
"You will face many decisions"
(= __ (if (false? (= 4 5))
(= :a (if (false? (= 4 5))
:a
:b))

"Some of them leave you no alternative"
(= __ (if (> 4 3)
(= [] (if (> 4 3)
[]))

"And in such a situation you may have nothing"
(= __ (if (nil? 0)
(= nil (if (nil? 0)
[:a :b :c]))

"In others your alternative may be interesting"
(= :glory (if (not (empty? ()))
:doom
__))
:glory))

"You may have a multitude of possible paths"
(let [x 5]
(= :your_road (cond (= x __) :road_not_taken
(= x __) :another_road_not_taken
:else __)))
(= :your_road (cond (= x 4) :road_not_taken
(= x 6) :another_road_not_taken
:else :your_road)))

"Or your fate may be sealed"
(= __ (if-not (zero? __)
(= 'doom (if-not (zero? 0)
'doom
'doom))

"In case of emergency, sound the alarms"
(= :sirens
(explain-defcon-level __))
(explain-defcon-level :cocked-pistol))

"But admit it when you don't know what to do"
(= __
(= :say-what?
(explain-defcon-level :yo-mama)))

16 changes: 8 additions & 8 deletions src/koans/creating_functions.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@
(meditations

"One may know what they seek by knowing what they do not seek"
(= [__ __ __] (let [not-a-symbol? (complement symbol?)]
(= [true false true] (let [not-a-symbol? (complement symbol?)]
(map not-a-symbol? [:a 'b "c"])))

"Praise and 'complement' may help you separate the wheat from the chaff"
(= [:wheat "wheat" 'wheat]
(let [not-nil? ___]
(let [not-nil? (complement nil?)]
(filter not-nil? [nil :wheat nil "wheat" nil 'wheat nil])))

"Partial functions allow procrastination"
(= 20 (let [multiply-by-5 (partial * 5)]
(___ __)))
(multiply-by-5 4)))

"Don't forget: first things first"
(= [__ __ __ __]
(= [:a :b :c :d]
(let [ab-adder (partial concat [:a :b])]
(ab-adder [__ __])))
(ab-adder [:c :d])))

"Functions can join forces as one 'composed' function"
(= 25 (let [inc-and-square (comp square inc)]
(inc-and-square __)))
(inc-and-square 4)))

"Have a go on a double dec-er"
(= __ (let [double-dec (comp dec dec)]
(= 8 (let [double-dec (comp dec dec)]
(double-dec 10)))

"Be careful about the order in which you mix your functions"
(= 99 (let [square-and-dec ___]
(= 99 (let [square-and-dec (comp dec square)]
(square-and-dec 10))))

16 changes: 9 additions & 7 deletions src/koans/datatypes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,30 @@
(deftype Razzie [category]
Award
(present [this recipient]
__))
(print (str "You're really the "
(.category this) ", "
recipient "... sorry."))))

(meditations
"Holding records is meaningful only when the record is worthy of you"
(= __ (.prize (Nobel. "peace")))
(= "peace" (.prize (Nobel. "peace")))

"Types are quite similar"
(= __ (.prize (Pulitzer. "literature")))
(= "literature" (.prize (Pulitzer. "literature")))

"Records may be treated like maps"
(= __ (:prize (Nobel. "physics")))
(= "physics" (:prize (Nobel. "physics")))

"While types may not"
(= __ (:prize (Pulitzer. "poetry")))
(= nil (:prize (Pulitzer. "poetry")))

"Further study reveals why"
(= __
(= [true false]
(map map? [(Nobel. "chemistry")
(Pulitzer. "music")]))

"Either sort of datatype can define methods in a protocol"
(= __
(= "Congratulations on your Best Picture Oscar, Evil Alien Conquerors!"
(with-out-str (present (Oscar. "Best Picture") "Evil Alien Conquerors")))

"Surely we can implement our own by now"
Expand Down
23 changes: 15 additions & 8 deletions src/koans/destructuring.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,45 @@

(meditations
"Destructuring is an arbiter: it breaks up arguments"
(= __ ((fn [[a b]] (str b a))
(= ":bar:foo" ((fn [[a b]] (str b a))
[:foo :bar]))

"Whether in function definitions"
(= (str "First comes love, "
"then comes marriage, "
"then comes Clojure with the baby carriage")
((fn [[a b c]] __)
((fn [[a b c]] (str "First comes " a ", then comes " b ", then comes " c " with the baby carriage"))
["love" "marriage" "Clojure"]))

"Or in let expressions"
(= "Rich Hickey aka The Clojurer aka Go Time aka Macro Killah"
(let [[first-name last-name & aliases]
(list "Rich" "Hickey" "The Clojurer" "Go Time" "Macro Killah")]
__))
(apply str (interpose " aka " (conj aliases (str first-name " " last-name))))))

"You can regain the full argument if you like arguing"
(= {:original-parts ["Steven" "Hawking"] :named-parts {:first "Steven" :last "Hawking"}}
(let [[first-name last-name :as full-name] ["Steven" "Hawking"]]
__))
{:original-parts full-name :named-parts {:first first-name :last last-name}}))

"Break up maps by key"
(= "123 Test Lane, Testerville, TX"
(let [{street-address :street-address, city :city, state :state} test-address]
__))
(apply str (interpose ", " (list street-address city state)))))

"Or more succinctly"
(= "123 Test Lane, Testerville, TX"
(let [{:keys [street-address __ __]} test-address]
__))
(let [{:keys [street-address city state]} test-address]
(apply str (interpose ", " (list street-address city state)))))

"All together now!"
(= "Test Testerson, 123 Test Lane, Testerville, TX"
(___ ["Test" "Testerson"] test-address))
((fn [full-name {:keys [street-address city state]}]
(apply str
(interpose ", "
(conj
(list street-address city state)
(apply str
(interpose " " full-name))))))
["Test" "Testerson"] test-address))
)
14 changes: 7 additions & 7 deletions src/koans/equalities.clj
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
(meditations
"We shall contemplate truth by testing reality, via equality."
(= __ true)
(= true true)

"To understand reality, we must compare our expectations against reality."
(= __ (+ 1 1))
(= 2 (+ 1 1))

"You can test equality of many things"
(= (+ 3 4) __ (+ 2 __))
(= (+ 3 4) 7 (+ 2 5))

"Some things may appear different, but be the same"
(= 2 2/1 __)
(= 2 2/1 4/2)

"You cannot generally float to heavens of integers"
(= __ (= 2 2.0))
(= false (= 2 2.0))

"But a looser equality is also possible"
(== 2.0 2 __)
(== 2.0 2 2/1)

"When things cannot be equal, they must be different"
(not= :fill-in-the-blank __))
(not= :fill-in-the-blank :blah))
16 changes: 8 additions & 8 deletions src/koans/functions.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@

(meditations
"Functions are often defined before they are used"
(= __ (multiply-by-ten 2))
(= 20 (multiply-by-ten 2))

"But they can also be defined inline"
(= __ ((fn [n] (* __ n)) 2))
(= 14 ((fn [n] (* 7 n)) 2))

"Or using even shorter syntax"
(= __ (#(* 15 %) __))
(= 30 (#(* 15 %) 2))

"Short anonymous functions may take multiple arguments"
(= __ (#(+ %1 %2 %3) 4 5 6))
(= 15 (#(+ %1 %2 %3) 4 5 6))

"One function can beget another"
(= __ ((fn []
((fn [a b] (__ a b))
(= 9 ((fn []
((fn [a b] (+ a b))
4 5))))

"Higher-order functions take function arguments"
(= 25 (___
(= 25 (#(% 5)
(fn [n] (* n n))))

"But they are often better written using the names of functions"
(= 25 (___ square)))
(= 25 ((fn [f] (f 5)) square)))
20 changes: 10 additions & 10 deletions src/koans/higher_order_functions.clj
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
(meditations
"The map function relates a sequence to another"
(= [__ __ __] (map (fn [x] (* 4 x)) [1 2 3]))
(= [4 8 12] (map (fn [x] (* 4 x)) [1 2 3]))

"You may create that mapping"
(= [1 4 9 16 25] (map (fn [x] __) [1 2 3 4 5]))
(= [1 4 9 16 25] (map (fn [x] (* x x)) [1 2 3 4 5]))

"Or use the names of existing functions"
(= __ (map nil? [:a :b nil :c :d]))
(= [false false true false false] (map nil? [:a :b nil :c :d]))

"A filter can be strong"
(= __ (filter (fn [x] false) '(:anything :goes :here)))
(= '() (filter (fn [x] false) '(:anything :goes :here)))

"Or very weak"
(= __ (filter (fn [x] true) '(:anything :goes :here)))
(= '(:anything :goes :here) (filter (fn [x] true) '(:anything :goes :here)))

"Or somewhere in between"
(= [10 20 30] (filter (fn [x] __) [10 20 30 40 50 60 70 80]))
(= [10 20 30] (filter (fn [x] (>= 30 x)) [10 20 30 40 50 60 70 80]))

"Maps and filters may be combined"
(= [10 20 30] (map (fn [x] __) (filter (fn [x] __) [1 2 3 4 5 6 7 8])))
(= [10 20 30] (map (fn [x] (* 10 x)) (filter (fn [x] (>= 3 x)) [1 2 3 4 5 6 7 8])))

"Reducing can increase the result"
(= __ (reduce (fn [a b] (* a b)) [1 2 3 4]))
(= 24 (reduce (fn [a b] (* a b)) [1 2 3 4]))

"You can start somewhere else"
(= 2400 (reduce (fn [a b] (* a b)) __ [1 2 3 4]))
(= 2400 (reduce (fn [a b] (* a b)) 100 [1 2 3 4]))

"Numbers are not the only things one can reduce"
(= "longest" (reduce (fn [a b]
(if (< __ __) b a))
(if (< (count a) (count b)) b a))
["which" "word" "is" "longest"])))
10 changes: 5 additions & 5 deletions src/koans/java_interop.clj
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
(meditations
"You may have done more with Java than you know"
(= __ (class "warfare")) ; hint: try typing (javadoc "warfare") in the REPL
(= String (class "warfare")) ; hint: try typing (javadoc "warfare") in the REPL

"The dot signifies easy and direct Java interoperation"
(= __ (.toUpperCase "select * from"))
(= "SELECT * FROM" (.toUpperCase "select * from"))

"But instance method calls are very different from normal functions"
(= ["SELECT" "FROM" "WHERE"] (map ___ ["select" "from" "where"]))
(= ["SELECT" "FROM" "WHERE"] (map #(.toUpperCase %) ["select" "from" "where"]))

"Constructing might be harder than breaking"
(= 10 (let [latch (java.util.concurrent.CountDownLatch. __)]
(= 10 (let [latch (java.util.concurrent.CountDownLatch. 10)]
(.getCount latch)))

"Static methods are slashing prices!"
(== __ (Math/pow 2 10)))
(== 1024 (Math/pow 2 10)))
14 changes: 7 additions & 7 deletions src/koans/lazy_sequences.clj
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
(meditations
"There are a wide range of ways to generate a sequence"
(= __ (range 1 5))
(= [1 2 3 4] (range 1 5))

"The range starts at the beginning by default"
(= __ (range 5))
(= [0 1 2 3 4] (range 5))

"It's important to only take what you need from a big sequence"
(= [0 1 2 3 4 5 6 7 8 9]
(take __ (range 100)))
(take 10 (range 100)))

"You can also limit results by dropping what you don't need"
(= [95 96 97 98 99]
(drop __ (range 100)))
(drop 95 (range 100)))

"Iteration provides an infinite lazy sequence"
(= __ (take 20 (iterate inc 0)))
(= (range 20) (take 20 (iterate inc 0)))

"Repetition is key"
(= [:a :a :a :a :a :a :a :a :a :a ]
(repeat 10 __))
(repeat 10 :a))

"Iteration can be used for repetition"
(= (repeat 100 :foo)
(take 100 (iterate ___ :foo))))
(take 100 (iterate (fn [x] :foo) :foo))))
Loading

0 comments on commit a174480

Please sign in to comment.