The Meta-Object Protocol and Knowledge-Based Systems

December 1997

This is the latest in a series of articles on developing Knowledge-Based Applications with Dynamic Objects technology. The first of these articles, Knowledge-Based Application Development with Dynamic Objects Technology (October 1997), discussed what kind of applications are included in this category, how they are being integrated into multi-tier client-server computing architectures, and how Allegro CL has become the "tool of choice" for development of knowledge-based systems.

The article Dynamic Objects Features Make Allegro CL Ideal for Knowledge-Based Applications (November 1997) focused on one of the Dynamic Objects features of Allegro CL which makes it ideal for this kind of development: the capability of Allegro CL to runtime-extend and reconfigure knowledge very efficiently. Allegro CL's runtime extensibility is one of the primary reasons why this development system remains pre-eminent in advanced knowledge-based application development today.

In this article, we take a look at another of the key features of Allegro CL which makes it ideal for knowledge-based applications development: the Meta-Object Protocol.

What is the Meta-Object Protocol?

The Meta-Object Protocol (MOP) is a protocol layer in Common Lisp which contains a set of default rules about how the CLOS object system works: how methods are added, how classes inherit from superclasses, etc. These protocols are built right into the object system, and are enforced automatically. Automatic enforcement makes the application development process much more efficient, as the protocols do not have to be manually invoked by the programmer wherever they are needed throughout the application.

The default rules of the MOP can also be modified, enabling the programmer to actually customize the object system to suit the application. Using the MOP, the developer can model any object system he wants, even the object system of another language such as Java. The Meta-Object Protocol is a unique, powerful feature of Dynamic Object systems; no other development languages and systems provide it.


If you are interested in getting more detail about the MOP, see The Art of the Metaobject Protocol by Gregor Kiczales et al. You can read about the book and order it from

Let's take a look here at how the MOP enables developers to write code in a highly abstract fashion, and take advantage of Allegro CL's dynamic reflection capabilities.

The MOP and Abstraction

The key advantage of the MOP is that it allows the software engineer to package up particular problem domains and express them succinctly in code: a technique known as abstraction.

The use of the object-oriented paradigm in general goes far in enabling the programmer to model a business problem in an abstract fashion by expressing the problem in terms of classes and methods instead of procedural statements. With Dynamic Objects systems, the programmer is able to achieve even greater abstraction.

This is a particularly important capability for developers building knowledge-based applications, because these applications can become very complex. Strong abstraction capabilities enable the programmer to model a particular problem area much more easily and efficiently. The resulting code becomes more concise, understandable, maintainable and reusable.

The MOP and Dynamic Reflection

Allegro CL's abstraction capabilities are made possible by the MOP and by a unique dynamic reflection functionality. Let's take a look at reflection and how it works before returning to our discussion of the MOP.

Reflection can be defined as the ability of an object system to understand information about itself. For example, a program might ask about its own class structure and inheritance rules, methods and method signatures, etc., and then use this information for further processing.

Some static object development systems enable the programmer to see this information at runtime (this is a type of reflection known as introspection) and use it for further processing in this way. However, with static languages like C++ there is no capability to actually change the information while the application is running.

With Dynamic Object systems, both introspection and a unique dynamic reflection capability are built-in. Dynamic Objects systems, unlike static languages such as C++, retain meta-data at runtime about the entire object hierarchy of the application. The presence of this built-in meta-data enables the developer to easily access and use information about the object hierarchy in the application.

In addition, the developer can change this data at runtime. Information in the object hierarchy can be modified in the running application—by user input or by the code itself.

An Example Application

Let's look at an example of how this works. The diagram below shows a multi-agent application containing a Web-based stock tracking system which has a set of methods and attributes it can publish to other agents. We will see how dynamic reflection enables changes to be made on-the-fly, and how the MOP enables new agents to be easily added to the system by abstracting out the rules which control agent interaction.

Agent 1 is the stock tracking application which receives incoming data from various data sources over the Internet. When new data comes in, Agent 1 publishes these updates via the notify method. A second agent, such as a personal portfolio manager, can look at the meta-data of the stock tracker agent to find the notify symbol. If notify is present, Agent 2 knows that Agent 1 is publishing new data.

MOP Article Diagram

Now let's say a third agent needs to be added to this knowledge system. The third agent might be a trading application which is completely separate from the portfolio manager application, but which must share the same data source.

The new agent can be added to the system dynamically by programming in some abstract rules for how to handle information requests. Agent 2, for example, can be programmed to look for the notify symbol and, if present, it can then dynamically add a trigger to the method. Any additional agents added to the system could be programmed to look for this trigger and self-update.

The trigger is added to the code vector of notify in the following way: the code is replaced with a new function which calls the trigger method first, then calls the original code. This new function is dynamically generated, incrementally compiled on-the-fly, and installed into the code slot of notify. In this way, dynamic reflection is used to modify the code while the application is running.

The way in which the trigger method is added (as well as the way in which agents update themselves) is dictated by the Meta-Object Protocol layer of the system. By abstracting out the rules for object interaction into this "meta" layer, the programmer makes it much easier to add agents on-the-fly because the application code does not have to change.

Uniform Syntax

Another important point about reflection and the Meta-Object Protocol is that these features permit a uniform semantic and syntactic access to objects which are conceptually the same but which have very different implementations. This is important because the uniform syntax achievable through reflection results in a dramatic simplification in code, making it much more understandable and robust.

For example, in Dynamic Object systems, the programmer can use the Meta-Object Protocol to define accessors on meta-classes. An accessor is a method, containing information about how to set or access the attributes of an object, based on the type of class rather than on a particular class itself. The actual object implementation can thus be abstracted away from the language used to manipulate the object.

In this way, the developer can abstract out various cases for how to deal with highly dynamic and heterogeneous data sources, including how to handle things like missing or inconsistent data. The rules for dealing with these situations are thus made separate from the classes themselves. This enables the application code to remain identical even if the data source changes from a flat file, to a record in database, to a remote CORBA service.


Because of its abstraction capabilities, made possible through unique features like the Meta-Object Protocol and dynamic reflection, Allegro CL is the "tool of choice" for building complex systems that need to evolve dynamically in order to accomodate new data sources, sophisticated user queries, and multiple collaborative agents.

Copyright © 2021 Franz Inc., All Rights Reserved | Privacy Statement Twitter