Have you ever written a parser for a configuration file? Or a data driven interpreter which walks through data, and dispatches appropriate actions? I’ve written too many to count, and more than half of them were a waste of time. They were a waste of time because they were programming problems in disguise.
A classical disguised programming problem is makefiles. Traditional tools, such as make, treat building programs as a configuration problem. For make, you create a configuration file to define what programs to build, what commands to run to generate each target, and so on. For a simple project, makefiles work fine. Sometimes, though, your build process is a bit more complicated.
Maybe you have to do a slightly different thing on different platforms. Perhaps you’d like to avoid listing source code files, instead using a naming convention to indicate which files to build. Or maybe you find that the makefiles have a lot of repetition which could be eliminated if you just could define some kind of an abstraction to reuse that piece of logic everywhere you need it. As a sidenote, there are some enlightened build tools which correctly treat building programs as a programming problem. SCons is one of these tools, and I encourage you to check it out.
The appropriate solution to a programming problem is straight up code. Instead of a configuration file parser or a data driven interpreter, write a library. Instead of a configuration file or input for your interpreter, you write normal code using your library. You get to enjoy the power and flexibility of a real programming language, and you don’t need to implement any of it yourself.
Occasionally, you really do need to provide a closed interface with some kind of mini language, because that just the way it is. Most regex APIs, for example, compile strings into regex objects. But there is no reason why you cannot also provide an API to programmatically build regex objects without having to go through the stupid strings.
Here are some telltale signs to detect a disguised programming problem:
- You have to generate configuration files to work around limitations.
- The configuration file format has grown abstraction capabilities like functions, macros, and reusable variables.
- The configuration allows embedding code.
- In general, any features which smell like a programming language: loops, inheritance, namespaces, types, and so on.
So the next time you find yourself writing a configuration file parser or interpreter, note that you are writing that program in a perfectly good programming language. Why not use it?
- The Essence of Lambda
- The Programming High
- Overriding System Functions for Fun and Profit
- Heuristics for Programming Language Design
- I Have Seen the Future, and It is Copy-On-Write