class MyClass:
def __init__(self):
self._signature = None
def get_signature(self):
if self._signature is None:
self._signature = self.peek_register(SIGNATURE_ADDR)
return self._signature
We’ve all seen this code before. You have some getter that you want to return a value, but it’s expensive/inconvenient to initialize, so you cache it. You don’t want to do it when you make the class, maybe because not every class ends up needing one, maybe because it’s difficult to initialize in the constructor.
The singleton pattern, in other words.
The Python nerds in the audience are shouting at me “use functools! save a couple lines!” and maybe they have a point:
class MyClass:
@functools.cache
def get_signature(self):
return self.peek_register(SIGNATURE_ADDR)
(nevermind why it’s in a class, in the Real World the class has lots of other parameters. And also it has that peek_register
method, obviously)
This code is clearly shorter. All of the functionality is contained in a single place, the get_signature
method, where before it was spread across __init__
and get_signature
, potentially separated by a hundred lines or more. The person reading (or reviewing) the code doesn’t need to keep track of the _signature
variable. Happiness abounds.
But, there’s a glaring catch: That @functools.cache
line. With the _signature
case, if a reader didn’t know what’s going on they can use their handy ctrl-f key to figure out what’s going on. Everybody knows how if
statements work. But if the reader doesn’t know how @functools.cache
works, they’re out of luck. They just don’t know. No beans for them.
Back in the olden days, before GitHub and pull requests, code reviews would happen in a meeting room. You, the pleb developer, would arrange time on all the tech lead’s calendars to sit in a room with you, and you would walk them through your code one transparency at a time. If you’re a tech lead in this situation, and you want to know how @functools.cache
works, there’s not much you can do. Ask the developer? Asking developers whether their code does what they think it does is a poor review strategy (pro-tip: They’ll always say yes. Even after the bug reports come in). Thumb through a 500 page O’Reilly book?
Fortunately, it isn’t the olden days anymore. We have this thing called the Internet. If you Google “python functools.cache”[1] it takes you straight to the reference page in 0.54 seconds. Readers and reviewers will look it up the first time, and then they’ll know forever. It’s generally considered that the average adult native speaker knows in the range of 20,000 to 35,000 words (thanks, wordcounter.io). We have enough linguistic space in our heads to handle it[2].
But there’s the flip side to this as well: How do you, the pleb developer, know to use @functools.cache
when you write the above code?
The answer is, that’s a people problem. Sure, arguably you could dedicate 50% of your time to memorizing docs.python.org, but that’d be about as effective as memorizing the Esperanto dictionary to learn Esperanto.
And what’s the best way to learn Esperanto? By speaking Esperanto with Esperanto speakers. Read code. Write code. Practice code. And if you’re a reviewer, point out these things. Your review is about so much more than “is it functionally correct” - in fact, as we’ll discuss elsewhere I would argue that aspect only barely matters - but it’s also about teaching this language to the younger developers. Becoming a better developer is done by being near, and interacting with, better developers.
(as a wise man once said - if you find yourself as the smartest person in the room, you’re in the wrong room. Or you’re full of yourself.)
[1] Dear Google: you have too much power. Kleenexing you is the only way I have to fight back. Please don’t hurt my search engine ratings.
[2] I’m not a linguist, but if you wanted a linguistic reason that graphical programming languages are no good, find me a language which uses only pictures with lines drawn between relevant concepts. When you fail you’ll have your reason.
This blog series updates every week at Programming for Maintainability