A *(term) describing an interpreter for a language <var>L</var> written in the same language <var>L</var> (or a subset thereof), said to be a meta-circular interpreter. More generally, any kind of metaprogram (implementation infrastructure or otherwise) written in a system <var>S</var> made to compute or reason about the meaning of programs written in system <var>S</var> is said to be meta-circular. Hence, you can have meta-circular compilers (what you do when bootstrapping a language implementation), meta-circular definitions of language extensions (see the _(CLOS MOP)), meta-circular reasoning systems (_(NuPRL) _(ACL2)), etc.

Simple _(Lisp) dialects like _(Scheme) are notabe for allowing very nice and short meta-circular interpreters, and many Lisp books have tackled the exercise, to the point that it has been suggested that the proof of Gdel's theorem would have been easier if he had invented Lisp first.

The origin of the term is still unclear to us. (<em>Question:</em> who first used the term? Who popularized it?) It seems that the "circular" part is related to the interpreter or metaprogram being applicable to itself. Hence, you can run an instance of a meta-circular interpreter for <var>L</var> inside another instance, and so on, and get exponentially bigger and slower implementations of <var>L</var> (or possibly, implementations of dialects of <var>L</var>, each time with small variations or extensions).

Writing a meta-circular interpreter for a subset of one's favorite language (or at least, studying one) is a very common exercise to get familiar with the details of the semantics of the language, and the general techniques involved in implementing it. Such an exercise can help one understand a lot about parts of the language that one may otherwise appear to one as tricky or counter-intuitive, or worse, that one may misunderstand without even being conscious of it.

Besides the value in learning, _(meta-)circular interpreters are useful for debugging programs or otherwise evaluating them in a controlled environment, for allowing _(dynamic) evaluation despite the underlying implementation being a static compiler, for bootstrapping language features and extensions on top of an implementation of a subset of the language without those features, for experimenting with new language extensions or implementation techniques, for obtaining a compiler by applying a partial evaluator, for allowing a proof system to reason about the semantics of the full language, etc.