The basics


The key idea in ActiveContext, is to have the context represented as a regular object. Context can then be instantiated and manipulated as other objects. There is however one active context per thread at a time. The state of objects is contextual — access to the object state is delegate to the current active context

Change propagation


If state was entirely local to a context, the system would not add much flexibility. Therefore, the state of an object can be synchronized across contexts using so-called transformation function.

Each context has a parent context that can not be changed. The various existing contexts form then a tree. When the state of an object is changed in a context, the effect will be propagated to other contexts.

A change propagation between two contexts A and B can go then either from A to B or B to A, depending on the origin of the change. The transformation is bi-directional. The two transformation functions should be implemented so that they are their inverse respectively: state = toFrom( fromTo( state ))

How each context propagates its change is defined by its class. The default Context class implements the identity transformation: all data are copied from one context instance to another. The Context class can however be subclassed to implement other change propagation strategies.

The class meta-level


The same mechanism expands naturally to classes themselves.

The class' state is contextual and class-side instance variable and then no more global.

Contextual class


The state of an object is contextual, which also applies to the class of an object. An object can then be seen (and behave) as an instance of ClassV1 in a context and of ClassV2 in another. The actual class switch will be performed by the transformation functions.

Class resolution is no more than an access to a dictionary object (Smalltalk in this case), which is also contextual. As a consequence, class resolution is also contextual; The name #MyClass may refer to different classes in different contexts.

Classes can then be seen as virtual without relying on a specific lookup mechanism! We can then swap between two versions of a class without changing the depending code. But this also support other cases for instance class renaming.

There are still a few issues to dig out:

The context meta-level


Every object is contextual, including context instances.

Context methods are executed within a meta-context. As a consequence, a context stores their state in a meta-context and class resolution is realized using the meta-context. The later point is especially important for transformation function.

The chicken-egg problem


This approach does however lead to a chicken-egg problem:

To solve theses issue, we introduce

The #Root context

This does however still lead to an infinite recursion during change propagation. This recursion is stopped by detecting the cycle.

Also, the class MetaContext - which is a regular object - stores its state in its own unique instance!

This design is necessary to allow objects created during a transformation function to be used later in a "regular" context.

The big picture


The picture on the right is then a recap of the system from a high level perspective.

Other implications