I think the direct solution, especially to the sort of problem you exemplified, is to make mistakes conspicuous.
If you look at the two lines you gave, the difference is actually quite subtle. You have to have a lot of detailed, nuanced syntax "in your mind" when reading it if you want to catch the mistake. You also have to keep an eye out for hard-to-see visual features (*
and 0
can be easy to confuse).
For example, in your example, if cron
syntax was like the following:
minute=0 hour=4 day=every week=every month=every year=every
You would be less likely to confuse it with:
minute=every hour=4 day=every week=every month=every year=every
You can't really change cron's syntax, but you could write a simple CLI program for yourself that takes named arguments like above, and then pass them to the actual cron
. You'd need to carefully review the code that converts from your named arguments, but you only need to do that once, so you can afford to really focus yourself and go the extra mile in error checking - print out the code, read and explain it to yourself aloud and so on.
When you have a program like this, you can also add a sanity check. After you make a new cron job, have it output:
This new job will run 1 times a day.
(perhaps it tries to find the shortest time period that results in a whole number)
Now it will be really difficult for you to make the same mistake. Your tradeoff is:
- It now takes more keystrokes to type the commands, and they look busier (this is probably why
cron
was given the syntax that it was in the first place).
- You have spent time and effort setting up the error-resistant interface model and the sanity check (but in this case you can probably do it in an hour or two).
Now, I'm not necessarily suggesting you do this for cron
. That seems like it's a bit of overkill, unless you set and edit tasks on cron
very often. I just used your example to illustrate the two useful tricks: Sanity checks, and preferring syntax that makes errors very conspicuous even if you don't look for them. The idea is to make sure that mistakes smell.
With syntax, the two obvious things you can do are:
- Select tools and languages that have more error-resistant syntax, for instance, C# vs. Perl. Notice again the tradeoff between catching mistakes quickly and having to do more work.
- Wrap poor syntax in better syntax. For instance, make your own wrapper function for a poorly named functions with ambiguous argument names, make your own wrapper program for arcane tools, use an editor that supports color highlighting and so on.
It doesn't make sense to do these all the way all the time. You want to ask yourself, what matters more in a given task: Correctness, or your time? It's no use disputing that hacking together a quick script in Perl is going to get the job faster than writing a well-structured C# program with clear OOP hierarchy. If you're not worried about mistakes, and you're in a hurry, why bother? But keep in mind that every time you take this shortcut, you are making a gamble: You wager much frustration and gnashing of teeth on the hope that you won't have to go back and extend on your project in the far future, long after you've forgotten how it was supposed to work (or that you won't realize halfway through that your original design won't work, and now must be radically altered).