Show passage from The Mythical Man-Month
Adding manpower to a late software project makes it later.
Writing and talks about software that influenced my thinking, and that I try to come back to regularly.
Small excerpts from the pieces can be toggled via the bullet points.
Adding manpower to a late software project makes it later.
Hope is not a strategy.
Complexity is anything related to the structure of a system that makes it hard to understand and modify the system.
Software engineering is programming integrated over time.
The ability to work and deliver in small batches is especially important, because it allows you to gather user feedback quickly.
A complex system may be an accurate reflection of our immature understanding of a complex problem.
Programming in this sense primarily must be the programmers’ building up knowledge of a certain kind, knowledge taken to be basically the programmers’ immediate possession.
Complexity is the root cause of the vast majority of problems with software today.
The complexity of software is an essential property, not an accidental one.
The human brain isn’t particularly good at basic logic and now there’s a whole career in doing nothing but really, really complex logic.
Producing beautiful software is not a goal. Solving complex technical problems is not a goal. Writing bug-free code is not a goal. Using sexy programming languages is not a goal. Add revenue. Reduce costs. Those are your only goals.
Don’t call yourself a programmer: “Programmer” sounds like “anomalously high-cost peon who types some mumbo-jumbo into some other mumbo-jumbo.” If you call yourself a programmer, someone is already working on a way to get you fired.
Instead, describe yourself by what you have accomplished for previously employers vis-a-vis increasing revenues or reducing costs. If you have not had the opportunity to do this yet, describe things which suggest you have the ability to increase revenue or reduce costs, or ideas to do so.
Profit Centers are the part of an organization that bring in the bacon: partners at law firms, sales at enterprise software companies, “masters of the universe” on Wall Street, etc etc. Cost Centers are, well, everybody else. You really want to be attached to Profit Centers because it will bring you higher wages, more respect, and greater opportunities for everything of value to you. It isn’t hard: a bright high schooler, given a paragraph-long description of a business, can usually identify where the Profit Center is. If you want to work there, work for that. If you can’t, either a) work elsewhere or b) engineer your transfer after joining the company.
Speed and reliability are often intuited hand-in-hand. Speed can be a good proxy for general engineering quality. If an application slows down on simple tasks, then it can mean the engineers aren’t obsessive detail sticklers. Not always, but it can mean disastrous other issues lurk. I want all my craftspeople to stickle.
It feels — intuitively — that software (beyond core functionality) should aim for speed. Speed as a proxy for efficiency. If a piece of software is becoming taurine-esque, unwieldy, then perhaps it shouldn’t be a single piece of software. Ultimately, to be fast is to be light. And to be light is to lessen the burden on someone or some task. This is the ultimate goal: For our pocket supercomputers to lesson burdens, not increase them. For our mega-powered laptops to enable a kind of fluency — not battle, or struggle — of creation.
The key is deliberative practice: not just doing it again and again, but challenging yourself with a task that is just beyond your current ability.
This messaging app I built for, and with, my family, it won’t change unless we want it to change. There will be no sudden redesign, no flood of ads, no pivot to chase a userbase inscrutable to us. It might go away at some point, but that will be our decision, too. What is this feeling? Independence? Security? Sovereignty?
Is it simply… the feeling of being home?
It took me another fifteen years to realize that the principle of Fire and Motion is how you get things done in life. You have to move forward a little bit, every day. It doesn’t matter if your code is lame and buggy and nobody wants it. If you are moving forward, writing code and fixing bugs constantly, time is on your side.
Fire and Motion, for small companies like mine, means two things. You have to have time on your side, and you have to move forward every day. Sooner or later you will win. All I managed to do yesterday is improve the color scheme in FogBUGZ just a little bit. That’s OK. It’s getting better all the time. Every day our software is better and better and we have more and more customers and that’s all that matters. Until we’re a company the size of Oracle, we don’t have to think about grand strategies. We just have to come in every morning and somehow, launch the editor.
Mindful choice of technology gives engineering minds real freedom: the freedom to contemplate bigger questions. Technology for its own sake is snake oil.
Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
Most experienced engineers own their work end-to-end: from getting the specification, through implementing it, all the way to rolling it out and validating that it works correctly. Product-minded engineers often go a step beyond this.
They consider their work done only after getting results on user behavior and business metrics. After rollout, they still actively engage with product managers, data scientists, and customer support channels, to learn how the feature is being used in the real world. It can take weeks to get enough reliable data to draw conclusions. Even though they might be working on a new project, they make checking on the results one of their top priorities. It’s not a time-consuming activity, but it needs that additional persistence from someone wanting to know: how is my work really doing?
Edit-compile-run is a software engineer’s work loop in which they (1) edit code, (2) compile the code (or start the interpreter), and (3) run the program or test suite. It’s the all-important standard workflow an engineer will run hundreds of times a day, and the speed at which it’s possible is one of the single most important factors for productivity in a codebase. Whether new code is being written or existing code modified, being able to run it and get feedback quickly is of paramount importance.
The ideal edit-compile-run loop for small programs is < 1s, or measured in a couple seconds. For larger programs, 10s of seconds is more likely and still acceptable, but go any higher than that and you’re entering the danger zone.
The fact is, distributed systems exist in a continual state of partial degradation. Failure is the only constant. Failure is happening on your systems right now in a hundred ways you aren’t aware of and may never learn about. Obsessing over individual errors will, at best, drive you to the bottom of the nearest whiskey bottle and keep you up all night. Peace of mind (and a good night’s sleep) can only be regained by embracing error budgets via service-level objectives (SLOs) and service-level indicators (SLIs), thinking critically about how much failure users can tolerate, and hooking up feedback loops to empower software engineers to own their systems from end to end.
so grug say again and say often: complexity very, very bad
grug understand all programmer platonists at some level wish music of spheres perfection in code. but danger is here, world is ugly and gronky many times and so also must code be
When should you over-ride YAGNI? When the cost of adding something later is so dramatically expensive compared with the cost of adding it early on that it’s worth taking the risk. On when you know from experience that an initial investment will pay off many times over.
Any of the ideas I’ve shown here could take an engineering team weeks (if not months) to add to an existing project—but with the right tooling they can represent just an hour (or less) work at the start of a project. And they’ll pay themselves off many, many times over in the future.
You don’t need to worry about scalability on your Rails-over-Mysql application because nobody is going to use it. Really. Believe me. You’re going to get, at most, 1,000 people on your app, and maybe 1% of them will be 7-day active. Scalability is not your problem, getting people to give a shit is.
Unless you know what you need to scale to, you can’t even begin to talk about scalability. How many users do you want your system to handle? A thousand? Hundred thousand? Ten million? Here’s a hint: the system you design to handle a quarter million users is going to be different from the system you design to handle ten million users.
Whether it’s building a new project from scratch, implementing a big feature, or beginning a large refactor, it can be difficult to stay motivated and complete large technical projects. A method that works really well for me is to continuously see real results and to order my work based on that.
I’ve learned that when I break down my large tasks in chunks that result in seeing tangible forward progress, I tend to finish my work and retain my excitement throughout the project. People are all motivated and driven in different ways, so this may not work for you, but as a broad generalization I’ve not found an engineer who doesn’t get excited by a good demo. And the goal is to always give yourself a good demo.
A rewrite made QuickDraw simpler, nearly six times faster, and 2,000 lines smaller.
The XY problem is a communication issue where an individual asks for help with their attempted solution (Y) rather than asking for help with their actual problem (X). This can lead to inefficient solutions and unnecessary complexity.
To those who read broadly, the hand of the LLM is so clear it’s as if the writer’s intellectual fly is open.
see, man, the bigger point here is that because of COVID and coding agents and remote work, things that have happened in the last five to ten years, right, you don’t really have the same structure of working next to someone and being given Jira tasks, etc. you have a lot more ownership, and you are unfortunately a little more siloed. so you never want to be in a situation where people don’t know what’s up with you. like, they shouldn’t be saying, “yeah, I don’t know what Sunil’s been doing,” and starting to get concerned, because they might only tell you when it’s too late. you want to be in a position where “Sunil doesn’t shut the fuck up about what he’s working on,” right? again, you don’t have to be obnoxious about it. you have to share your work.
and the reason you want to do this is you want to move away from an outcome-based mindset to momentum-based. like, you want to build a routine, because momentum is everything in this, and relationships are an even bigger thing in this. and by getting momentum going and fixing your relationships with other people, the thing you get is stamina. and that’s when you realize the real lesson, which is that big projects are not done with big efforts. it’s a big marathon, just slow, steady, incremental work. forget about a weekly basis, like a daily basis, an hourly basis, to the point that it’s muscle memory.
remember, you are in the reputation-building business, and software is actually downstream of that.
Values in your system afford shifting boundaries between anything.
This functional core is surrounded by a shell of imperative code… all based on values produced by the functional core.
Stupid, clear, easy to read code is what we’re looking for… Mostly, unclever code, that’s clear to read, that’s clear to understand is what we’re aiming at.
Programming is enormously expensive.. So even if we get a little advantage in programming, that’s worth a lot. If you were able to convince someone that this technology will save you 10% of your programming costs, that quickly translates into millions of dollars. If I can show you that a particular programming technology reduced risk of schedule variations, that quickly translates into millions of dollars.
If you ignore complexity, you will slow down. You will invariably slow down over the long haul.
The primary motivator for superlative engineers is mission, purpose. If you can’t explain why your company exists, don’t expect to ever find superlative talent. Ever. Doesn’t matter how much money you have. Compensation is the fourth most important thing. No higher, no lower.
The second you allow the numbers to be formalized, you’re going to get organizational jockeying, and then you ultimately have the mother of all perverse incentives: you are actually incentivized to not work with good people. Ranking is organizational cancer. Do not do it under any conditions.
Functionality, quality, and schedule: you get to pick only two. If you’re going to pick functionality and schedule, I’m out of here, and so is every other high quality engineer, because I don’t want to deliver shit.
Writing is nature’s way of letting you know how sloppy your thinking is. To think, to really think, you have to write. If you’re thinking without writing, chances are you’re fooling yourself. We’re only pretending to think.
When they’re telling you not to write a spec, they’re really telling you not to think. Examples are great to explain, but they’re terrible. They keep you from thinking. You think in terms of these particular examples. The real problem in programming is not to think of the easy cases. The hard cases. And you don’t get that with examples.
When you’re at a big tech company and you have a bunch of engineering problems, if you can’t solve them you just go and find more engineers. If you have a lot of money and you have a big problem, you use the money to solve the problem. It’s completely reasonable. But it doesn’t work for me, because I don’t have all the money, so I have to just solve it myself.
I write a server in a process. I can scale my service until I hit the limits of one computer, and then it’s all over. Fortunately I don’t need to build big distributed things. It turns out one computer can do an awful lot. A lot of the moderately large services I worked at Google could have been built this way.