I get around that by writing the API first, with usage code examples and all, Or in a GUI app, the UI first. I'll iterate there if needed, and only rewrite internals if it's truly bad or I think it will cause a problem later.
A lot of situations where the code is so nasty I actually have wanted to rewrite... I wind up just throwing it away instead.
Like, one of my happiest days in coding was throwing out some code to support JACK and going all in on Pipewire. Another happy day was replacing some DIY code with a GPL licensed library, deciding that I really didn't need the option to do proprietary stuff anywhere near as much as I wanted less thinking about gstreamer.
"If it's hard to explain, it's probably a bad idea".... If I try a bunch of API variations and I can't come up with anything that doesn't require learning 3 new algorithms to use... Maybe I'm not making a library or an abstraction, I'm making a proof of work hashing scheme that users have to do manually to access an encrypted version of the complexity I'm hiding, and I need to stop before I make z80 assembly in JSON to autogenerate Vue templates that render to cobol.
A lot of situations where the code is so nasty I actually have wanted to rewrite... I wind up just throwing it away instead.
Like, one of my happiest days in coding was throwing out some code to support JACK and going all in on Pipewire. Another happy day was replacing some DIY code with a GPL licensed library, deciding that I really didn't need the option to do proprietary stuff anywhere near as much as I wanted less thinking about gstreamer.
"If it's hard to explain, it's probably a bad idea".... If I try a bunch of API variations and I can't come up with anything that doesn't require learning 3 new algorithms to use... Maybe I'm not making a library or an abstraction, I'm making a proof of work hashing scheme that users have to do manually to access an encrypted version of the complexity I'm hiding, and I need to stop before I make z80 assembly in JSON to autogenerate Vue templates that render to cobol.