But I also spent some time with modern Spring Boot, and I get where the hate is coming from. There is a lot of complexity that just doesn't seem necessary at all.
But I also spent some time with modern Spring Boot, and I get where the hate is coming from. There is a lot of complexity that just doesn't seem necessary at all.
I'm sure there is some (very high) level of inherent project complexity where the massive number of abstractions and tools that Spring Boot gives you (and forces on you) actually starts turning into a net positive... And I'm also fairly sure that most projects don't quite break even, and would be better off with something more lightweight.
also a lot of oop hate is 1) hatred of compile-time hierarchies attempting to match the domain model and 2) all the complexity in oop systems which isn't really inherent to OOP but made possible by it. oop doesn't require a PrototypeFactoryInjectorFactoryBean but it doesn't prevent you either :)
on the flip side I've seen functional codebases which are also full of complexity because of how fragmented everything is, like 20 functions all applied when it could have been a single imperative one making it hard to keep track of what is happening.
and of course everything in between
I think the hate typically comes from the mis-application of various tools; overly complex solutions for simple problems. There's nothing wrong with patterns per say, or frameworks that have complex building blocks for every conceivable permutation of relatively common issues. However, when people reach for unnecessarily complex tools out of laziness/habit, some hate is justified. I suspect this is very similar to what you're saying, and of course, it's not OOP specific. Functional languages have their patterns too, but instead of a famous book enumerating them, we have a famous blog post stating that functional languages are so awesome that they don't need patterns (or at least, this is how most people seem to interpret it).
The point is not to be snug about it. Functional programming (and monads) are actually simpler. You just need to resist the urge to "make it more understandable".
Abstract math doesn't have good analogies to the real world. By trying to make an analogy with the concrete ("monads are mappable") you lose simplicity.
They are supposed to help you build better foundations; the abstractions to better understand your complexity you need to build (or at least pick) yourself.
Good foundations then help you relate the abstractions. For example, the categoric dual of a product is a sum. We can apply it to relation (relational algebra), and we get that sum is data inheritance.
So that gives you understanding of how functions (foreign keys), product (relation) and sum (inheritance) fit together. This sometimes helps to build abstractions in a consistent way.
We're collectively shaking a lot of trees when we build frameworks, languages and tools. What works? What does not? What is the right level of abstraction? How much developer ergonomy do we want to sacrifice?
Sadly we only seem to know in hindsight what works well. But that is also how we learn and grow; it was just meant to be this way.