There is a lot to say about scope, quality and features (either discovered or planned), but the main things in my opinion are that:
- we don't know what is important, what is temporary and what will stay.
- whatever we do, we are likely to get it wrong the first time. Only time will tell us if we are right.
And sure, that's discouraging. But the solution out of it is stands on that criteria:
- always build things to minimize the cost of error, including the time passed to build the wrong thing.
From there, you get a whole lot of principles, practices and methods to minimize such cost, from iterative development to TDD, rapid feedback, Scrum, Lean, refactoring, continuous delivery, backlog, feature management, pair programming, weighted priotization, YAGNI, MVP, etc. All of them with their own flaws and high dependency on the circumstances, but with this common criteria to evaluate them: how good they are to reduce the cost of error in my own work.
I like that—minimize the cost of error. As opposed to minimizing the cost if we’re right. And I agree that the rest of XP derives from that one principle.
I have a couple other dimensions I sometimes highlight - quality of life and future capacity. Yes, maybe I could work extra hours this week for a critical thing, but it erodes my quality of life - burns out my relationships and health. Similar for future capacity - (which interacts w/QOL) - cut out learning, collaboration, etc. and maybe you finish this project, but you can end up with a team that falls behind what you need for the next project (or version:)
I've always wondered: why? I used to feel bad about not being able to accurately translate a "requirement" into an "estimate". I viewed that as a sign that I wasn't as good of a developer as I thought I was.:)
But over time I realized that software, no matter how simple we think it is, is actually complex. A code base, plus its dependencies, plus its infrastructure, results in dozens, if not hundreds of components that are tied together. And add versioning on top of that.
No developer can hold all of that information in his head and simply go through it, predicting what needs to change in which component.
I fully agree! Software is too complex than to foresee everything, plan ahead or give correct estimations.
And this always makes me think: is this complexity accidental or essential? Will we, one day, discover new ways of writing software that makes it as foreseeable as building a single-family home?
Or will it always be like this, simply because software is never just like building the thousandth instance of the house type 08.15. Because in the digital realm, copying is cheap, and if it was a mere copy of what’s already there, we would solve it by configuration. And also, it’s never just another arrangement of walls, doors, windows, pipes and cabling.
So, maybe any attempts to move software out of the „complex“ realm, into the „complicated“ (and more foreseeable) one, will just hold for a few edge cases (e.g. enhancing the possibilities of configuration using no-code approaches).
Oh the number of times I had to explain that it's not faster if I deliberately reduce quality...
I think quality is confusing in the software context because it mixes two things.
1) Quality that is visible to the user (bugs and UX), and (2) code quality, which is not immediately visible.
(1) really is just an aspect of the scope dimension. Sure, we can do more new features if we stop fixing bugs of the existing ones and dont care what the UI looks like.
(2) is something that should not be discussed with non-technical management at all, what are they even supposed to say about it? The developer should find the optimal level of quality based on the business needs.
> The developer should find the optimal level of [code] quality based on the business needs.
Maybe we don't mean the same thing by "code quality" but I find that whenever I dial it to the max there are fewer surprises and day-long debugging sessions down the line.
I think this goes for both higher and lower level design choices (eg naming, determinism, reproducibility, simplicity).
So I guess I take issue with "business needs" in some sense, but yeah, I guess there's a difference between one-off scripts and life-critical systems.
I don't think there's a "max" setting for code quality. But there is a business need that you don't spent days debugging a single bug, so the extra effort for higher code quality will eventually pay off.
Scope vs time vs money is a trade-off problem. You can't increase one without making something else worse.
Code quality is an optimization problem. There is a perfect amount of effort to spent on quality, where less will cost you more later, and more will never amortize.
I actually, instinctively, don't think that's true, but I don't have a good way to rationalize 🙂.
There's a point where you can inspect each function in a call tree and see that it either obviously works, or, if a problem is reported you can write a test that shows how it doesn't. The design choices that make that possible seem to me to be the minimal engineering effort necessary.
But yeah, sometimes I don't have the skill or patience to make it happen.
Can you exemplify what you mean by more or less code quality? I only have a very blunt "know it when I see it" feeling.
When I just write code it will have a certain degree of quality. It will probably have better quality than if a junior would have written the same thing, but it willl also not be perfect. I can now choose to spent time purely improving the quality of the code that exists. I postulate that I will always (in a realistic setting) find something to improve when I want to, i.e. I can always spent more on quality instead of starting the next feature. But there are diminshing returns. At some point, the business value of effort spent on quality will be less than of effort spent on the next feature. Finding that point is the challenge.
There is another point: the environment around the code, physical, industrial, human and commercial, change, and by itself, change the quality of the code, specifically its capacity to adapt to changes, especially unexpected changes. The code that was once of very high quality (at least on some aspects of quality) is now performing poorly, without having change a iota.
It's why constant small refactoring rather than large migration, and rapid feedback loops rather than long release process are so important to maintain a high level of quality efficiently.
You can have code that perfectly implements the requirements and so it has zero user-visible bugs and exactly the requested UI/UX -- but that code could still be monstrously poor quality and very, very hard to maintain/enhance in the future.
I'm probably wrong but I have feeling that most of your ideas assume product setup? What if my team work on a project with in advanced (badly defined) scope, optimistic estimates, hard deadline, and not so good budget. What if none of the stakeholder care about quality, or value, just about appearance of getting things done, just that everyone are respecting contract, and milestone. Are our pour souls out of the scope of your ideas? Do your ideas have organizational or contract preconditions? I'm not sure do I make any sense.
At this point you're set up for failure & blame no matter what you do. Any rewards go to others. What would define "success" for an individual programmer in such a situation? I suppose something like:
* Acting in ways you are proud of
* Learning as much as possible
* Building solid relationships
* Preparing for the best possible next job
* Not killing yourself or your family relationships in the process
I think my advice applies for reaching these goals.
Planning weakly is great, but it does prove challenging when interfacing with the organization. I used to give it an honest answer of the top undone ideas, which was bad because those were our worst ideas! Now I present on accomplisments and principals and it turns out that works way better.
But, Kent, you don't understand. Scope is immutable, too. 😅
The above is a faithful paraphrase of many people (usually executives and product "managers") in my career. If everything is P0…
But, yeah, managing expectations (or choosing better customers) is a hard-won skill. Regardless of how you phrase it, influencing and educating are skills that many of us weren't born with and don't enjoy employing. I'm grateful to be a place in my career where I can choose the leaders I follow instead of feeling compelled to be conscripted into whatever death march will pay me enough to eat. "Yes, and…" or "Yes, but…" are hard to say sometimes.
That's an interesting idea, Kent. Do you have more resources on "scope management"?
I’ve been thinking along the same lines about personal productivity. We’re always juggling time and energy—there’s only so much of both—and we all want to hit a certain level of quality in our work. If we keep that quality bar high, like you’re suggesting (which I’m all for), then managing the scope of what we take on becomes the key lever.
When we let scope drive our work, our time and energy naturally fall into place. It’s like a declarative approach to work—letting scope set the boundaries so we’re not constantly struggling to squeeze in more time or energy.
There is a lot to say about scope, quality and features (either discovered or planned), but the main things in my opinion are that:
- we don't know what is important, what is temporary and what will stay.
- whatever we do, we are likely to get it wrong the first time. Only time will tell us if we are right.
And sure, that's discouraging. But the solution out of it is stands on that criteria:
- always build things to minimize the cost of error, including the time passed to build the wrong thing.
From there, you get a whole lot of principles, practices and methods to minimize such cost, from iterative development to TDD, rapid feedback, Scrum, Lean, refactoring, continuous delivery, backlog, feature management, pair programming, weighted priotization, YAGNI, MVP, etc. All of them with their own flaws and high dependency on the circumstances, but with this common criteria to evaluate them: how good they are to reduce the cost of error in my own work.
I like that—minimize the cost of error. As opposed to minimizing the cost if we’re right. And I agree that the rest of XP derives from that one principle.
I have a couple other dimensions I sometimes highlight - quality of life and future capacity. Yes, maybe I could work extra hours this week for a critical thing, but it erodes my quality of life - burns out my relationships and health. Similar for future capacity - (which interacts w/QOL) - cut out learning, collaboration, etc. and maybe you finish this project, but you can end up with a team that falls behind what you need for the next project (or version:)
> Software ain’t like that. We do the work to discover what work needs doing.
♥️
I've always wondered: why? I used to feel bad about not being able to accurately translate a "requirement" into an "estimate". I viewed that as a sign that I wasn't as good of a developer as I thought I was.:)
But over time I realized that software, no matter how simple we think it is, is actually complex. A code base, plus its dependencies, plus its infrastructure, results in dozens, if not hundreds of components that are tied together. And add versioning on top of that.
No developer can hold all of that information in his head and simply go through it, predicting what needs to change in which component.
I fully agree! Software is too complex than to foresee everything, plan ahead or give correct estimations.
And this always makes me think: is this complexity accidental or essential? Will we, one day, discover new ways of writing software that makes it as foreseeable as building a single-family home?
Or will it always be like this, simply because software is never just like building the thousandth instance of the house type 08.15. Because in the digital realm, copying is cheap, and if it was a mere copy of what’s already there, we would solve it by configuration. And also, it’s never just another arrangement of walls, doors, windows, pipes and cabling.
So, maybe any attempts to move software out of the „complex“ realm, into the „complicated“ (and more foreseeable) one, will just hold for a few edge cases (e.g. enhancing the possibilities of configuration using no-code approaches).
Oh the number of times I had to explain that it's not faster if I deliberately reduce quality...
I think quality is confusing in the software context because it mixes two things.
1) Quality that is visible to the user (bugs and UX), and (2) code quality, which is not immediately visible.
(1) really is just an aspect of the scope dimension. Sure, we can do more new features if we stop fixing bugs of the existing ones and dont care what the UI looks like.
(2) is something that should not be discussed with non-technical management at all, what are they even supposed to say about it? The developer should find the optimal level of quality based on the business needs.
> The developer should find the optimal level of [code] quality based on the business needs.
Maybe we don't mean the same thing by "code quality" but I find that whenever I dial it to the max there are fewer surprises and day-long debugging sessions down the line.
I think this goes for both higher and lower level design choices (eg naming, determinism, reproducibility, simplicity).
So I guess I take issue with "business needs" in some sense, but yeah, I guess there's a difference between one-off scripts and life-critical systems.
I don't think there's a "max" setting for code quality. But there is a business need that you don't spent days debugging a single bug, so the extra effort for higher code quality will eventually pay off.
Scope vs time vs money is a trade-off problem. You can't increase one without making something else worse.
Code quality is an optimization problem. There is a perfect amount of effort to spent on quality, where less will cost you more later, and more will never amortize.
> Code quality is an optimization problem.
I actually, instinctively, don't think that's true, but I don't have a good way to rationalize 🙂.
There's a point where you can inspect each function in a call tree and see that it either obviously works, or, if a problem is reported you can write a test that shows how it doesn't. The design choices that make that possible seem to me to be the minimal engineering effort necessary.
But yeah, sometimes I don't have the skill or patience to make it happen.
Can you exemplify what you mean by more or less code quality? I only have a very blunt "know it when I see it" feeling.
When I just write code it will have a certain degree of quality. It will probably have better quality than if a junior would have written the same thing, but it willl also not be perfect. I can now choose to spent time purely improving the quality of the code that exists. I postulate that I will always (in a realistic setting) find something to improve when I want to, i.e. I can always spent more on quality instead of starting the next feature. But there are diminshing returns. At some point, the business value of effort spent on quality will be less than of effort spent on the next feature. Finding that point is the challenge.
There is another point: the environment around the code, physical, industrial, human and commercial, change, and by itself, change the quality of the code, specifically its capacity to adapt to changes, especially unexpected changes. The code that was once of very high quality (at least on some aspects of quality) is now performing poorly, without having change a iota.
It's why constant small refactoring rather than large migration, and rapid feedback loops rather than long release process are so important to maintain a high level of quality efficiently.
Isn't code quality related closely to the bugs and UX type?
You can have code that perfectly implements the requirements and so it has zero user-visible bugs and exactly the requested UI/UX -- but that code could still be monstrously poor quality and very, very hard to maintain/enhance in the future.
Ahh Sean Corfield replied to me 😳 I totally agree with you but let me fanboy a bit.
You helped me so much on the Clojurians slack like 5 years ago. I'm forever indebted. Got me into the paradigm!
I'm probably wrong but I have feeling that most of your ideas assume product setup? What if my team work on a project with in advanced (badly defined) scope, optimistic estimates, hard deadline, and not so good budget. What if none of the stakeholder care about quality, or value, just about appearance of getting things done, just that everyone are respecting contract, and milestone. Are our pour souls out of the scope of your ideas? Do your ideas have organizational or contract preconditions? I'm not sure do I make any sense.
At this point you're set up for failure & blame no matter what you do. Any rewards go to others. What would define "success" for an individual programmer in such a situation? I suppose something like:
* Acting in ways you are proud of
* Learning as much as possible
* Building solid relationships
* Preparing for the best possible next job
* Not killing yourself or your family relationships in the process
I think my advice applies for reaching these goals.
Not the answer I was expecting but I like it.
Planning weakly is great, but it does prove challenging when interfacing with the organization. I used to give it an honest answer of the top undone ideas, which was bad because those were our worst ideas! Now I present on accomplisments and principals and it turns out that works way better.
You can have longer cycles to synchronize with other folks. Be aware that the interface between the two will always be a bottleneck.
I like the "accomplish stuff & celebrate it" approach! Much easier to estimate 🤪
But, Kent, you don't understand. Scope is immutable, too. 😅
The above is a faithful paraphrase of many people (usually executives and product "managers") in my career. If everything is P0…
But, yeah, managing expectations (or choosing better customers) is a hard-won skill. Regardless of how you phrase it, influencing and educating are skills that many of us weren't born with and don't enjoy employing. I'm grateful to be a place in my career where I can choose the leaders I follow instead of feeling compelled to be conscripted into whatever death march will pay me enough to eat. "Yes, and…" or "Yes, but…" are hard to say sometimes.
That's an interesting idea, Kent. Do you have more resources on "scope management"?
I’ve been thinking along the same lines about personal productivity. We’re always juggling time and energy—there’s only so much of both—and we all want to hit a certain level of quality in our work. If we keep that quality bar high, like you’re suggesting (which I’m all for), then managing the scope of what we take on becomes the key lever.
When we let scope drive our work, our time and energy naturally fall into place. It’s like a declarative approach to work—letting scope set the boundaries so we’re not constantly struggling to squeeze in more time or energy.
Amen