There are few professions where you make your own tools. Woodworkers are an example, as so are programmers.
However, it seems to me woodworkers know better when they are doing furniture and when they are making tools. For programmers, things are not always so clear.
Let’s say you are adding logs to the program, you do that to lots of places in the whole code, then you think “maybe I should keep this in one place…”. At this very moment, you switch from “make the program” to “make a tool”.
I would say ANY refactoring means you are doing a little tool making.
Well, tool making has some differences from making a furniture or a program. Reflection, metaprogramming, late binding, and closures are incredibly useful for tool making, but no big deal for application building. Don’t believe me: Take a look where they are being used and tell me :)
Useful tools are more general and don’t care about business rules. They seldom have state or heterogeneous structures. Compare that to “build the software for your company”, they are all about business rules, are useless without preserving state and have lots of different structures, one for each “business entity”. (Things can’t get very interesting when you are making a tool, like a library, and make a tool for building it.)
This would be programming in “App mode” (in absence of a better name) and in “Tool mode”.
But, does it matter?
Well, I guess it makes two great ways to build software more explicit. One is “top-down”, “programming by intention” or “TDD/BDD”: you start from business and refactor to the tools. There are lots of benefits on those approaches (avoid unnecessary generalization is the key one). Other is the less popular “down-top” or “Scheme-like”, where you make the tools first (think “DSL”) and then you build from it.
Of course, it’s possible to mix things, especially when you are not aware you are changing modes.
Try it… next refactoring, ask yourself if you are doing “tool making” or “app making”.
Finally, tools make you faster, especially if they are (really) reusable. But building tools is time-consuming. Good programmers understand the former, Seniors understand the latter.
A challenge to you: how many times those “very reusable, easier to change” part of the program (a tool) really paid off the time you spent building it? How many other places are they used?