The Expression Problem
Early in Crafting Interpreters, Robert Nystrom introduces the "expression problem." It's likely obvious to some and a gross oversimplification to others, but I personally found it thought-provoking enough to repeat.
Many programming languages allow the programmer to define new types of data (nouns) as well as operations on them (methods). In an object-oriented language, those could be classes (or interfaces) and methods; in a functional language those might be types and functions.
The insight exposed by the expression problem is that adding or changing nouns and verbs typically runs into friction at some point. In an object oriented language, it's easy to add new nouns (add a new class and implement the methods it needs), but hard to add an abstract method to an interface or superclass, because you then need to update all existing implementations of that interface. While in a functional language, it's easy to add a new verb (create a function and handle existing types), but painful to add a new noun (because existing functions must be make aware of the new type). (At least in many ML-inspired languages like Haskell, Scala, and Rust, the compiler will help by detecting non-exhaustive pattern matching, but in more free-form languages like Scheme, you'll get no such assistance.)
In Crafting Interpreters, this is a prelude to the Visitor pattern, a design pattern that attempts to patch over object-oriented programming's awkwardness here. In functional languages that offer them, type classes solve the complementary problem.
Also, human languages don't seem to experience the same problem: newly minted nouns or verbs can be immediately composed with a wealth of existing words. Apparently we can interpret on the fly how arbitrary words might connect with a lot more flexibility than the average compiler!