It's much easier to google "how to do X with graphs" to find some research on a great (if needed) runtime solution to your problem.
It's really hard to google "how to sort these things so I can quickly do X with them" of course ...
On top of that, if you have even a fairly-good data structure for your problem it makes coding and maintaining your solution that much more fun!
Annoying doesn't get even half way close.
- -
Also as we get into programming in multiple languages over the course of our careers - we can better harness the power of code templates (live templates in Intellij or code snippets in VS === kind of meta programming).
eg: I can spend couple of weeks to learn a new framework/language (which sometimes can involve lot of syntax) or Just few days to learn concepts well - then an hour to make handy live templates in editor. Latter I've found - boosts productivity really well.
The whole point of programming is to take something complex and break it down into simple arithmetics and logic that a computer can digest.
So you build simple, isolated expressions that do one slightly more complex thing using slightly less complex things, then use these expressions to build slightly more complex things, and so on recursively, all the way up to having a "do the thing" button in an app.
Having these isolated, modular, layers of testable implementations is what makes code that can survive the test of time.
You will always have side effects but you can try to isolate the bits that are impure and write the rest of your software in a purely functional manner.
Callbacks - or closures, to use the more general mathematical term - allow you to delegate behaviour.