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
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.
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."
:dependencies [[org.clojure/clojure "1.10.0"]
[koan-engine "0.2.5"]]

View file

@ -254,7 +254,7 @@
nil
\C
inc
:park "Oracle Park"
:park "AT&T Park"
'Giants
"Giants"]}]
@ -266,23 +266,4 @@
10
'(+ 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"
(= 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"))
"But when something doesn't exist, nothing is found"

View file

@ -12,7 +12,7 @@
"Remember that a set is a *mathematical* set"
(= __ (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}))
"And also the intersection"

View file

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

View file

@ -35,10 +35,10 @@
"Yet it becomes more difficult the more steps you take"
(= '(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))
"They may require other simple steps"
"They may require other simple steps."
(= 2 (factorial 2))
"Sometimes a slightly bigger step is necessary"

View file

@ -29,7 +29,7 @@
(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"
(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"
(= '((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)))
"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))))

View file

@ -6,7 +6,7 @@
[odds evens]))
(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"]))
"You can simulate filter + remove in one pass"

View file

@ -40,7 +40,7 @@
@(:world-series-titles (meta giants))))
"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
assoc __ __)))

View file

@ -38,7 +38,7 @@
"You can do better than that - hand crafting FTW!"
(= '(* 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)))))
"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]})))