Essentially programmatically writing the program -
is that what Lisp's macros are?
Macros are often described that way. "Lisp macros let you write code that writes code!" While that's a true statement, it's kind of useless for coming to an initial understanding of what macros let you
really do.
Think of it this way. Programming languages have built-in control flow operators like if-then, do, while, and for. Macros let you write your own operators - that work just like the ones built into the language itself.
Here's an example. Let's say you want to print a list of names.
In a language without an operator specifically for going over lists - and without macros - you may have to write:
ListIterator iterator = namesList.GetListIterator();
while(iterator.HasMoreItems()) {
string name = iterator.GetNextItem();
print(name);
}
If you have a language that supports macros, you can create a macro called forEachItemInList. And then it'll work just like it came with the language all along:
forEachItemInList(string currentName in namesList)
{
print(currentName);
}
If you count how many words the
non-macro solution took, it's 13. The macro solution takes 7. Having to solve a problem with more code means more time to understand, teach, write, test, debug, and document - so savings like this can really add up.
And there's also the subjective part. Having to write code like in the first example just isn't satisfying. You have to repeat yourself constantly. You may think, "Look, I loop over lists all the time. And it's always the same pattern: I call GetListIterator(), I do a 'while' loop while it HasMoreItems(), then I call GetNextItem(), etc. Why can't I just inform the compiler of the general pattern - and then tell it how to fill in the blanks when I need to actually loop over a list?"
And that's what macros let you do.