Avi Drucker / Apr 22 2021
Remix of Clojure by
Nextjournal
Clojure Koans 15 Destructuring Notebook
Original Koans repository: https://github.com/functional-koans/clojure-koans/
Spoilers Alert
{:deps {org.clojure/clojure {:mvn/version "1.10.1"} ;; complient is used for autocompletion ;; add your libs here (and restart the runtime to pick up changes) compliment/compliment {:mvn/version "0.3.9"}}}deps.edn
Extensible Data Notation
{:hello (clojure-version)}0.1s
Clojure
Initial Thoughts
Oh man, I think these Koan exercises all need descriptions.
At the point I'm feeling a strong need for descriptions, I can envision smaller, more atomic examples, that build up more gradually.
(def test-address {:street-address "123 Test Lane" :city "Testerville" :state "TX"})Clojure
;; "Destructuring is an arbiter: it breaks up arguments"(= ":bar:foo" ((fn [[a b]] (str b a)) [:foo :bar]));; question 15001: What exactly is happening here?;; question 15002: Is this an example of destructuring?;; question 15003: What is being destructured and how?;; question 15004: What does the prompt above mean by "breaks up arguments"?Clojure
;; "Whether in function definitions"(= (str "An Oxford comma list of apples, " "oranges, " "and pears.") ((fn [[a b c]] (str "An Oxford comma list of " a ", " b ", and " c ".")) ["apples" "oranges" "pears"]));; question 15005: What is the relevant skill here?Clojure
;; "Or in let expressions"(= "Rich Hickey aka The Clojurer aka Go Time aka Lambda Guru" (let [[first-name last-name & aliases] (list "Rich" "Hickey" "The Clojurer" "Go Time" "Lambda Guru")] (str first-name " " last-name " aka " (clojure.string/join " aka " aliases))));; question 15006: Is this an example of rest parameters? If yes, how so? If no, what is a clear example of rest parameters?;; question 15007: Is there a relationship between destructuring and rest parameters, if so what is it, and if not, why might they seem related?;; skill 15001: Define rest parameters (?) in a `let` function/macro (?)Clojure
;; "You can regain the full argument if you like arguing"(= {:original-parts ["Stephen" "Hawking"] :named-parts {:first "Stephen" :last "Hawking"}} (let [[first-name last-name :as full-name] ["Stephen" "Hawking"]] {:original-parts [(first full-name) (second full-name)] :named-parts {:first first-name :last last-name}}));; question 15008: Was there a more idiomatic/concise/preferred way to solve this Koan exercise?Clojure
;; "Break up maps by key"(= "123 Test Lane, Testerville, TX" (let [{street-address :street-address, city :city, state :state} test-address] (str street-address ", " city ", " state)));; question 15009: What is meant here (purpose/intent and result/outcome) by "break up maps"?Clojure
;; "Or more succinctly"(= "123 Test Lane, Testerville, TX" (let [{:keys [street-address city state]} test-address] (str street-address ", " city ", " state)))Clojure
;; "All together now!"(= "Test Testerson, 123 Test Lane, Testerville, TX" ((fn [[first last] {:keys [street-address city state]}] (str first " " last ", " street-address ", " city ", " state)) ["Test" "Testerson"] test-address))Clojure
Closing Thoughts
I struggled to pull skills out of all the Koan exercises in this section. As I come to better understand destructuring in Clojure (which seems to behave slightly different than in other languages I have learned) I think I can better tease apart its nuances and atomic components.