Hacker News new | ask | show | jobs
by daniel-levin 2187 days ago
32 comments so far and no mention of the word budget. There's a great analogy between software engineering and construction. Does your organization build skyscrapers and gorge-spanning bridges? Or does it build driveways and swimming pools? Commercially developed software consumes capital to get something in return. Are the people spending capital budgeting for a driveway or for a skyscraper? Must it be done this month or in two years? Sure, those are false dichotomies, but they illustrate the point: it is desirable for the bosses to clearly define engineering spend.

Over-engineering can be avoided by carefully sticking to a budget.

For a lot of developers, there's a trade-off between rationality (in the sense of ROI) and feeling good. It doesn't feel good to make every engineering decision against a budget. My dopamine levels [0] skyrocket when I visualize making some component generic, or future proof. I come crashing back to earth when I realize the budget is for a driveway. Budgeting earns the bosses / customer / capital a better return. Engineering for future use cases or making things generic (or the mere anticipation thereof) is an easy way to get a massive hit of neurotransmitter that makes you feel good.

[0] Not a neuroscientist. But I think it's useful to label that spike of feel good and motivation. It may have nothing to do with dopamine.

4 comments

> My dopamine levels [0] skyrocket when I visualize making some component generic, or future proof.

I think I've successfully rewired that impulse in myself now, at least partially. I do get that feeling from imagining great systems, but I also get that dopamine hit from deleting old stuff and simplifying things as much as possible. We can ditch compatibility for API v8? Awesome, I just made my code smaller and we can scrap that entire abstraction layer! The service just lost 20% of its LoC :)

Honestly I think this may be a component: besides code shame (my code is bad and I don't want other people to see it) a lot of programmers also feel protective of their code. They want it to last forever, a paean to their skills. Writing simple code to throw away and refactor feels like a failure -- it should be perfect and eternal.
I totally understand the sentiment of writing elegant code that lasts forever, but I think developers need to manage their expectations a little better.

If you're writing foundational code for an operating system, then yeah, whatever you write is going to stick around for a while. (Which means you need to be a LOT more careful about what you write.)

If you're writing code for a mobile app or website, expect your code to get thrown out in a few months due to shifting requirements. I'm sure the Facebook app has been completely rewritten more than once, since they switched to React Native at one point.

If you're writing a JavaScript library, expect your code to be replaced next week. :D

I've reprogrammed myself to only get the dopamine hit when I delete old or unneeded code :-)
Deleting code is one of the most satisfying things in the world. Puff and gone are all the worries, all the bugs, all the maintenance hassle, all the limitations that code imposed on you.
You'd be able to sum it up as different stages of the reward process:

As you learn to code, it becomes increasingly satisfying to solve problems, so you write more code, which provides more satisfaction, but it gets unwieldy quickly and you start to get lost in the spaghetti.

As you learn to abstract, it becomes increasingly satisfying to create abstractions and manipulate them afterwards, allowing you to not get lost thanks to the now beautiful mental map of your code. But at some point in time it leads to excessive abstractions and issues start to pile up, and you can't quite make sense of the map anymore because everything is a little bit too generic and doesn't carry any more meaning, and such abstractions invariably leak through the lasagna. You usually start by writing more abstractions, but this only feeds the loop.

And finally, as you learn to delete code, you get back to simplicity, and the disappearance of the mental and causality weight associated with that deleted code becomes increasingly satisfying. You start inlining code, you start repeating code, only for the repeating patterns to emerge by themselves, you start thinking about names for those, and the names come naturally. Instead of powering through, there is a state of continuous, unstoppable flow based on a loop of implementation and emergence, where a giant Rubik's cube effortlessly solves itself by throwing it in the air and falling into place.

Very often projects are overbudgeted though. Not just cost and time, but quality of hires, salaries, promises to investors, and a competitor's feature list.

The scope of the project then expands to fill the budget.

Promises to investors and a competitor's feature list define your scope, not your budget. Salaries and quality of hires are correlated (but not causal), and are directly tied to cost as a component of it, along with time. Feature cost estimation can be as simplistic as:

Running Costs + (Weekly cost of Engineers * Weeks Slated) + (Hourly Cost of Managers * Hours in Meetings/Discussions) = Projected cost / required budget.

Increasing scope causes an increase in time spent both in meetings arguing about it and engineers working to build it, which increases the time side. Increasing salaries / quality of hires increases the cost side. Promises to investors or contractual obligations to partners/customers are non-negotiable increases in scope, so directly drive how much time something takes.

This is a good response. One of the things that has helped me temper myself is to explicitly consider the ROI of my work. If I do this, will I save more time in the long term than I expend doing it? Depressingly often, the answer is "no".

Software engineering has the potential to earn a lot of money with relatively little effort.

This is both a blessing and a curse: if I just do anything that I feel like, maybe only 5% of what I do would actually carry a profit – but that profit would be big enough to compensate for the other 95% of the time when I only do things that make me feel good without getting any real return from it.

If your goal is to produce maximum value, you have to think very long and hard about what projects you take on. It is worth taking the time to consider projects and research their viability, because very many of them won't pay off in the long run. You'll have to get used to saying "no" to anything that doesn't have an obvious route to profit.

On the other hand, if your goal is to have a little fun along the way and not only to produce maximum value, you can use this fact to your advantage! If you know you've rejected a bunch of low-value projects recently, you can afford to take on some low-value (but fun!) projects and still sit firm in the knowledge that you're still producing net value in total. Because the 40% of projects you've done that do produce a lot of value will easily pay for the other 60% that aren't obviously profitable. Or whatever ratio you settle at.