I may not agree with it -- it might even make me angry -- but this is a short list of links that made me think.

John Carmack on Abstraction and Complexity


Abstraction trades an increase in real complexity for a decrease in perceived complexity. That isn't always a win.

John Carmack via Twitter

I agree, but the problem is it's subjective and may change over time as the project evolves.

Also, what abstractions are worth it for a new programmer vs. an old/expert programmer likely differ. I bet the expert (w.r.t. the codebase and language) would benefit from fewer abstractions, whereas a new coder would benefit from more. In short, the new person is trying to learn the code and just get by. The expert can likely find some efficiency gains by understanding the code closer to its true monolithic reality. I also bet the expert is better served by knowing the edge cases where an abstraction can leak.



Over-engineered is a phrase I hear often when talking about code (and designs in general) but what exactly is over-engineering? I ran into an article today with this to say:

Over-Engineering is when someone decides to build more than what is really necessary based on speculation.

by Fagner Brack - How To Accept Over-Engineering For What It Really Is

It goes on, but I think this is the most concise definition I've heard. Essentially, over-engineering is solving problems you don't have. [ SO ] That makes sense and seems to gel with what I think of as over-engineering, but the real question for me is how do I prevent myself from over-engineering? And why do so many programmers -- myself included -- keep doing it?

I think the answer is simple if we think about it in terms of risk and reward, because we want to invest in the future. We spend time, money, and complexity now to solve a problem we anticipate in the future, for potential profit. The problem is that not all bets pay off. Over-engineering is more precisely sunk costs with no benefit and likely a more complex design because of it.

Seen this way, over-engineering is less a vice of amateur programmers than it is a bad bet that anyone can fall for. You might be tempted to avoid over-engineering by simply designing for today and never planning for the future, but I think this too is a mistake. The world is filled with examples of software that no longer fits our needs, but which is difficult to change due to backwards compatibly, cost, mind-share and dozens of other reasons (e.g. Python 2 vs 3, JavaScript's primitives, etcetera).

This doesn't leave us with an easy solution, but it does suggest we should think carefully about how we plan for the future. For example, using API versioning in your first release is a good idea. It gives you a clean escape hatch to make breaking changes, while supporting old code.



Searching the web and desktop has improved tremendously since this was written (circa 2001), yet metadata is still with us. It can be useful, but it is important to remember why and how it can fail.

Motherf***ing Website [NSFW]


Multi-objective problems are hard. That said, many of the modern web's problems are self-inflicted but have obvious solutions. I'm talking about websites that are slow, don't handle multiple screen sizes and resolutions, and are not accessible (for the deaf and blind). We understand why it happened: we chose ads, aesthetics-focused design, and traffic-maximization over simplicity and focus on the content.

Tufte CSS


I don't have anything smart to say for this one. It's just a great looking style.

Four Pitfalls of Hill Climbing


A/B testing -- when it comes to product design -- is a big improvement over what came before. Just be aware of its' problems as well.

The Best Icon is a Text Label


Remember to test your UI's icons with real users. If something makes them think, you need to find a better icon or go back to text.

Email Isn't The Thing You're Bad At


People are bad about saying no. Each email is asking something of you and you need to be able to read it and decide right then if you will or not. Don't lie to yourself. Saying "maybe" is a great way to fill your to do list with lots of things you'll never get to.

A Significant Amount of Programming is Done by Superstition


We all work from memory which isn't perfect so it's important to occasionally revisit the primary sources. Did the API change slightly? Did you forget a feature? The same goes for your own code.

Why I Love Ugly Interfaces


Most problems are multi-objective. Optimizing for one goal can undermine another. Beauty and ease of use are important goals, but are often at odds with featureful software. It's ok to have a complex and thus ugly UI if the requirements are complex. This is not a free pass to ignore UX, just a reminder that everything should be made as simple as possible, but no simpler.

Also, what makes a UI easy for a beginner may hurt the efficacy of the advanced user.

Being tired isn't a badge of honor


Working hard is admirable. Working long hours -- in the long term -- is not. Habitually working long hours is a great way to burnout, wreck your health, and lose touch with loved ones. If you have to do it, make it a sprint, not a habit.