COOL

(Internal classification: historical) Reference paper: “Aspect-Oriented Programming” Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Lopes, Jean-Marc Loingtier, John Irwin, In ECOOP'97 – Object-Oriented Programming, Springer LNCS Volume 1241, P220 – 242 , 1997. The ECOOP paper only briefly talks about COOL. It instead refers to a Xerox PARC techreport 1) for more information.

Another source of detailed information is Lopes' PHD Thesis, which was was published later: “D: A Language Framework for Distributed Programming” Cristina Isabel Videira Lopes, PhD Thesis of the College of Computer Science of Northeastern University, 1997. We use the PHD thesis here as reference material as it is the most recent complete discussion of both COOL and RIDL.

Domain of the language

Both COOL and RIDL are designed as part of the D framework. “D is a language framework that supports new kinds of modules for addressing some of the distribution issues that are hard to capture in classes. […]. The language framework proposed here focuses only on a subset of [distributed system] applications […]: applications over the Internet, the Web, corporate-wide applications such as calendar managers, network managers, document management systems […], hospital management systems, front-end applications for database access, interactive multi-user environments, and many others like these.” The base language of D is Java, without the synchronized keyword.

“[D] really consists of two languages: (1) COOL, for controlling thread synchronization over the execution of the components; and (2) RIDL, for programming interactions between remote components.”

Intent of the language

“COOL provides means for dealing with mutual exclusion of threads, synchronization state, guarded suspension and notification […] A COOL program consists of a set of coordinator modules […] [These] are helpers with respect to the implementation of the classes: they take care of thread synchronization over the execution of the methods”

Join Point Model and Advice Model

  • JPM: General-Purpose : Coordinators act on method invocations to the target object.
  • AM: Domain-Specific : A coordinator defines exclusion constraints and pre-conditions for methods.

Anatomy of the language

A coordinator has a signature part and a body part.

The signature defines a list of class names of where the coordinator applies, and whether the coordinator is per instance or per class. Note that the list of class names does not support wildcarding, and that per class coordinator for a number of classes means that there is one coordinator for all the classes.

The body defines the behavior of the coordinator, and may contain various declarations:

  • Condition Variables: declarations of initialized boolean variable (array), used for guarded suspension
  • Ordinary Variables: declarations of variables of primitive types, used as auxiliary state for the coordinator. (Note that these values are immutable if they are not boolean, due to restrictions of the language discussed later.)
  • Self-Exclusive Methods: a set that “identifies the methods that can be executed by at most one thread at a time. […] Self-exclusion is re-entrant”
  • Mutual Exclusion Declarations: a set that “identifies a set of methods that cannot be executed concurrently by different threads”. Multiple such sets may be declared.
  • Method Managers: for a list of method names it defines
    • Guarded Suspension: a boolean expression on condition variables. While false, the thread calling the method remains suspended.
    • On Entry and On Exit Statements: code to be executed just before or just after the method runs, to update coordinator state.

The coordinator has complete access to instance variables declared in the classes it is coordinating (+ the non-private variables of their superclasses).

If a method is not mentioned in the coordinator, it is not included in the coordination strategy. It is important to remark here that COOL (and RIDL) does not have a strong separation of pointcut and advice, as is now usual. The pointcut is not only defined by the signature part, as this only identifies classes. Additionally, identification of methods is performed in various parts of the body.

The grammar of COOL and RIDL is fully described in appendix A of the thesis.

Typical Example

The classical bounded buffer in COOL, taken from Lopes' thesis:

coordinator BoundedBuffer { 
    selfex put, take; 
    mutex {put, take}; 
    condition empty = true, full = false; 
    put: requires !full; 
         on_exit { 
           if (empty) empty = false; 
           if (usedSlots == capacity) full = true; 
         } 
    take: requires !empty; 
         on_exit { 
           if (full) full = false; 
           if (usedSlots == 0) empty = true; 
         } 
  }

Enforced Restrictions

Advice in COOL is very restricted. Self-exclusive and mutual exclusive declarations have no extra programmable behavior, in method managers guarded suspension is only a boolean expression. Expressions are only allowed in on entry and on exit statements. However these expressions may only contain if-statements or assignment statements. The test of the if-statement can be an expression, excluding method calls. Assignment statements only assign to variables declared in the coordinator, and must have boolean results for their right-hand side expressions. (We assume this is to ensure correct typing when assigning to condition variables.)

Implementation description

The aspect weaver for both COOL and RIDL is discussed in detail in Appendix C of the dissertation: “The translation of DJ programs into Java is done by a pre-processor, of which the Aspect Weaver is the most important module. […] The Parser takes DJ programs and constructs representations of them (parse trees); the Semantic Analyzer checks the semantic validity of the tree, and, at the same stage, there may be some local transformations on the trees that facilitate the implementation of the Weaver (e.g. transforming COOL condition variable declarations into ordinary Java variable declarations, transforming RIDL traversal specifications into simpler structures, etc.); the Weaver takes those transformed parse trees and outputs new trees that represent woven Java programs; finally, the un-Parser takes those internal representations of Java programs and outputs Java.”

1)
D: A Language Framework for Distributed Programming Cristina Videira Lopes, Gregor Kiczales, Xerox PARC technical Report SPL97-010, 1997