When writing a library or the public API of a module that will be used by a lot of other code in a variety of use cases, what is the best way to balance flexibility with ease of use? I believe that the two often conflict in that, the more flexible you make something, the harder it is to get it to do any one particular thing well.
For example, the C++ STL uses iterators, which IMHO are horribly low level and annoying to work with, but in exchange they are extremely flexible in allowing the same code to operate on all kinds of STL containers. Another example is the design philosophy of the Java standard library, with its small, very specific classes that are designed for maximum modularity and flexibility, versus the Python standard library, with its preference for a flatter class hierarchy that makes handling the common use cases simpler. How should things like these be balanced?
If you are part of a standards body that can enforce usage of your classes on others then you can go with flexible and complicated (e.g. stl).
For everyone else, unless there are some really compelling reasons, then ease of use should always be your first choice. Otherwise, few people will use your code/API. If the learning curve to use someone else’s code is high then most people will opt to reimplement just the parts they need. That is usually way quicker and problems are easier to resolve.
In my opinion, ‘ease of understandability’ is 2nd only to ‘It Works Correctly’ when it comes to rating the quality of code.
So bottom line, if adding flexibility comes at expense of easy to learn and use then don’t add the flexibility until it is PROVEN that the flexibility is necessary.