Overthunk

Functions, Introspection and Conj

Jun 24, 2020


Contents

Expectations

My primary expectation for today was to really try to get into a functional frame of mind. After yesterday’s revelations with the 4Clojure problems, I wanted to try to solidify those revelations and make sure that I was comfortable with them. On a more quotidian note, I also wanted to see how many of the 4Clojure Problems I could complete.

What I learned

Today’s learning material was Chapter 3 of Clojure from the Ground Up. It’s all about Functions. I still remembered some of the material I studied in Brave and True so I was able to get through the chapter without much ado.

Observations:

Threader macro forms are very elegant ways of expressing transformations on data. It allows us to express code like this :

(sort (rest (reverse [4 3 6 2 7 1])))

in this form:

(-> [4 3 6 2 7 1]
		(reverse)
		(rest)
		(sort))

The expression is passed down from expression to expression as the second item in the list. This form makes it much easier to understand how the data flows and transforms.

Introspection

There are so many cool Clojure introspection features that I felt it needs its own section.

type gives you the concrete type of an object. If type isn’t being useful, use supers to get all the super-types of the object. Supertypes is the set of all types that includes the given type. We can check if a given object is a function with fn?. We can get the documentation for a function with doc. Want to find the associated metadata for an object? Simply use (meta #'obj). Confused how a function is implemented? Fret not, source is here to save the day.

That a language is so honest and forthcoming with it’s fundamentals and source is amazing. Using functions like doc and source becomes second nature when you’re using the REPL and it’s incredibly helpful to have access to them locally.

On a personal introspection note, I’m slowly getting more accustomed to spending time gathering my thoughts, taking notes on something I found interesting so I can share them with anyone reading this. I’ve also often struggled with feeling inadequate with my technical skills and this feeling sometimes surfaces when working on challenging problems. But as I spend more time interacting with my fellow learners, I feel myself learning that it’s ok to struggle. Everyone learns at their own pace. I’ll get there too.

More 4 Clojure

‘Twas a good day in 4Clojure land. I spent quite some time throughout the day working on problems and I was able to complete an additional 20 problems.

There were quite a few interesting functions and concepts that I ran across like recur, for,partition and iterate . I definitely have to spend some time understanding the nature of recur in particular since I think it’s non-stack-consuming nature would make it useful for intensive recursion.

23 was a particularly vexing one. My initial solution for it used map and nth but that didn’t work since one of the test cases supplied a set as input. (nth doesn’t really make sense for an unordered collection).

(fn [xs] (map #(nth xs %) (range (- (count xs) 1) -1 -1)))

I tried a recursive function next.

(defn newrev [xs]
  (if (= (count xs) 2)
    (list (second xs) (first xs))
    (conj (newrev (take (- (count xs) 1) xs)) (last xs))))

This is very contrived way of solving the problem. Let’s break it down.

The base condition is that if the collection has 2 elements, we flip them and return. I made the assumption that the output had to be list. This impacted how I approached the problem, since conj behaves differently on lists and vectors.

@adrien made the other assumption leading to a more elegant use of conj

(fn rev [coll]
  (if (empty? coll)
    []
    (conj (rev (rest coll)) (first coll))))

However, in my opinion, @banditelol had the most elegant solution with reduce and conj.

(fn rev [coll]
  (reduce (fn [x y] (conj x y)) () coll))

Conclusion

In the end, I learned quite a bit about how reduce and conj and recursion works in Clojure. The next time I see a problem that needs any of these, you betcha I’m gonna kick it’s ass.

Let’s end this day with a nice little tally:

(repeat "See ya Tomorrow!")

You can also find this post on Notion.