Did you know that our native language affects what we think?
We think of words as tools to communicate reality. But get this: they also impact how we experience reality.
Here’s a cool example: Russian speakers have separate words for light blue and dark blue, so they see the colors as fundamentally different rather than shades of the same hue—sort of the way we English speakers see red and pink as different colors, even though those are also different shades of the same hue.
Here’s an even cooler one: English speakers say “Tom accidentally broke the wine glass.” But the Spanish translation of the same idea is closer to “The wine glass broke itself on Tom.” Do you see how the Spanish representation doesn’t center blame? Here’s the kicker: after a while, Spanish speakers are less likely to remember who knocked over the glass than English speakers. (There might be a lesson here for tech teams, but we’ll skip it for today).
I have chosen just two examples, but there are several.
Stick with me. I swear this is going to be about code.
The way we express a concept affects how people experience it within a language, too.
Let’s take an example: crime. Evidence suggests that the metaphors we use to describe crime affect how we try to reduce crime. When we compare crime to a beast, we’re inclined to hunt it down. When we instead compare crime to a contagion, we’re inclined to treat root causes. Cognitive scientist Lera Boroditsky gives a brilliant TED talk on this:
So a metaphor implicitly persuades us toward certain ideas. And when it does, it closes mental doors toward other ideas. We use metaphors as framing devices. What does a frame do? It focuses us on an aspect of something, while drawing a border around it.
And that is what programmers do every time we name our variables, our classes, and our ideas.
So each time we name something, we limit ourselves. Alan Kay, the guy credited with coining the term “Object-Oriented Programming,” mentioned after the fact that he wishes he had instead chosen a name about messages.
We’re committing the transactional fallacy when we send a message to an object and then wait around to get a response. We do this all the time. Synchronous code is this. Avdi characterizes it brilliantly:
The transactional fallacy has a symbol…it’s the spinning beach ball of death. This is the universal symbol that a programmer expected something to either finish or fail more or less instantaneously and it did neither of those things.
Hey! We don’t do that all the time…do we? We have asynchronous code. We have fire-and-forget calls.
Even so, we build whole applications around things users cannot do until they’ve done some other unrelated prerequisite. And it’s so common that users expect it.
When I register for a free trial, I am surprised if I don’t have to enter my credit card information to sign up. Even though they’re not supposed to be charging it yet!
At my last job our product design case interview went like this: design an app to help ping pong players sign up for tables. I cannot tell you how many candidates went “Well, first thing’s first…login.” Then we spent 40 minutes talking about login. We didn’t get to the needs of ping pong players until the last 5 minutes of the interview. This happened often.
Avdi has a great example of a real-world process that the average application would totally botch:
Whenever I take my kids to a new doctor, I have to spend 15 minutes filling out intake forms…Hate it.
But at least I know that if I put the clipboard down, the forms won’t reset themselves!
At least I know that if my kid gets called back into the office, I can take the forms with me into the consulting room, and I can continue filling them out asynchronously while my kid is getting checked out.
At least I know that I can leave some fields blank—if they really need to know, they can call me.
I shudder to think what the intake experience would be like if it were designed by a programmer.
A programmer? That’s…me.
I don’t want to design systems in ways that make people shudder.
So I feel inspired to rethink some of the systems that I work on as a software engineer and as a data scientist. But how?
This is how Avdi describes his current approach to program design:
If there is one fundamental change in how I’ve approached programming in the last few years, it’s this: I’ve started trying to look for processes. I’ve started trying to model systems as processes made up of more processes.
What does it mean to build graceful processes?
Avdi mentions a list of things that contribute to building graceful processes. I don’t want to spoil the talk for you, so I’ll let you watch it for this. The list starts out technical, and it gradually becomes more personal and less about programming. You’ll hear inspiring stories and pick up valuable life lessons.
One thing you won’t hear: code examples. That’s because code examples would bring this inspiring keynote to a screeching halt. (Trust me. It’s extremely hard to effectively mix high-level inspiration with low-level explication.)
I still love code examples, though. Working through concrete examples helps me understand how I can operationalize a credo like “build graceful processes.”
Code examples work great in blog posts.
So we’re going to start a new blog series: Adventures in Process Design. Over the next few posts, we’ll work through examples of processes—at the class level and at the application level—that we can reconsider and redesign. I hope that you enjoy them, and I’ll be eager to hear your thoughts about them!
If you just cannot wait for the next post in this series and you want to read some other stuff I’ve already written, I recommend:
This three part series on the history of API design. Lots of fun anecdotes, plus a little myth-busting!
This ongoing series on leveling up for programmers—or maybe anyone, but I’ll stick to what I know.
How to socialize big changes at work—the interpersonal skills you might need to redesign your whole app as processes ;).