Clojure Koans 12 Sequence Comprehensions Notebook

I'm excited to share with you my 12th notebook on the Clojure Koans!

Please remember, there are spoilers below.

With that, I hope you find the questions, skills, and Koan exercise answers below to be helpful in your Clojure learning journey.

{: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

Sequence comprehensions remind me of list comprehensions in Python. Is it effective to relate them to each other for learning purposes?

;; "Sequence comprehensions can bind each element in turn to a symbol"
(= [0 1 2 3 4 5]
   (for [x (range 6)]
       x))
;; question 12001: What exactly are "sequence comprehensions"?
;; question 12002: Is the usage of the word "symbol" above correspond to the usage of the word "constant" in other languages? How can the nature of bindings in Clojure be differentiated and explained?
;; skill 12001: Create a vector of numbers from 0 to N by using the `for` macro (?) and `range` function
Clojure
;; "They can easily emulate mapping"
(= '(0 1 4 9 16 25)
   (map (fn [x] (* x x))
        (range 6))
   (for [x (range 6)]
       (* x x)))
;; question 12003: Using a `for` loop (?) where you could instead `map` is considered poor practice in Clojure, correct?
;; skill 12002: Emulate mapping over a list without the `map` function by using a `for` macro (?)
Clojure
;; "And also filtering"
(= '(1 3 5 7 9)
   (filter odd? (range 10))
   (for [x (range 10) :when (odd? x)]
       x))
;; skill 12003: Emulate filtering a list without the `map` function by using a `for` macro (?)
Clojure
;; "Combinations of these transformations is trivial"
(= '(1 9 25 49 81)
   (map (fn [x] (* x x))
        (filter odd? (range 10)))
   (for [x (range 10) :when (odd? x)]
       (* x x)))
;; exercise 12001: Generate a list of numbers that are only odd numbers squared from number X to number Y by using sequence comprehension (and no higher order functions such as map or filter)
;; exercise 12002: Generate a list of numbers that are only odd numbers squared from number X to number Y by using higher order functions map and filter (and no for loops)
Clojure
;; "More complex transformations simply take multiple binding forms"
(= [[:top :left] [:top :middle] [:top :right]
    [:middle :left] [:middle :middle] [:middle :right]
    [:bottom :left] [:bottom :middle] [:bottom :right]]
   (for [row [:top :middle :bottom]
         column [:left :middle :right]]
       [row column]))
;; skill 12004: Dynamically (?) create new bindings and use (invoke/call) them in the same function block (?)
;; skill 12005: Create a for loop which iterates through two vectors and sandwiches / zips them together into a vector of vectors
Clojure

Closing Thoughts

I'm curious where sequence comprehensions are more useful/beneficial/effective compared with the commonly known Higher Order Function trio of map/reduce/filter. I think it will be fun to do some time/big O profiling of algorithms after I have completed all Clojure Koans exercises.

Runtimes (1)