Reflective towers have been regarded as mysterious devices, but in fact they appear at the heart of any system exhibiting a form of behavioral reflection (to our current knowledge). For example, two important families of behaviorally reflective object-oriented languages have been proposed. One family is built around the generic function model, where the application of a generic function is reified as a generic function; the CLOS MOP [KRB91] is the quintessence of such systems. The second family is built around the lookup apply introspective protocol, where a message is decomposed into a lookup and an apply phases, both reified as methods in the language [MDC96]. Interestingly enough, reflective towers appear in both.
Des Rivières [dR90] has brought to the fore the existence of a reflective tower in the CLOS MOP through the generic function apply-generic-function 6, which describes how a generic function is invoked. The tower appears because when invoked, as a generic function apply-generic-function must invoke itself. The potential infinite meta-regression is avoided by topping out to the internal implementation when the method for applying standard generic functions is invoked. In Malenfant et al. [MDC96], we have shown the existence of reflective towers in the lookup apply model. In this model, reflective towers appear because apply methods are themselves methods and must have their own apply method, and so on. Because they are so ubiquitous in behavioral reflection, the efficient implementation of reflective towers appears as a key issue.
Indeed there are differences between the 3-Lisp approach and the two latter ones, the most important from an implementation point of view being that the 3-Lisp tower is potentially infinite. In the object-oriented models, the towers are finite by construction and the languages always provide explicit rock-bottom entities that stop the tower at some fixed level, perhaps differing from methods to methods. This difference also implies very different philosophies of introspection. Because the interpreters in the 3-Lisp tower are all the same, the end user needs reflective procedures to introduce new meta-level code in the tower. In the object-oriented approach, the apply methods are build by the end user in such a way that they include the necessary meta-level code to perform the envisaged introspection. We therefore distinguish two general approaches: discrete and continuous behavioral reflection.
These two approaches favor quite different reflective applications. The discrete approach is good at interrupting the computation at some point, observing its state and taking some punctual action. For example, a reflective procedure can be called by a particular function to gather usage statistics in order to optimize it for the most frequent cases. The continuous approach lends itself to applications where some part of the semantics is modified more or less permanently, like changing the parameter passing mode. Although not exclusive, there are few examples, to our knowledge, of languages mixing both models (Simmons et al. [SJ92] provide such an example). In languages exhibiting discrete behavioral reflection, the interpreters in the tower are almost never modified (except through reflective procedure calls) while in languages exhibiting continuous behavioral reflection, reflective procedures are almost never provided (but they could easily be introduced using reflection).