Overthunk

Sequences and Recursion

Jun 25, 2020


Contents

Expectations

My primary goal for today was to learn Clojure in a focused and efficient manner. I’ve been noticing over the last few days that my learning schedule has been quite erratic. This is probably due to my tendency to get distracted easily and work on multiple things at the same time. But I wanted to overcome this and set a realistic schedule for myself.

What I learned

Today’s learning material was Chapter 4 of Clojure from the Ground Up. This was a chapter that I was really looking forward to since it handles recursion and sequences. As I mentioned in my post yesterday, I wanted to crystallize my understanding of recursion and using functions that operate over sequences.

The sheer number of functions in Clojure’s core library that handle sequences ( take, repeat, iterate, repeatedly, cycle, interleave, partition, group-by and more!) blew me away. It really does seem like there’s a specific function for anything you might possibly need to do over a sequence or collection. And since most of these functions produce lazy sequences, the computation is only done when it needs to. Another interesting thing about these lazy-seq ’s is that they invoke the underlying expressions only on the first call, and cache the result for future calls.

Chapter 4 also handles recursion. Using cons to recursively operate on a sequence is quite easy and the syntax mimics the mathematical form of recursion closer than some imperative languages. The book has an excellent example on how to use cons and recursion to create your own version of the map function.

(defn own-map [f xs]
	(if (first xs)
		(cons (f (first xs))
			(own-map f (rest xs)))
	(list)))

Here the base case is when xs is an empty collection. When that happens, we return an empty list. The recursive step is when we call own-map on the all elements but the first.

I found this explanation of recursion to not only be succinct but also eye-opening for how I approached it.

Recursion is folding an unbounded stream of computation over and over, until only a single step remains

On the note of unbounded streams of computation, normal recursion in Clojure allocates a stack frame for each recursive call. So if the computation is ”unbounded”, our program will consume a significant amount of memory. Other programming languages use tail-call optimization to avoid this. In Clojure, however, there is no automatic tail-call optimization. Clojure does make a loop .. recur idiom available to us which is non-stack consuming.

More 4 Clojure

I didn’t spend much time working on the 4Clojure problems today as I was more focused on working through Chapter 4 and understanding all the different concepts. I did however finish 6 more Easy problems that required the use of sequences. None of these problems were really as vexing as the ones from yesterday now that I’m more familiar with sequences and using reduce to manipulate them.

Learning how to Learn

As I mentioned earlier in this post, a goal of mine was to learn how to learn in a focused and more efficient manner than usual. I remembered reading about Pomodoro Timers in a Hacker News posts and how they helped people (especially software devs) focus and get into flow states. Some of my cohort members also mentioned that they’d found it useful. So I gave it a shot and I found it quite useful for concentrating. I was able to achieve a nice hour and a half of focused learning.

One thing I’m struggling with now is organizing what I’m learning into a single place. Currently, the way I take notes is quite scattered. I maintain some info in an Obsidian Vault using the zettelkasten method. However, I end up writing most of what I learn as comments in the code. This has the benefit of co-locating code and insights into a single place. At the same time, I lose the benefits of using a system like Obsidian in the first place.

Having said that, I am happy with the fact that I’m writing a lot more than I used to. This is the first time that I’ve ever written 4 consecutive posts. And I hope that I can keep this going with the support of my cohort.

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

(repeat "See ya Tomorrow!")

You can also find this post on Notion.