You’d need to find a niche that values this level of quality, but if that exists, and if the theory is true, then there’s your gold.
I come to think that the whole concept of MVP/prototype became a bane to software development when the management/business side got aware of its existence. Architecture and design sessions can be skipped because we just build a prototype.
I have yet to see a prototype that did not end in production. It's "good enough software", let's move to the next feature.
When you are really lucky you can revisit your prototype a year or two later and try to improve it's design now that you got some data on its actual usage, but you have to figure out again, what the heck you actually did...
https://course.ccs.neu.edu/cs5500f14/Notes/Prototyping1/plan...
git add program
...
... #first implementation works; time to rewrite
git add newprogram
...
... #second implementation works; bury the first
git rm program; git mv newprogram program
...
This keeps my directory relatively clean, as I only have my previous attempt and the current refactor around at any given time. It also keeps the git history clean for the living files, and keeps the diffs nice and tidy.It's preferable to work in branches and rewrite and refactor incrementally whenever possible, merging the new code in as things progress at convenient milestones.
Then the history documents which functionalities in the old implementation became what files and lines in the new implementation.
That information can be very helpful when the rewrite breaks previously working functionality and customers are upset, especially if the rewrite authors aren't even around anymore.
That's the goal of this practice. Throw it all out and rewrite from scratch.
> That information can be very helpful when the rewrite breaks previously working functionality and customers are upset, especially if the rewrite authors aren't even around anymore.
I'm talking about writing non-releases. The entire structure of the code, algorithms, data structures, API / CLI must not be preserved. Anything that stays constant between non-releases is either (a) a good idea or (b) a stone unturned. Rename variables, split and join modules, violently reorder function arguments... nothing is off-limits. After I've been through a few rounds of this, the first release should be entirely free of inessential warts (and maintenance is typically quite easy at this stage).
After the first release, I'm a stickler about backwards-compatibility and my development pattern is closer to what you're suggesting.
Among folks who know me, I've got a reputation for writing clean, optimized code. It isn't because I'm good at writing clean code; it's because I'm good at throwing away ugly code and I'm very reluctant to share code that doesn't meet the bar.
In my experience my MVPs often end up in production and that utopia of iterating in isolation is fairly short-lived.
Yes yes, have points, well done, but it’s a boring low effort class of comments that applies to nigh every single idea ever, and skips the interesting or important bits - in this case whether it produces better software or helps understand things - in favour of a cheap vote grab. “It’s not universally applicable” - no, nothing is.
and you don’t sound cynical you sound like you’re trying to dismiss and status grab, like someone talking about the “out here in the real world”.
Still, my point stands: I am not sure if this is really a matter of “SOME people can’t do this”, I suspect it is the other way around: “SOME people can do this... because they are working on free software, on their own personal project, on programs or systems that do not have any TTM aspect”.
And it is not just a matter of "deadlines" either: if your code is part of some bigger system you may not have the chance to reimplement things from scratch not because you don't have time, but because you could impact someone else using your library/module/API.
In other words, this approach is eminently laudable, but in my experience does not scale in most cases.
> if your code is part of some bigger system you may not have the chance to reimplement things from scratch not because you don't have time, but because you could impact someone else using your library/module/API.
In this case, if your code is used by someone else, you can't do that. The trick is not releasing your code "out there" until after you've done several rewriting passes on it. In the cases I've done that in professional context, I worked on a feature branch. I would occasionally rebase it on top of master, to stay current with rest of the product, but nobody ever looked at my feature branch until I've done a few rounds on the code, declared it's ready for integration, and issued a merge request.
I suppose this should teach me to wait until I have time enough to write a proper post, next time.
My situation isn't typical. To put it in common parlance, this is how I nucleate my 20% projects, and personal projects. Which, once released, almost never require significant maintenance because of the care and attention spent upfront.
I'm more than capable of whipping out a prototype that will do the job and incur technical debt. And I'm upfront about tradeoffs in planning, and meticulous about the rare deadline I get saddled with.
I think it is less a problem to be solved than a fundamental trade-off that comes with the scale of systems: the more components a system is going to have, the greater the cost of not minimizing complexity of individual components.
New features mean new sales opportunities, good for the company but not good for the user.
The problem with adding features to MVP is that when we ship more complex products like complete operating systems that are packed with programs, the complexity of the individual programs contributes to the complexity of the whole.
Not sure how to solve that particular problem though.
This made me think of a blogpost linked on Hacker News when Joe passed away: https://github.com/lukego/blog/issues/32. This part seems relevant here:
Joe wrote amazingly simple programs and he did so in a peculiar way. First he wrote down the program any old way just to get it out of his head. Then once it worked he would then immediately create a new directory program2 and write it again. He would repeat this process five or six times (program5, program6, ...) and each time he would understand the problem a little better and sense which parts of the program were essential enough to re-type. He thought this was the most natural thing in the world: of course you throw away the first few implementations, you didn't understand the problem when you wrote those!