I just refactored the access control rules framework in
peak.security to use generic functions instead of adaptation. The result has less than half the code (about 140 lines versus the old version’s 480), and uses only one interface (versus eight in the old version). The old version used interfaces extensively to perform adaptation, but the new version just uses generic functions instead. And it’s more flexible, too.
Generic functions aren’t always a substitute for adaptation and interfaces, however. Technically, a generic function can do anything that you can do by adapting to an interface and calling a method, but sometimes interface+adaptation is a better “metaphor” for what’s going on, or a more convenient or expressive way to do things, especially for documentation. (For example, the interface I left behind in the new implementation was purely for documentation purposes.)
In the process of writing the new rule system, however, I did flush a few generic function bugs out of hiding. Nothing serious, fortunately. But I always feel better about my code when some bugs have been found; the state of “no bugs” always makes me feel like things are “too good to be true”. Code that has had bugs and had them fixed is a bit more robust, a little less virginal, more “battle-hardened”, so to speak. Even with massive quantities of unit tests, sometimes you don’t know if you’re testing the right things until sometime later!