2. Iteration
There are many ways to go over a dataset in clojure. Here are a just a few functions
● Reduce
● Map
● Filter
● Doseq
● Reduce-kv
● Plain old recursion
● Merge-with
● Loop
Any I didn't mention that you use frequently?
3. Reduce
This function is often the bread and butter of clojure projects. It is equivalent in
usefulness to the "for" from java. It's main function is to return a single value.
Super basic example:
(reduce + 1 '(1 1 1 1))
Which is 5. It would also work like
(reduce + '(1 1 1 1 1))
4. Reduce continued
Here is an example function that will apply a list of changes to a value:
(reduce (fn [value change] (change value)) value-x changes-list)
For instance if value-x was 1 and changes-list was '(inc inc inc) we would get 3.
5. Map
Map is the next most important clojure function. Here is a simple example:
(map inc `(1 1 1 1 1)) => (2 2 2 2 2)
It takes a function and applies it to every element of a list.
6. Map is lazy
Beware!!! It is lazy.
As in side effects will not take place. Values are calculated when used. So if we
have:
(defn hello[] (map print '(1 1 1 1)) "hello")
Then: (hello) => "hello" and will not print the 1's
By contrast, this function will print the 1's:
(defn hello-2[] (reduce (fn [_ value] (print value)) nil '(1 1 1 1)) "hello")
7. Filter
Filter will only keep elements selected by a conditional. For instance:
(filter #(> 1 %) '(0 0 1 2 3)) => (2 3)
Where #(> 1 %) is an anonymous function with % as the single argument. If the
conditional is true then the content is kept.
8. Rest
Any of these you would like me to cover?
● Doseq
● Reduce-kv
● Plain old recursion
● Merge-with
● Loop
9. Formatter
After seeing my code you are likely thinking it looks somewhat gross.
That is not nearly as bad as it can get.
Hence we have a formatter which you use like this:
Lein zprint sum.clj
It will create a new file called sum.clj.old that saved the unformatted version.
The formatted version will be in the original file name. These settings can be
changed.
10. Formatter examples
The following was a one liner:
(defn join
"two number addition"
[number1 number2]
(loop [times number1
total number2]
(if (> times 0) (do (recur (dec times) (inc total))) total)))
Feel free to try it yourself. It works magic. Just look up lein zprint and you should
find it.
11. State
In clojure we have immutable data types. So how are we supposed to store
changes?
ATOMS!!!
Here is an example atom creation:
(def status (atom false))
If we want the value of status we simply do @status
12. Changing state
If we want to change status, we could do:
(reset! status 1)
Now it is 1. Atoms are great because they are thread safe. That is why we go to this
trouble.
The other way is to do:
(swap! status inc) which would now give us 2 if we did @status.
For more examples ask about my evolution game.
13. Destructuring
Here is a super simple example of destructuring on a vector:
(let [[x y] [1 2]] (print x " " y)) prints 1 2
What we are doing here is vector destructuring where in the let statement we are
setting x to 1 and y to 2.
This can also be done with functions
14. Destructuring with functions
Ever wanted to have an easier way to pass the values of a map as parameters to a
function? Well today is your lucky day.
(def john {:height 10 :age 12 :weight 80 :first "john" :last "doe"})
(defn person-print
"A function that will print stats about the given
person from the person hashmap."
[:keys [height age weight first-name last-name]]
(print height age weight first-name last-name))
(person-print john)
The above will print 10 12 80 john doe
15. Places to go if you want to learn more
https://clojure.org/api/cheatsheet
https://clojuredocs.org/clojure.core/map
https://clojuredocs.org/clojure.core/reduce
https://clojuredocs.org/clojure.core/filter
https://github.com/kkinnear/lein-zprint
https://clojure.org/reference/atoms
https://clojure.org/guides/destructuring
16. Thank you for listening!
Please ask me any questions you have
Written and presented by Jason Basanese