Compare commits

..

No commits in common. "master" and "0.5.1" have entirely different histories.

15 changed files with 20 additions and 179 deletions

View file

@ -152,7 +152,7 @@ to add to existing koans. So write some fun exercises, add your answers to
Please follow the guidelines in Please follow the guidelines in
http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html for http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html for
commit messages, and put your code in a feature branch (not master) before commmit messages, and put your code in a feature branch (not master) before
making the pull request. This makes patches easier to review. making the pull request. This makes patches easier to review.
Feel free to contact me (Colin Jones / trptcolin) on Github or elsewhere if you Feel free to contact me (Colin Jones / trptcolin) on Github or elsewhere if you

View file

@ -1,4 +1,4 @@
(defproject clojure-koans "0.5.2-SNAPSHOT" (defproject clojure-koans "0.5.1"
:description "The Clojure koans." :description "The Clojure koans."
:dependencies [[org.clojure/clojure "1.10.0"] :dependencies [[org.clojure/clojure "1.10.0"]
[koan-engine "0.2.5"]] [koan-engine "0.2.5"]]

View file

@ -254,7 +254,7 @@
nil nil
\C \C
inc inc
:park "Oracle Park" :park "AT&T Park"
'Giants 'Giants
"Giants"]}] "Giants"]}]
@ -266,23 +266,4 @@
10 10
'(+ 9 1)]}] '(+ 9 1)]}]
["25_threading_macros" {"__" [{:a 1}
"Hello world, and moon, and stars"
"String with a trailing space"
6
1
[2 3 4]
12
[1 2 3]]}]
["26_transducers" {"__" ['(2 3 4)
[2 4]
[2 4]
[2 4]
6]}]
["27_multimethods" {"__" ["Hello, World!"
"Hello there"
1
6]}]
] ]

View file

@ -39,7 +39,7 @@
"Maybe you want to find the index of the first occurrence of a substring" "Maybe you want to find the index of the first occurrence of a substring"
(= 0 (string/index-of "hello world" __)) (= 0 (string/index-of "hello world" __))
"Or maybe the last index of the same substring" "Or maybe the last index of the same"
(= __ (string/last-index-of "hello world, hello" "hello")) (= __ (string/last-index-of "hello world, hello" "hello"))
"But when something doesn't exist, nothing is found" "But when something doesn't exist, nothing is found"

View file

@ -12,7 +12,7 @@
"Remember that a set is a *mathematical* set" "Remember that a set is a *mathematical* set"
(= __ (set '(1 1 2 2 3 3 4 4 5 5))) (= __ (set '(1 1 2 2 3 3 4 4 5 5)))
"You can ask Clojure for the union of two sets" "You can ask clojure for the union of two sets"
(= __ (set/union #{1 2 3 4} #{2 3 5})) (= __ (set/union #{1 2 3 4} #{2 3 5}))
"And also the intersection" "And also the intersection"

View file

@ -20,7 +20,7 @@
(for [x __ :when (odd? x)] (for [x __ :when (odd? x)]
x)) x))
"Combinations of these transformations are trivial" "Combinations of these transformations is trivial"
(= '(1 9 25 49 81) (= '(1 9 25 49 81)
(map (fn [x] (* x x)) (map (fn [x] (* x x))
(filter odd? (range 10))) (filter odd? (range 10)))

View file

@ -35,10 +35,10 @@
"Yet it becomes more difficult the more steps you take" "Yet it becomes more difficult the more steps you take"
(= '(6 5 4 3 2) (recursive-reverse [2 3 4 5 6])) (= '(6 5 4 3 2) (recursive-reverse [2 3 4 5 6]))
"Simple things may appear simple" "Simple things may appear simple."
(= 1 (factorial 1)) (= 1 (factorial 1))
"They may require other simple steps" "They may require other simple steps."
(= 2 (factorial 2)) (= 2 (factorial 2))
"Sometimes a slightly bigger step is necessary" "Sometimes a slightly bigger step is necessary"

View file

@ -29,7 +29,7 @@
(let [[first-name last-name :as full-name] ["Stephen" "Hawking"]] (let [[first-name last-name :as full-name] ["Stephen" "Hawking"]]
__)) __))
"Break up maps by keys" "Break up maps by key"
(= "123 Test Lane, Testerville, TX" (= "123 Test Lane, Testerville, TX"
(let [{street-address :street-address, city :city, state :state} test-address] (let [{street-address :street-address, city :city, state :state} test-address]
__)) __))

View file

@ -14,8 +14,8 @@
"If you need to, you can start each sequence with an offset" "If you need to, you can start each sequence with an offset"
(= '((0 1 2) (5 6 7) (10 11 12)) (partition 3 __ (range 13))) (= '((0 1 2) (5 6 7) (10 11 12)) (partition 3 __ (range 13)))
"Consider padding the last sequence with some default values" "Consider padding the last sequence with some default values..."
(= '((0 1 2) (3 4 5) (6 :hello)) (partition 3 3 [__] (range 7))) (= '((0 1 2) (3 4 5) (6 :hello)) (partition 3 3 [__] (range 7)))
"But notice that they will only pad up to the given sequence length" "... but notice that they will only pad up to the given sequence length"
(= '((0 1 2) (3 4 5) __) (partition 3 3 [:these :are "my" "words"] (range 7)))) (= '((0 1 2) (3 4 5) __) (partition 3 3 [:these :are "my" "words"] (range 7))))

View file

@ -6,7 +6,7 @@
[odds evens])) [odds evens]))
(meditations (meditations
"To categorize a collection by some function, use group-by" "To categorize a collection by some function, use group-by."
(= __ (group-by count ["hello" "world" "foo" "bar"])) (= __ (group-by count ["hello" "world" "foo" "bar"]))
"You can simulate filter + remove in one pass" "You can simulate filter + remove in one pass"

View file

@ -40,7 +40,7 @@
@(:world-series-titles (meta giants)))) @(:world-series-titles (meta giants))))
"You can also create a new object from another object with metadata" "You can also create a new object from another object with metadata"
(= {:league "National League" :park "Oracle Park"} (= {:league "National League" :park "AT&T Park"}
(meta (vary-meta giants (meta (vary-meta giants
assoc __ __))) assoc __ __)))

View file

@ -38,7 +38,7 @@
"You can do better than that - hand crafting FTW!" "You can do better than that - hand crafting FTW!"
(= '(* 10 2) (macroexpand '(infix-concise (10 * 2)))) (= '(* 10 2) (macroexpand '(infix-concise (10 * 2))))
"Things don't always work as you would like them to" "Things don't always work as you would like them to... "
(= '(+ 10 (2 * 3)) (macroexpand '(infix-concise (10 + (2 * 3))))) (= '(+ 10 (2 * 3)) (macroexpand '(infix-concise (10 + (2 * 3)))))
"Really, you don't understand recursion until you understand recursion" "Really, you don't understand recursion until you understand recursion"

View file

@ -1,66 +0,0 @@
(ns koans.25-threading-macros
(:require [koan-engine.core :refer :all]))
(def a-list
'(1 2 3 4 5))
(def a-list-with-maps
'({:a 1} {:a 2} {:a 3}))
(defn function-that-takes-a-map [map a b]
(get map :a))
(defn function-that-takes-a-coll [a b coll]
(map :a coll))
(meditations
"We can use thread first for more readable sequential operations"
(= __
(-> {}
(assoc :a 1)))
"Consider also the case of strings"
(= __
(-> "Hello world"
(str ", and moon")
(str ", and stars")))
"When a function has no arguments to partially apply, just reference it"
(= __
(-> "String with a trailing space "
clojure.string/trim))
"Most operations that take a scalar value as an argument can be threaded-first"
(= __
(-> {}
(assoc :a 1)
(assoc :b 2)
(assoc :c {:d 4
:e 5})
(update-in [:c :e] inc)
(get-in [:c :e])))
"We can use functions we have written ourselves that follow this pattern"
(= __
(-> {}
(assoc :a 1)
(function-that-takes-a-map "hello" "there")))
"We can also thread last using ->>"
(= __
(->> [1 2 3]
(map inc)))
"Most operations that take a collection can be threaded-last"
(= __
(->> a-list
(map inc)
(filter even?)
(into [])
(reduce +)))
"We can use functions we have written ourselves that follow this pattern"
(= __
(->> a-list-with-maps
(function-that-takes-a-coll "hello" "there")
(into []))))

View file

@ -1,30 +0,0 @@
(ns koans.26-transducers
(:require [koan-engine.core :refer :all]))
(def example-transducer
(map inc))
(def transforms
(comp (map inc)
(filter even?)))
(meditations
"A sequence operation with only one argument often returns a transducer"
(= __
(sequence example-transducer [1 2 3]))
"Consider that sequence operations can be composed as transducers"
(= __
(transduce transforms conj [1 2 3]))
"We can do this eagerly"
(= __
(into [] transforms [1 2 3]))
"Or lazily"
(= __
(sequence transforms [1 2 3]))
"The transduce function can combine mapping and reduction"
(= __
(transduce transforms + [1 2 3])))

View file

@ -1,44 +0,0 @@
(ns koans.27-multimethods
(:require [koan-engine.core :refer :all]))
(defmulti multimethod-without-args
(fn [keyword-arg] keyword-arg))
(defmethod multimethod-without-args :first [_]
(str "Hello, World!"))
(defmethod multimethod-without-args :second [_]
(str "Hello there"))
(defmulti multimethod-with-args
(fn [opt-one opt-two] opt-one))
(defmethod multimethod-with-args :path-one [_ opts]
(:first-opt opts))
(defmethod multimethod-with-args :path-two [_ opts]
(let [numbers (:second-opt opts)]
(->> numbers
(map inc)
(reduce +))))
(defmethod multimethod-with-args :path-three [_])
(meditations
"A multimethod takes one or more arguments to dispatch on"
(= __
(multimethod-without-args :first))
"Though it can be ignored and represented by _ in defmethods"
(= __
(multimethod-without-args :second))
"Alternatively, we can use the arguments in defmethods"
(= __
(multimethod-with-args :path-one {:first-opt 1
:second-opt 2}))
"This allows us to do something different in each method implementation"
(= __
(multimethod-with-args :path-two {:first-opt 1
:second-opt [0 1 2]})))