Remix.run Logo
jdw64 an hour ago

Right, there were examples like Singleton and baseController. We moved from ambient/global dependency access to explicit constructor injection and Composition Root, didn't we?

Application entry points use Composition Root now, but old general programming books didn't. Errors were handled differently too. In the past, you'd throw new Exception() and wrap it in try/catch at a higher level, but these days we use Result<T, E> type modeling. Of course, C# still uses try/catch, but the guidance in .NET has long been to return predictable failures as type contracts.

Old .NET documentation used to encourage global access to common features and dependencies. Now it's shifted toward composition at the entry point.

Node.js used to use nested error-first callbacks as a standard pattern, but that's no longer the case, right? It moved to promise/async-await, and these days, as you know, type-based modeling is trending.

C# books also used to return null if something was missing, but now we use nullable reference types to express nullability more explicitly.

Even inheritance—these days it's often advised to avoid inheritance, but it used to be very common.

Just off the top of my head, I can think of quite a few examples. Record keywords and immutability features started appearing about 10 years ago, and Java has started adopting them too.

These are all outdated patterns now, with clearly defined use cases. More precisely, the contexts in which they should be used have become much more granular.

I could probably give about 30 more examples of this.