In my attempts to bring the âDAO insiderâ work that Iâm apart of into more public spaces, I felt it would help to step back and offer up a post on how I think about problems. I hope itâs of value to someone.
Background
So, a bit of context on my background and my approach to solving issues, what I mean by refactoring, and how I see names as the high-value place to start addressing change in our DAO.
In the arc of my career, Iâve spent a lot of time in and around code, but not just coding or programming specifically, but software design and software engineering. There are some concepts from these disciplines that I have internalized deeply enough that itâs hard sometimes to tell where those beliefs come from. This pops up in funny non-coding places for me these days, namely: names.
I hate things that are named wrong. I find acronyms or names that force you to translate their meaning every time you use them not just irritating but alarming. Like literally, when I hear a badly named thing, an alarm goes off in my head. This is not a subtweet at the branding work. I think that process stands and brands are a bit of a different animal.
But this alarm has been useful, and Iâve tried to pay attention to it. It comes from the years Iâve spent trying to organize software and systems, and I want to try and explain the importance of names in the hope that my recommendations to rename things can be seen for what they are: an attempt at good systems design.
Does all code crumble?
Iâm going to walk this back to the beginning.
At first, every programmer starts out just learning to code. Just building stuff that works is the hard thing.
But at some point, you encounter the next hard problem: codebases get big, they begin to get buggy, theyâre hard to work in, and eventually, they start to crumble. It feels like a fact of nature: code slowly rots.
Itâs in encountering this âfactâ that a fine distinction between just coding and something else emerges.
This next thing is software engineering. I think the Xooglers that wrote the book Software Engineering at Google own the best definition in the section Programming Over Time:
We propose that âsoftware engineeringâ encompasses not just the act of writing code, but all of the tools and processes an organization uses to build and maintain that code over time [âŚ] Software engineering can be thought of as programming integrated over time.â Software Engineering at Google
And now, as someone thinking about coding in terms of software engineering (including the processes and tooling), you see there are some projects where this âfactâ you saw early in your career doesnât hold up - there are cleaner, healthier codebases that donât slowly crumble.
You start wanting to build lasting things, things that scale, things that donât break down slowly over time. And in this part of your journey, youâll encounter a number of techniques: automated testing, test driven design, clean code, CI/CD, domain driven design, etc. Each of these contributes tools to let you build maintainable systems, not just at a code level, but at a human-to-human level, at a level where the organization of your work supports the maintainability of the systems you build.
Letâs zoom in on two turning points where naming things emerged as clear benefits to building maintainable systems
Cleaner Code
âAny fool can write code that a computer can understand. Good programmers write code that humans can understandâ â Martin fowler
Clean code was something I encountered fairly early on, and itâs a bit too big to get into, but one of the core parts of this is to write your code in a way that lowers the cognitive load of those that have to read it, or extend it later.
Clean Code - Reveal your intent:
var d: Int // elapsed time in days
a name that requires a comment does not reveal itâs intent
var elapsedTimeInDays: Int
the name of a variable should tell us the significance of what that variable contains
Clean Code - Naming - by Uncle Bob - part 3 | Bogdan Poplauschi
Kevin, hold it, why do I care. I donât code.
You donât need to code, relax. What this example shows is that the code itself now captures the meaning that the programmer was trying to express with the comment. When that var d
gets used later on, potentially dozens of lines of code later it wonât have that comment next to it, and the semantic meaning is lost. The programmer will just be seeing that d
in some new context and have to remember, âoh yeah, that means elapsed time in daysâ. The clean code approach is to give that d
a meaning, reveal the intent of that variable by naming it elapsedTimeInDays
so when the programmer encounters it many lines later, away from any comment or explanation of what that variable is, they can reason about it in line, no mental lookup or translation necessary.
So really good names in your code is great and we should all do it. Glad we all agree. Moving ON!
Building a Ubiquitous Language
Now that your code is clean and intention-revealing, youâll notice that you are still doing these mental lookups and translations in conversations with colleagues and in meetings with stakeholders. Youâll realize youâre constantly translating concepts from your non-engineering colleagues (business, design, product) into concepts in your codebase. If you inherit a legacy codebase or stick around a project long enough, these concepts can drift very far apart!
This higher-order problem is core to Eric Evanâs Domain Driven Design: Tackling Complexity in the Heart of Software (great title) in a concept he repeats (ad nauseam) called Ubiquitous Language.
Ubiquitous Language is the creation and maintenance of a shared vocabulary end to end - from the customer to the codebase.
For those that were in the event storm as we kicked off the build-out of the Grants Stack / Allo protocol, this ubiquitous language was part of what @lthrift and I were trying to establish.
But this is also meant to be a living practice:
Domain experts should object to terms or structures that are awkward or inadequate to convey domain understanding; developers should watch for ambiguity or inconsistency that will trip up design._
â Eric Evans
Framed in the negative, Evansâs ideas on what we should avoid:
- The lack of a common language, generating âtranslationsâ, which is bad for the Domain Model, and causes the creation of wrong Domain Models.
- Team members using terms differently without realizing it, for lack of a common language.
- Communication without using Ubiquitous Language, even if it exists.
- Creation of abstraction by the technical team for the construction of the Domain Model, which is not understood by domain experts.
- Technical team disregarding the participation of domain experts in the Domain Model, considering it too abstract for domain experts. But it is necessary that domain experts participate, because who can validate the Domain Model that was built?
- Developing the ubiquitous language - DDD - The Domain Driven Design
Got it, so we all use the same vocabulary to describe our system and weâre all good!
Yes. AND we make this a continuous process to check that our vocabulary matches reality and that we update our vocabulary every time our model, our strategy, and our macro context change. Everytime our Domain changes.
Refactoring the DAO
In computer programming and software design, code refactoring is the process of restructuring existing computer codeâchanging the factoringâwithout changing its external behavior. Refactoring is intended to improve the design, structure, and/or implementation of the software (its non-functional attributes), while preserving its functionality. Potential advantages of refactoring may include improved [âŚ] readability and reduced complexity; these can improve [âŚ] maintainability and create a simpler, cleaner, or more expressive internal architecture or object model to improve extensibility. - Code refactoring - Wikipedia
At the point Iâm at in my software engineering journey, I see how software, codebases, teams, and organizations are all helped tremendously by good naming.
As I think about and suggest refactorings to the DAO, naming is the low-hanging fruit. Because naming our work badly manifests in the accumulating friction from many repeated low-level translations, mistranslations, and misuse we incur when mapping other teamâs concepts onto our work. It is a tax we all pay daily to get things done: as we onboard new contributors, as stewards and workstream leads struggle to understand each otherâs budgets, in the anxiety our DAO Community expresses on the forum.
We need to reduce this mental burden.
This is at the core of my recommendations: How can we reveal intent in a name that everyone can use as they navigate the complex and abstract structures of these human and software systems we are building?
I see the solution in clean names mapping the work being done to the budgets we are funding. These are the slim workstreams as I see them. Itâs my belief the fear of a sprawling and unmaintainable DAO would largely be solved with clear, intent revealing workstream names.
Iâve formed this belief about the importance of naming over the years from my experiences with software engineering (in the broadest possible definition), and Iâm basing quite a lot of my recommendations on these beliefs.
I hope this post helps elucidate at least some of my process and may even help to introduce a tool into the systems design work we do here in organizing and running our DAO.