What is Reflection?

TL;DR

We define Reflection and related terms, and give a couple of simple examples.

Terminology

Reflection is the ability of a program to manipulate a representation of its own state during its execution. Reflection can be used to build custom and ad hoc analysis tools.

Introspection is the ability for a program to observe and reason about its own state.

Intercession is the ability for a program to modify its own execution state or alter its own interpretation or meaning.

Reification is the mechanism for encoding execution state as data.

A metaobject is an object that describes or manipulates other objects.

A reflective architecture is one in which (i) the system implementation is reified in terms of metaobjects, and (ii) these metaobjects are causally connected to the running system.

A metacircular architecture is a reflective architecture in which a programming language and the meta-language of its implementation are the same ( e.g., Smalltalk and CLOS).

Structural reflection lets you reify and reflect on (i) the program currently executed, and (ii) its abstract data types .

Behavioral reflection lets you reify and reflect on (i) the language semantics and implementation (processor), and (ii) the data and implementation of the run-time system.

Reflection and Reification

Metaobjects live in the implementation of a language, typically in the VM. To use them, they have to be reified to ordinary objects in the run-time image. You can then query these reified metaobjects. This form of reflection is called introspection . If you modified these metaobjects, and reflect these changes back to the meta-level ( i.e. , the implementation), then this form of reflection is called intercession . Note that the line between the base level and meta level is sometimes called a mirror , because the meta-level objects are reflected to the base level.

Examples

Introspection and structural reflection

We can ask an object at run time for its class, query that class for its methods and compute the average number of lines of code.

anObject := GtLudoGameExamples new emptyGame.
(anObject class methods collect: #linesOfCode) average.
  

This is introspection , because we exploit the reflective architecture of Smalltalk to query the object for its class, reify its class as a metaobject , and perform structural reflection to reason about the implementation. Note that the metaobjects are causally connected with the underlying implementation, since any changes to the code will be faithfully reflected in the result of the query.

Intercession and behavioral reflection

We can compile and modify classes and methods at run time in Smalltalk.

Object
	subclass: #HelloWorld
	instanceVariableNames: ''
	classVariableNames: ''
	category: 'HelloWorld'.
helloClass := (Smalltalk at: #HelloWorld).
helloClass compile: 'hello ^ ''hello'''.
(helloClass perform: #new) perform: #hello.
  

In this snippet we interact with the Object ProtoObject subclass: #Object instanceVariableNames: '' classVariableNames: 'DependentsFields' package: 'Kernel-Objects' metaobject representing the Object class to create a new class. We then interact with the Smalltalk metaobject representing the system to retrieve the metaobject of the new class, we reflectively compile a new method, create an instance and send a message. This is intercession , and in particular behavioral reflection because we are modifying the running system.

Further reading

Concepts and Experiments in Computational Reflection,” Pattie Maes, OOPSLA, 1987 — Explains computational reflection , reflective architecture and metaobjects in OO languages.

Reflective Facilities in Smalltalk-80,” Foote et al., OOPSLA, 1989 — Explains reflective features in the context of Smalltalk.

CLOS in Context: The Shape of the Design Space,” Bobrow et al., Object Oriented Programming: The CLOS Perspective, 1993 — Defines reflection , introspection and intercession .

A Tutorial on Behavioral Reflection and its Implementation,” Malenfant et al., Proceedings of Reflection, 1996 — Distinguishes structural and behavioral reflection.

Reflection and Open Implementations,” Tanter, U Chile, 2009 — Reviews the state of the art in reflection and metaprogramming.

Sub-method, partial behavioral reflection with Reflectivity,” Costiou et al., The Art, Science, and Engineering of Programming, 2020 — Surveys the Reflectivity framework in Pharo.

Pharo: a reflective language — A first systematic analysis of reflective APIs,” Thomas et al., IWST 23, 2023 — Surveys and analyzes the reflective API of Pharo.

See also: Reflective programming (Wikipedia page).