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.

Runtimes (1)