PurelyFunctional.tv Newsletter 334: Tip: can you fill in the blanks?
Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.
Clojure Tip 💡
can you fill in the blanks?
One of the cooler experiences of functional programming is when you start to see the arguments of functions as "blanks". That is, they are blanks that you have to fill in to get a successful function call. If you see the arguments that way, then you work backwards to figure out how to get arguments that will work.
For example, I was teaching a workshop last weekend. The task was to deal out cards to an x,y grid. Here's the function signature they knew they needed to use:
(deal x y picture)
The signature itself told us our next goal: we needed to calculate an x, a y, and to figure out the picture. But we didn't have an x and a y. We had an i, an index into the list of cards. We calculated x and y from that, and grabbed the "picture" from the list using the index. Then it's just a matter of "wiring it all up".
What surprised me was how unintuitive this was to beginner programmers. Seasoned programmers seemed to get it right away. But those beginners were overwhelmed by so much new stuff already that they were too overloaded to think backwards.
I find that when a library is well-designed, the arguments that a function needs all make sense and are close at hand. They are like holes in a puzzle, and all you have to do is find the piece that fits.
Killer Book 📖
The Mythical Man-Month by Frederick P. Brooks is a great book. I had never read it, and always meant to. I could see instantly why it's a classic. It is giving me quite a lot of food for thought, as well as a glimpse into what computing and product management was like back in the 1970s. This is also the book that originally used essential and accidental complexity as we know from Out of the tar pit.
Brain skill 😎
Organizing information helps you understand relationships. Sort the functions you know alphabetically. Then organize them another way, by category. Then sort then by return type. The more times you reorganize, the more patterns will emerge.
Currently recording 🎥
Last week I started a course called Property-Based Testing with test.check. Property-based testing (PBT) is a powerful tool for generating tests instead of writing them. You'll love the way PBT makes you think about your system.
It was a holiday this week, so I didn't record any new lessons. But I did plan some of the lessons.
The two stumbling blocks people have when doing Property-Based Testing are creating customer generators and coming up with properties to test. You will learn both of these skills. As usual, there won't be a lot of jargon, and we'll test some realistic functions that aren't obvious how to test.
Like I said last week, I'm really excited about this course. Property-Based Testing is one of those superpowers of functional programming.
I've made the first and fifth lessons free to watch. Go check them out.
Members already have access to the lessons. I'll open the Early Access Program next week. There is already 50 minutes of video, and looking at my plan, this one might be 5-6 hours. But that's just an estimate. It could be more or less.
Clojure Challenge 🤔
Last week's challenge
The puzzle in Issue 333 was to discover phrasal anagrams of a given phrase
I didn't get many submissions. The second part of this task was harder than the last one. You can check the submissions out here.
Part 1 was easy: you just needed to avoid spaces. But Part 2 required generating phrases of words from the dictionary. A simple filter wouldn't cut it.
I solved it with a recursive solution, but it wasn't as easy as I thought.
I should also mention a couple of problems with my problem statement that I only realized just before drafting this:
The dictionary that I recommended was the top 1000 English words. However, it didn't include the words "funeral", "moon", or "starer", which were part of the problem statement. My fault! I just added them. Check out the up-to-date dictionary here.
I did not realize how many anagrams would be generated. Most of them are gibberish. They are just words in random orders. Does anyone have any ideas how to filter them for some kind of grammatical correctness? For instance, my algorithm generates 1226 phrasal anagrams for "astronomer". The list includes "term son or a" and "or as Mr note".
This week's challenge
mergesort is one of the earlier sorting algorithms. It was developed and characterized by none other than von Neumann. It's a great example of a divide-and-conquer algorithm, and it's quite fun to write in Clojure.
So that's the task: implement mergesort.
You can find descriptions of mergesort by searching. But remember, it's easy in Clojure because recursion is the norm.
Note: Make sure it works on large lists. Try it on a list of 1 million numbers.
- Have it use
compareto work on more than numbers.
- Have it take a key to sort by.
clojure.reducersto implement a parallel version.
As usual, please send me your answers. I'll share them all in next week's issue. If you send me one, but you don't want me to share it publicly, please let me know.