Please do the opposite. Let all deprecation warnings last at least a decade, just include in the warning that it is not maintained.
But more to the point, go out of your way to avoid breaking backwards compatibility. If it's possible to achieve the same functionality a different way, just modify the deprecated function to use the new function in the background.
My biggest problem with the whole static typing trend is that it makes developers feel empowered to break backwards compatibility when it would be trivial to keep things working.
edit: Not that it is always trivial to avoid breaking backwards compatibility, but there are so many times that it would be.
> My biggest problem with the whole static typing trend is that it makes developers feel empowered to break backwards compatibility when it would be trivial to keep things working.
I don't see the connection you're drawing here.
I was hoping to spin it as an environmental concern. You change something "for reasons". If you're doing this in a popular tool/library you probably just burnt down a small forest of trees worth of energy from all of the work people will have to put in deal with it. 100s of thousands of users missed dinner with a kid or loved one because of the extra work you created. A product that would of shipped on time didn't. Things you wanted to exist didn't because 100k people were distracted dealing with your breakage.
Static Typing != Strongly Maintained Relationships.
While I am happy to see types in Python and Javascript (as in Typescript) I see far more issues how people use these.
In 99% of the time, people just define things as "string" or if doesn't cover, "any". (or Map/Object etc)
Meanwhile most of these are Enum keys/values, or constants from dependencies. Whenever I see a `region: string` or a `stage: string`; a part of me dies. Because these need to be declared as `region: Region` or `stage: Stage`. Where the "Region" and "Stage" are proper enums or interfaces with clear values/variables/options. This helps with compile (or build) time validation and checking, preventing issues from propagating to the production (or to the runtime at all)...
> Not that it is always trivial to avoid breaking backwards compatibility, but there are so many times that it would be.
In this case it was 2 functions with 1 line of code each. https://github.com/urllib3/urllib3/pull/3732/files
Stripe do this in a cool way. Their REST API is version based on date, and each time they change it they add a stackable compatibility layer. So your decade old code will still work.
As with all things, this can be pushed too far. Microsoft was suffering a maintainability crisis before the transition to Windows XP; their years of bending the API to support customers (which, in the short run, did keep customers to their benefit) was making for a fairly unmaintainable mess of an API surface that then screamed under the strain when the Internet era hit and all those open, under-observed APIs became potential worm attack vectors.
One thing I've always hated was this idea of "bitrot." That software just spontaneously stops working after time and loses backwards compatibility. Like it's some force of nature.
It's not a force of nature. Bitrot is: many software developers deliberately choosing to break backward compatibility in very small ways over and over. Software written in 1995 should still work today. It's digital. It doesn't rot or fall apart. It doesn't degrade. The reason it doesn't work today is decisions that platforms and library maintainers deliberately made. Like OP. Deprecate like you mean it. That's a choice!
If we want to solve bitrot, we need to stop making that choice.
Isn't that arguing for keeping the maintenance cost high and also stagnating the design?
> just include in the warning that it is not maintained.
I'm convinced this isn't possible in practice. It doesn't matter how often you declare that something isn't maintained, the second it causes an issue with a [bigger|more important|business critical] team it suddenly needs become maintained again.