Online Manual: Compound Classages
Classages allows programmers to ``mix'' two classages together to form a bigger classage, a compound classage. A compound classage is defined as follows:
classage X = Y + Z with P >> Qor
classage X = Y + Z with P >> Q as R
In both cases, X is formed by ``hooking up'' the P mixer of classage Y and the Q mixer of classage Z. The difference is whether the result of ``hooking up'' P and Q leads to the creation of a new mixer for X. For the first case, the answer is no and we therefore call this form compound with consumed mixers. In contrast, the second form is called compound with re-exported mixers. Technically, ``hooking up'' a pair of mixers is a process of having imports of one side satisfied by exports of the other, detailed in the paper.
Obviously, It is possible to have multiple mixer pairs ``hooked up'' during one mixing process:
classage X = Y + Z with P >> Q, U >> Vor
classage X = Y + Z with P >> Q as R, U >> V as W
The compound classage can also define its own constructors. For instance,
classage X = Y + Z with P >> Q {
X() { :Y(); :Z(); }
X(int x) {this(); }
}
denotes X has two constructors, distinguishable by different
argument types:
- one constructor (taking no argument) consequently invokes a constructor of classage Y, via the :Y() syntax, and then a constructor of classage Z. Such an invocation is called a participant constructor call;
- the other constructor (taking an integer argument) invokes the X() constructor of the same classage via a ``this'' constructor call, the same as in the atomic classage case.
Well-formedness and Typechecking
A compound classage classage X = Y + Z with P » Q or classage X = Y + Z with P » Q as R fails to typecheck iff
- Y or Z does not exist as an already defined classage.
- P is not a mixer defined in Y, or Q is not a mixer defined in Z.
- Cyclic definitions exist, such as:
classage X = Y + Z with P >> Q classage Y = X + Z with Q >> R classage Z = X + Y with R >> S
- Y and Z each have a connector of the same name, but one is generative and the other is singleton; The condition is analogous when Y and Z each have a plugger of the same name, but one is generative and the other is singleton.
- Y and Z each have a connector of the same name, but the two connectors do not have identical imports (including the number of imports, the names of imports and the signatures of the imports). The condition is analogous when Y and Z each have a plugger of the same name, but the two pluggers do not have identical imports.
- Y and Z each have a connector of the same name, but the two connectors have exports of the same name. The case is analogous when Y and Z each have a connector of the same name, but the two connectors have exports of the same name.
- If P declares a method (say m) as an import and Q declares m as an export, the signature of m in Q is not the same or more specialized than that in P (i.e. failure to conform to a subtyping property). vice versa for the situation when Q declares an import and P does an export.
For the compound classage with consumed mixers only, typechecking of classage X = Y + Z with P » Q fails iff
- For P and Q, some import defined in one of them does not have a default export, and at the same time not satisfied by an exported defined in the other. (dangling imports).
For the compound classage with re-exported mixers only, typechecking of classage X = Y + Z with P » Q as R fails iff
- R is already an interface defined in Y and R is not the same as P or Q; if so, such a compound would end up having two different interfaces with the same name R.
- P and Q each declares an import with the same name, but the two imports do not have identical signatures.
- P and Q each declares an export with the same name.
For compound classages with explicitly defined constructors, the compiler complains iff:
- Any constructor has a name different from the name of the enclosing classage.
- Some constructors of the compound classage have identical signatures.
- A participant constructor call is not on a classage being a
``part'' of the compound, for instance:
classage X = Y + Z with P >> Q { X() {:W() } } - if the arguments taken by any participant constructor call does not have types that can result in locating the unique most specific constructor.
- if the arguments taken by any ``this'' constructor call does not have types that can result in locating the unique most specific constructor.
- If in the body of a constructor, a participant constructor call or a ``this'' constructor call is issued but not at the beginning of the body.
Here is an example to demonstrate how the compiler rejects all programs that fall into the aforementioned conditions.