some news before we get to the essay
š Iāve published a draft of the Introduction to Runnable Specifications. I normally write the intro at the end, once I know what Iām going to say, but I had a lot of people holding back comments because they thought I might address them in the Introduction. Well, this is what I wanted to say in the introduction, so now thereās no confusion. As always, I welcome comments and suggestions, critiques and insults.
š·ļø If you want a copy of Grokking Simplicity (GS) in any format, you can use the coupon TSSIMPLICITY for 50% off. GS is the book that I wanted to recommend to people when they were curious about functional programming.
š Office hours have begun again in earnest. Iāve been solving the live stream problems. I think Iāve got it down now. Thursdays!
š§ I will be speaking in Leuven, Belgium, at Heart of Clojure this year. This looks like a wonderful, human-centered conference. Iām happy to be going. If youād like to go, the first 10 people to buy tickets with this link will get a 5% discount.
Hiding in plain sight
I once met one of the legends of software design, Sandi Metz, after her talk. A group of people had formed around her in the hallway. Most seemed content to absorb her presence. They didnāt say much. But I had an agenda.
Her talk was great. She showed how you can identify hot spots in your code. Theyāre the files with lots of code complexity that also get committed to a lot. She explained a lot about software design, how code gets to be a mess, and more. Then she refactored some code by following code smells and made everything better.
Like I said, it was a great talk, and I had studied her other talks and read her book. But something didnāt sit right with me. I just didnāt know what. I have tried to explain it many times, including in the talk I gave at the same conference a few hours before. Basically, I donāt think refactoring is enough.
So thatās what I said: āI donāt think refactoring is enough.ā
āYou have to trust that it is,ā she replied.
Ugh. So unsatisfying. Of course, itās my fault. The way I phrased it, it sounded like I didnāt have confidence in my own refactoring skills. On the contrary, I use refactoring all the time, and I often have experiences like she showed in the talk where I use refactoring to find a better way to express the problem. But at the same time, what she showed us was more than refactoring. Explaining what she was doing as ārefactoringā was not enough. Refactoring just means changing the code. It doesnāt mean making it better in any particular way. And it certainly didnāt explain how she chose which refactorings to do.
Hereās a quote from an interview with her and her co-author, Katrina Owen, talking about some of their process for writing their book, 99 Bottles of OOP.
KATRINA: Over and over again, we would have this disagreement. Exactly what Sandi said, "This is wrong," and I'm like, "It can't be wrong because the rule says it's right." And we'd arrive at an understanding of a better rule.
SANDI: Yeah.
āon the Greater than Code podcast (transcript)
Sandi would present a rule, Katrina would follow it to the letter, and then Sandiās 35 years of experience would jump in and say, āNo, thatās not right.ā It made me think of all the rules and principles and patterns that require years of experience to use correctly. Theyāre too common in the industry.
The two co-authors shared their story as an example of the wonders of collaboration. But it made me feel like all of their talk about rules was not really getting where they thought it would. I just donāt believe rules can capture 35 years of software design experience. Either they miss the mark or they are so convoluted that you canāt use them.
For instance, this is what one of the rules looks like after going through their collaborative process:
Flocking Rules
1. Select the things that are most alike.
2. Find the smallest difference between them.
3. Make the simplest change to remove that difference:
a. parse the new code
b. parse and execute it
c. parse, execute and use its result
d. delete unused codeAs youāre following the rules:
In general, change only one line at a time.
Run the tests after every change.
If you go red, undo and make a better change.
These are the mechanical refactoring rules they state. But they come after a lengthy (10 page) discussion of how to choose what to refactor that includes no rules as consise as these. I just donāt buy that you can do this with rules alone.
Yet I believe in her. She has this skill. She does it. What was she doing? After a careful rewatching of one of her better talks on refactoring, I saw the answer. Sheās using refactoring, yes, but sheās using it to build a better domain model. She overemphasizes the mechanical changes to code structure and underemphasizes her deep intuitive process of seeking out a good domain model.
Once I saw it, I began to see it everywhere. Not just in her talks, but everywhere. Any time people were talking about design, they were really talking about the domain model. They just never explicitly mentioned it. But itās there.
For instance, 99 Bottles of OOPās third chapter is called āUnearthing Concepts.ā Itās about following duplication to find important concepts in the domain (which they call āunderlying abstractionsā or āunderlying conceptsā).
Section 3.7.3 (āNaming Conceptsā) discusses how to decide what to name a method based on words from the domain
If you were to ask your users, āWhat kind of thing is a bottle?,ā they wouldnāt reply āItās a unit.ā Instead they might call it the container.
Throughout, thereās a lot of discussion of code smells and coding problems (like complex if statements), but the end goal of a lot of it is āfinding the right abstractions.ā That sounds like domain modeling to me.
In Nothing is Something, she use the Null Object Pattern to make functions total and also to show that many abstract things can be part of a domain.
When you first started writing in OO, it was really easy to see that real things could be modeled as objects. The chair that you're in. The person beside you.
And it didn't take long once you started writing code to figure out that more abstract things can be modeled usefully.
So, in the end, it seems that both code quality and domain modeling are important, just as style and substance are essential to creating a beautiful novel. I donāt know why we focus more on the code, but I hope to refocus us, if only just a little, back onto the domain, in my upcoming book, Runnable Specifications.
Refactorings can be useful "in the small" but to refactor "in the large" definitely means being guided by _something_. Articulating that "something" isn't always easy and I think "domain modeling" is doing a lot of heavy lifting as the explanation -- the key phrase to me is "deep intuitive process" and I've always wondered how we can better teach developers about that?
×ַּרְ×Ö¶Ö£× ×Ö¼Ö°×ַרְ×Ö¶Ö£× ×ÖøÖ×Ö·× ×Ö°Ö×Ö“Ö××©× ×Ö·Ö£×Ö·× ×¤Ö¼Ö°× ÖµÖ½×־רֵעֵֽ××Ö¼×
As iron sharpens iron, so a man sharpens the wit of his friend.
https://www.sefaria.org/Proverbs.27.17