For example, why is it not easy to add an "onClick" event handler method to a particular button in a Java GUI? One has to use lambdas instead. Attempts to reorg the GUI engine to remedy such create side-effects. Java's OOP model is simply not powerful enough to do GUI's naturally. Conway's Law seems to apply to domain structures as well. Fit matters.
Something like Lisp allows one to create behavior-containing "structures" that are customized to a domain or need, but can get too confusing. Lisp can easily get too hard to read and follow for most mortals, and is why it never became mainstream despite being around for 60-ish years.
We need something in between traditional OOP and "full meta".
I increasingly advocate F#, and many people recommend Elixir for these purposes too (though I'm not familiar with it myself).
The only real trick is to use delegation patterns instead of inheritance, i.e. dispatch requests to class members rather than super/subclasses.
It doesn't feel awkward or unnatural.
Then you could easily answer:
A) Show me all the GUI event handling code for all buttons. B) Show me all the event handling code for Form X. C) Show me all the event handling code for all buttons within forms having at least one drop-down list.
Similar goes for executing code (running business logic), not just code inspection. Then one doesn't have to crawl object graphs as often. Early databases did graph crawling, but then Dr. Codd showed a better way, and graph-DB's mostly withered. I'm waiting for the Dr. Codd of code and behavior dispatching management to come save the day.
I'd like to explore using relational modelling for behavior, not just attributes (data). I used to do such in xBase (dBASE, FoxPro, etc.) because of its dynamic nature and ease of editing tables, including code in tables. I thought that direction was the future, it looked bright to me. Then OOP came along and killed the seeming birth of table-oriented programming.
(It might seem like a security risk to put code in tables, but the difference between a file system and database are not different enough to say putting them in a database is "bad" while putting them in a file system is "good". I'd like to blur the distinction between a file system and database, but maybe that's a diff topic. Plus, one doesn't necessarily have to put code "in" the tables, just references to it in tables. One just needs a system/convention to track and map each to the other.)
Lack of pointers. An event reference is a double pointer: to the method and to the object that is "self" or "this" for the execution of the event handler. Since they refused to have pointers in the language, they devised that convoluted solution.
(One problem with traditional RDBMS and GUI's is that different widgets need a variety of similar and often overlapping attributes {columns}. It's not realistic to have a table dedicated to each widget "type". Thus, I propose using "dynamic relational" instead, in which column existence is optionally situational.)
It's "sold" as enabling extensibility and code reuse, but the only feature it adds to good old-fashioned composition is 'open recursion' a.k.a. late binding, which inherently leads to the "fragile base class" problem-- making behavior of base-class implementations dependent on preserving complex and generally unspecified invariants in the derived classes - so it's basically never what you actually want!
Full-blown OOP (including implementation inheritance and polymorphism) doesn't work. It's a terrible idea that only ever became popular because we didn't quite grok its implications.