Sun Jul 19 13:33:30 CEST 2009
Two forms of broken base systems
The need for metaprogramming comes from an inability to replace one
system with another when it is not appropriately flexible, but at the
same time it is impossible to do so for any (practical or theoretical)
reason. The strange thing is that this happens both for systems that
are either not complex enough or too complex.
1. Getting it abstract: metaprogamming as a symptom of inflexible base
In this case, the base system is not expressive enough to provide a
substrate to encode a solution in a non-redundant way.
If you look at Ruby on Rails, the "irrepairable" part is the fixed
In Scheme, the inflexible part is the way in which new name
bindings are introduced, and the order in which sub-expressions of
an expression are reduced to produce a value. In the case of Scheme
this inflexibility is a choice: the base language is _designed_ to
be simple, which renders it incomplete in these two areas. Macros
can be used to build abstractions on top of this.
In general: macros help to abstract `fixed' parts of a language:
eliminate redundancy due to regularity of constructs that cannot be
manipulated at run-time.
2. Getting it right: metaprogramming as constraint system.
In some cases the inflexible nature of a system might be that it is
_too_ flexible, for different meanings of flexible: the base system
permits too many mistakes that one would like to prevent by
specification in a less flexible language.
This is essentially what (domain specific) programming language
design is about: providing higher level semantics that is easier to
check for inconsistencies compared to a more flexible low-level
Often however it is a combination of both: I.e. a typed functional
langauge provides more flexibility in some domains (i.e. providing an
abstract memory model) but less flexibility in others (requiring some
contraints on the code structure are satisfied before translation to a