Metaprogramming is the writing of computer programs that write or manipulate other programs as their data or that do part of the work during compile time that is otherwise done at run time. In many cases, this allows programmers to get more done in the same amount of time as they would take to write all the code manually.
As languages acquire more features, code-generating programs get less appealing. Have you ever thought, what is available as a standard feature of one language may be available only through a code-generating program in another language? However, inadequate language design is not the only reason for needing code-generating programs. Easier maintenance is also a reason for code generating programs.
Firstly, for the use at a runtime, you can write programs that will pre-generate tables of data. For example, if you are writing a game and you demand a quick lookup table for the sine of all 8-bit integers. The first option is that you can calculate each sine yourself and then hand-code it. Then place your program build the table at startup at runtime, or write a program to build the custom code for the table before compile-time.
However it may make some sense to build the table at runtime for such a small set of numbers that you are using. Other such tasks may cause program startup to be prohibitively slow. In those cases, usually the best answer is to write a program that builds static data tables.
Secondly, if a program has a large application in which many of the functions include a lot of boilerplate code. Then the programmer can create a mini-language that will do the boilerplate code and allow coding only the important parts in the program. Now, if the programmer can abstract out the boilerplate portions into a function, it is probably the best. But often the boilerplate code isn't so pretty.
It is because there is a list of variables to be declared in every instance in the program runtime, maybe the programmer needs to register error handlers, or it could be because there are several pieces of the boilerplate that have to have code inserted in certain circumstances when the program runs. These things make a simple function call that is impossible.
In such circumstances, a better idea would have been to create a mini-language that allows you to work with your boilerplate code in an easier fashion. So that, the mini-language will then be converted into your regular source code language before the compiling of program.
In the end, a lot of programming languages make you write really verbose statements to do really simple things. These Code-generating programs allow you to abbreviate such statements and save a lot of typing, which probably prevents a lot of mistakes because there is less chance of mistyping in writing the program.