Skip to content

Latest commit

 

History

History
109 lines (74 loc) · 6.03 KB

2020-06-24.md

File metadata and controls

109 lines (74 loc) · 6.03 KB

Learning Clojure in Public - Week 1 Day 3

Another day, more Clojure concepts. This is day 3 of learning Clojure in public, with Athens' ClojureFam. I'm changing the the format of these posts and will be using the one I saw in my cohort-mate Mani's repository, learn-clojure-in-public, so here we go!

Expectations

Yesterday I was a little bit disappointed with my performance on 4Clojure, it took me a lot longer to complete 7 problems than the 20 I did on Monday. Difficulty goes up, so that's expected. I also don't know how to use map and reduce in Clojure so I reached for recursion every single time. So today I decided to focus on Clojure From the Ground Up. Luckily Chapter 4 covers reduce & co. as well as recursion. My initial expectation was to complete Chapter 4 and 5. However, after chatting with my cohort-mate I found out that Chapter 5 (which covers macros) can easily be skipped: it's complicated, not really necessary to contribute to Athens and I can easily do it at a later date. I would rather solidify my learning

What I learned

Clojure from the Ground Up -- Chapter 4

The first part of this chapter was introducing recursions which was nice to go over again, but so far I have the opposite problem: I use recursions all the time in lisps. I was happy to cover the if function though.

This chapter mostly felt like a laundry list of functions to manipulate sequences. I added them all to my function cheatsheet and it didn't really feel necessary to document this here, it would be redundant. I did learn some new things though: For instance that strings are sequences too! You can break a string into a sequence of characters with seq and rebuild it with apply and str like so (apply str (reverse "woolf")).

I was also quite impressed with some function, which I feel I have built myself many times over and are already there in Clojure. I found out that you can leverage quite niche tools from Java as well. If you want to figure out if a letter is uppercase or not you can call #(Character/isUpperCase %). Among the functions that I was happy to see, were:

  • frequencies will count how many times an element appears in a sequence. (frequencies [:meow :mrrrow :meow :meow]) will return {:meow 3, :mrrrow 1}
  • group-by group sequences by a function, for instance
user=> (pprint (group-by :first [{:first "Li"    :last "Zhou"}
    {:first "Sarah" :last "Lee"}
    {:first "Sarah" :last "Dunn"}
    {:first "Li"    :last "O'Toole"}])){"Li"    [{:last "Zhou", :first "Li"}   {:last "O'Toole", :first "Li"}],
    "Sarah" [{:last "Lee", :first "Sarah"} {:last "Dunn", :first "Sarah"}]}
  • And of course the famed reduce! It takes a function and will run it on the first two elements (unless you pass a starting value) and then run again on the result of that function and the next value. (reduce f default-value coll)

At the end of the chapter, the book walks you through building a function to find the sum of the products of consecutive pairs of the first 1000 odd integers. Here is my answer with a lot of help from the book:

(reduce +
	(take 1000
          (map (fn [pair] (* (first pair) (second pair)))
               (partition 2 1 (filter odd? (iterate inc 0))))))

The difference between collections and sequences

Every sequence is a collection, but not every collection is a sequence. The seq function makes it possible to convert a collection into a sequence. Any object supporting first and rest functions is a sequence.

Problems from Chapter 4

Chapter 4 of Clojure From the Ground Up is the first one that comes with exercises. Here are my answers and choices for the first three. I decided to skip the prime number question because there's probably better use of my clojure learning time.

Write a function to find out if a string is a palindrome–that is, if it looks the same forwards and backwards.

The first idea that I get here is always to use a recursion. I know I won't have any issue so I looked for another solution. An easy one that is almost cheating is reversing the string and making sure it matches:

(defn palindrome? [word]
    (= word (apply str (reverse word))))
Find the number of ‘c’s in “abracadabra”.

I can find of a few solutions for this one. How about using frequencies that I liked so much when I read about it in the chapter?

(defn countc [string]
    (last (first
        (filter (fn [pair] (= (first pair) \c))
            (frequencies string)))))

Another easy way would be to keep the c's only and the count the members of the sequence:

(defn countc [string]
    (count
    	(filter (fn [l] (= l \c))
         	(seq string))))
Write your own version of filter.
(defn my-filter [f xs]
    (reduce
        (fn [v e]
            (if (f e) (conj v e) v))
        [] xs))

(my-filter pos? [1 2 -1 1 0 1 -1])

4clojure

Today I did 16 4clojure problems which brings my total number of complete problems to 43! I have added my answers to the 4clojure document.

Takeaways

Even though I decided to skip Chapter 5 for now and didn't match my expectations, I am glad I did. I have taken in a lot information in the past few days. I wouldn't want to overload myself with too much, and time spent applying this new knowledge is probably better spent. It's not a sprint, but a marathon! I will make sure over the next few days to spend some time to review and make flash cards. This will most likely be tomorrow and over the weekend when I will either have less time, or will be away from a computer.

Today has been the most active day for our ClojureFam cohort: we've been exchanging tips, solutions and encouragement. I hope this continues like this.

Let's end the day with a tally of what I completed:

  • Chapter 4 of Clojure From the Group Up
  • 3 problems from that chapter
  • 16 4clojure problems