If you’re really into something, you’re bound to get asked
Why do you love X?
all the time. This question seems straightforward at first. If you do something all day, how can you not know why?!?
However, it’s often surprisingly hard to articulate. When you really love something, you don’t often think about why — you just do.
I can use code to build whatever I want!
Most people are fascinated by this.
Woah! I can’t do that. Sounds cool.
- Is it cool? Yes.
- Is it rewarding? Definitely.
- … But, is it really why I love programming? Meh.
After many years, I’ve finally cracked the code — I love programming because I love abstractions. It’s the same reason I love analyzing code, reading about startups, and more recently, studying number theory.
Abstractions, huh? Don’t you just build apps?
Believe it or not — the job of a good “software engineer” is not just to slam keys and output code but also to manage (and eliminate) complexity.
A common method of limiting complexity is cutting scope, but what if scope has already been cut, and things really are complex?
Depends on who you’re talking to. The average developer will likely tell you that’s why they’re there to solve the hard problems and then, produce a convoluted, unmaintainable solution. However, the adept “software engineer” knows that an increasingly complex system is not an excuse for increasingly complicated code, and that the correct approach is to abstract.
What’s in an abstraction?
The concept of an abstraction is simple. You take complicated stuff, simplify it, isolate it, build a human-friendly, generic interface around it, name it something cool, and reference it elsewhere.
Though not purely technical, here are some real-world examples of abstractions you may reason about frequently without even realizing:
- When you multiply X and Y, do you think about summing Y sets of X? Nope. That’s why multiplication exists, right?
- When we charge a customer at Segment, do we think about how that money gets from their bank to ours? Nope. Our friend, Stripe, does.
- When you buy something on Amazon, do you think about how it ends up at your door in 2 days? Nope. Their friend, UPS, does.
It turns out that there are a number of ways these abstractions could have been architected, and it takes a lot of planning to get them right… or even wrong for that matter.
The greatest challenge of abstractions is that they’re rarely static. The requirements of customers and thus, systems are constantly evolving, and abstractions need to adapt to this. For example, due to the rise of on-the-go purchases, payment processors like Stripe have been forced to not only support debit and credit cards in addition to banks but now, mobile services like Apple Pay, too. Fortunately, the engineering team at Stripe didn’t have to rewrite their entire system to implement these major changes. Instead, they’ve developed an interface that each payment source implements to execute common operations like “charge customer X $Y”.
A good abstraction is
- Flexible. An abstraction should be able to adapt or be easily adapted to an ever-changing set of needs.
- Simple. Remember, the point of an abstraction is to reduce complexity.
- Readable. Is it easy to use the abstraction without worrying about implementation details? Is it easy to figure out how it works?
On the contrary, a bad abstraction violates at least one of the above. Finally, the worst type of abstraction is one that shouldn’t exist at all, as they harm productivity by introducing unnecessary indirection.
Evidently, there are lots of concerns in creating abstractions, but managing these is inevitable, as abstractions are crucial to productivity. In a nutshell, programming is both the art and science of crafting better abstractions. That’s what makes it so challenging. That’s what feeds my brain.
As per usual, I’ll conclude with the idea that sparked this post—
Technology will definitely solve all our problems, but in the process it will create brand new ones. But that’s O.K. because the most you can expect from life is to get to solve better and better problems.
— Scott Adams, Author of Dilbert