PurelyFunctional.tv Newsletter 327: Tip: always be decomplecting
Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.
Clojure Tip 💡
always be decomplecting
Decomplecting is design. It's a way to understand a problem better. And code is an encoding of the understanding we have of the problem. always be decomplecting asserts that our code should reflect the contours of the problem.
Whenever I'm coding, I start to pull the code apart into smaller bits. I look for places where pulling it apart feels natural. I know that's quite subjective, and require a lot of experience. But it's also an iterative process, so it's not something I get right on the first try.
However, I have some questions I ask myself:
- Can I imagine using this on its own? A thing that can be used on its own should probably be its own function.
- Can I think of a good name for each of the parts? If there's a good name, there's a good chance it can live on its own.
- What are the responsibilities of this code? Surely, there are ways to describe the responsibilities at different levels. Are all of those ways clearly expressed in the code?
- What are the topics going on in this code? Sometimes, instead of looking at "responsibilities" or "actions", "topics" gives a different perspective. For instance, "configuration" might be a separate topic from "storage".
- What are the semantic levels involved? Am I crossing different levels of meaning? For example, treating a hashmap like a hashmap, and in the next step treating it like a Person record? Separate those out.
These questions help me feel my way around a refactoring. Do you have questions you ask yourself? Let me know and I'll share them.
RDD Course Launch 🚀
Folks, if you are reading this, the course has launched! Repl-Driven Development in Clojure is now available for purchase at a 50% discount. That discount will last till the end of the week, so if you want to buy, now is the time. By the time the next newsletter comes out, the discount will be over.
There were three new lessons this week.
Editing servers and other long-running processes goes over some tips and techniques for applying RDD to servers.
Some reloading tools some people use talks about clojure.tools.namespace, Component, mount, and Integrant. It describes the problems they are solving and when I think they should and shouldn't be used.
Recap and Conclusions wraps up the course.
And those are all of the lessons. In total, there are nearly nine hours of video in this course. The course explains the background behind Repl-Driven Development (RDD), the practical nuts-and-bolts, and the high-level guidelines to keep you moving toward flow and deep engagement with your software.
I have gotten so many thanks and advice from people who have followed along with the early access for the course. The course is better because of their questions, comments, and suggestions. I'm so excited by this course because people seemed to lap it up. It seems there aren't enough demonstrations of real RDD in video form.
And now it's available at a serious discount, for one week.
Of course, members of PurelyFunctional.tv get the course as part of their membership for no extra cost. Just another benefit of being a member.
Check out the course. The first lesson is free.
Clojure Media 🍿
Clojure/north videos are coming out! You can watch them here (YouTube).
Brain skill 😎
Cross-pollinate. Learn outside of your normal bubble. Read about other programming languages. Read about math ideas. Read about biology, and poetry, and history. It exercises your ability to learn, and you never know what ideas will come out of unrelated fields.
Clojure Puzzle 🤔
Last week's puzzle
The puzzle in Issue 326 was to write a function to maximize the concatenation of integeres.
You can see the submissions here.
I think it's cool that most of the implementations followed the same basic structure. A lot of these puzzles were defined for imperative languages where this kind of thing is a bigger challenge. But in Clojure, it's just a single pipeline. Here is Steven Proctor's solution, which is illustrative of the common solution:
(defn maxcat [l] (->> l (sort-by str) reverse (clojure.string/join "") bigint))
This week's puzzle
Largest Lynch-Bell number
A Lynch-Bell number is an integer that is divisible by each of its base-ten digits. The digits have to be all different (no repeated digits) and it can't have a 0 because you need to divide by it. For instance, 135 is evenly divisible by 1, 3, and 5.
The task is to implement a search for the largest Lynch-Bell number. Feel free to get clever with reducing the search space if the search is not fast enough.
As usual, please send me your implementations. 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.
PS Newsletter Maintenance 🔧
Folks, I migrated the email service I use for this newsletter. You're now reading this on the new service.
Email migrations can be tricky. I would really appreciate it if you report any issues with deliverability. That includes not receiving the email, the email showing up in spam, and any warning messages you get in your email client. I want to make sure you can get the emails you want.
The most obvious benefit to you of the new system is that I am no longer tracking links you click on. Unlike my old system, my new system can turn off link tracking. You actually know where the link will send you before you click. And nobody is tracking the clicks.
I also believe the new system has better deliverability, meaning you're more likely to get it. I am still tracking email opens, because I would like to make sure that people are getting the email. Open tracking is the best way to assess the health of your email delivery system.