Avi Drucker / Apr 19 2021
Remix of Clojure by Nextjournal
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.