Metaprogramming enables developers to write programs and develop code that falls under the
generic programming paradigm. Having the programming language itself as a
first-class data type (as in
Lisp,
Prolog,
SNOBOL, or
Rebol) is also very useful; this is known as
homoiconicity.
Generic programming invokes a metaprogramming facility within a language by allowing one to write code without the concern of specifying data types since they can be supplied as
parameters when used. Metaprogramming usually works in one of three ways. • The first approach is to expose the internals of the
runtime system (engine) to the programming code through
application programming interfaces (APIs) like that for the
.NET Common Intermediate Language (CIL) emitter. • The second approach is
dynamic execution of expressions that contain programming commands, often composed from strings, but can also be from other methods using arguments or context, like
JavaScript. Thus, "programs can write programs." Although both approaches can be used in the same language, most languages tend to lean toward one or the other. • The third approach is to step outside the language entirely. General purpose
program transformation systems such as
compilers, which accept language descriptions and carry out arbitrary transformations on those languages, are direct implementations of general metaprogramming. This allows metaprogramming to be applied to virtually any target language without regard to whether that target language has any metaprogramming abilities of its own. One can see this at work with
Scheme and how it allows tackling some limits faced in
C by using constructs that are part of the Scheme language to extend C.
Lisp is probably the quintessential language with metaprogramming facilities, both because of its historical precedence and because of the simplicity and power of its metaprogramming. In Lisp metaprogramming, the unquote operator (typically a comma) introduces code that is
evaluated at program definition time rather than at run time. The metaprogramming language is thus identical to the host programming language, and existing Lisp routines can be directly reused for metaprogramming if desired. This approach has been implemented in other languages by incorporating an interpreter in the program, which works directly with the program's data. There are implementations of this kind for some common high-level languages, such as
RemObjects’
Pascal Script for
Object Pascal. == Usages ==