In Take Advantage of Modern Perl I digressed to discuss a hierarchy of defaults. I use this concept to help make design decisions about where to fix problems. (I admit to borrowing concepts from Joshua Bloch's How to Design a Good API and Why it Matters (PDF link)).
As you progress from the top of the tower to the base, you solve the problem for more people.
- Unknown Problem
- Poorly Recognized Problem
- Infrequently Asked Question
- Frequently Asked Question
- Frequently Reinvented Module
- Available Module
- Community Idiom
- Popular Module
- Bundled Module
- Core Module
- Core Language
Please note that this post does not address the difficulty of fixing a problem at any one of these locations, nor does it consider the costs of compatibility, testing, or maintenance. Those are important concerns, but they're not the important point for this post.
Institutional Knowledge Locations
The least effective way to address a problem is by ignoring it. Of course, that assumes you know it's already a problem. A problem you haven't even identified is worse. A problem only a few people acknowledge is bad.
(By "good" and "bad" I refer to the efficacy of addressing the problem. Again, the severity and reach of a problem are important to consider when deciding how to fix it.)
Documentation Locations
Documenting a problem is an improvement. Moving down the tower even to institutional knowledge, where occasionally someone ask for and receives a workaround helps more people avoid the problem. Documenting the problem and any workarounds in a FAQ is even better.
External Code Locations
If users know enough to reinvent the wheel to solve the problem, this can be better than a FAQ. (It can be worse, too; some problems are difficult to solve even with domain-specific knowledge and good test cases.)
It's better to have a decent solution available, though that's generally only useful to people who know it's available.
Widespread community knowledge helps even more people, at least if they have contact with the appropriate parts of the community. There's an overlap here with FAQs and IAQs, but not all FAQs become idioms and vice versa. The ability to look at code and recognize such an idiom -- or to recognize the need for an idiom -- is useful.
The best solution in this category is a popular, well-recognized, well-understood module. Its existence does not preclude other options, but its efficacy and applicability makes it the default solution.
Internal Code Locations
A project such as perl5i or Strawberry Perl can address problems (bugs, missing features, useful enhancements) by bundling modules. They're available by default to everyone who uses the distribution. People need to know that they're available, so other parts of the tower apply, but the barrier to use is much smaller.
The core library is even more effective, provided that users know which parts exist.
As you might expect, the most effective way to address a problem is often to address it in the language itself.
Caveats
I glossed over the importance of design on purpose. I bring it up now because I don't want to give the impression that I believe that pushing all potential fixes into the language itself is either desirable or good. It's not.
An XML parser may be a good bundled module, but it's likely a mistake to put XML parsing in the language itself. A garbage collector tweak tuned for a specific processor may be sufficient as an infrequently asked question, as the people who can best take advantage of it need to analyze its benefits and drawbacks appropriately.
Yet it's also important to remember that the further up the tower a solution exists, the fewer people can take advantage of it.