Aspect Definition Language Specification

Clifford Heath, cjh@managesoft.com

(c) Copyright, Clifford Heath, 1983-2005.

Introduction

The Aspect Definition Language (ADL) is a language for defining the classification, attributes, relationships and values of arbitrary data objects.

Derivation

Every object in ADL is derived from another object, except the builtin Object which is the root of the derivation tree. ADL differs from most data definition languages in making no distinction between object instances and object classes; any object may be derived from any other object, thus any object may be treated equally as a class or an instance. Derivation is single; an object may have only a single base object (superclass in conventional terminology) - this restriction may be removed in later revisions of the language.

Containment

Any object may contain (be a parent of) any other object, almost without restriction on the types (classes) of the child objects. Containment has no depth restrictions. An object inherits (is regarded as containing) all the child objects of its base object recursively as well as its direct children. All objects have a parent, except the predefined Origin object.

Variables

A predefined Object called Variable has a set of predefined subclasses, each of which has an associated value notation. In future revisions of this language, syntax methods will specify notations for new Variable base types. Any object may contain Variables (children derived from Variable). All objects inherit some Variables from the predefined base Object class. Some types of Variables themselves contain Variables; they are parameterised.

Assignment

Each Variable belonging to an object (including by inheritance) allows the object to also contain a single Assignment object for that variable. If no Assignment exists nor is inherited for a Variable belonging to a given object, the value of that Variable is undefined for the object. If an Assignment is inherited, a local assignment overrides it.

References

An object may contain References, which are derived from the Reference object. References associate the objects derived from the parent object with the derived instances of another object. Two syntaxes are used, declaring associations as one-or-one or one-to-many of the referent object. Depending on usage, a Reference may be regarded as an index or a conventional association - these distinctions are elaborated below. Future revisions of the language will define additional characteristics of References, including support for Methods.

Extension

Finally, an object (including Variable, Assignment or Reference) may be defined as extending any other object. That is, it may declare that from its point of view (aspect or context), an extended object has additional children. The added children are hidden except when viewed from an aspect which includes (is or inherits) the aspect that defined the extensions. Assignments to hidden variables are hidden.

When viewed from the aspect where it is declared, a contextual assignment overrides the value of a variable outside that aspect. For example, an object may defined a textual message in the English language. When the object is queried from a German aspect, a local assignment may override the message with one written in German.

Any object may be extended. For example, an application may require that a documentation string be allowed for any Object. The application can declare a documentation Variable within (pertaining to) a Documentation aspect, so that normal queries of Objects disregard the documentation values.

Object Naming and Variables

In addition to the above, an Object contains a Name variable which may optionally be assigned. All the above listed features of ADL Objects are then supported by the following Variables of Object:

Super
A Reference to the object from which this object derives.
Parent
A Reference to the parent of this object.
Context
A Reference to the object context within this object is visible (frequently the same as Parent).
Name
A string which forms the name of this object (may be unassigned for an anonymous object).

Syntax

Syntax is free-form except within values - white-space and line breaks are ignored. The syntax of values is defined by the value notation for the Variable with which the value is used. The built-in Variable subclasses define value notations in a similar style to C and C++, so for example, white-space is relevant inside literal strings.

Both C and C++ style comments may be used.

New Objects

A new object is declared by saying its name and its superclass separated by a colon, and followed by a semicolon or a list of children:

The name BusinessPartner must resolve to an object that already exists in the local or an enclosing scope.  The base class may be omitted, and defaults to Object:

If an object will never need to have a name, there's no reason it should. Objects that are primarily values are often in this class:

Child scoping

A list of children is enclosed in braces { }:

An individual child may be referenced or created by the dot notation:

The syntax used here re-opens the scope of the Customer object, and adds ContactAddress within that object, not as an extension. An alternate syntax allows adding variables as extensions instead, see below.

A child may have a name the same as an identifier in another scope, including its type, for example:

This looks a bit like cheating; which GUID is which? It works because the base class search will disregard the object being declared (it hasn't been created yet), so will find the nearest definition, but it's preferable in this case (and sometimes necessary in others) to qualify the name:

The point . declares that the variable GUID derives from another GUID which is visible from global scope (probably because its parent is the predefined Origin object). Similarly:

The name Definitions is here found by looking through the class and base class contexts of each lexically enclosing context in the obvious way, and then the definition of GUID is found within the Definitions object.

A final special case exists for a new variable of the same name as its base object, the colon and base object name may be omitted if no children are declared (eponymous naming):

Assignment

A variable belonging to an object may be assigned a value using either the weak assignment operator ~ or the final assignment operator =. The assignment may be included in the declaration of the variable, or it may stand alone:

An assignment is an object declaration; it defines an Assignment object. The statement above which defines the Discount variable also defines an initial assignment (two objects created by the one statement). No object may have more than one assignment to a variable, nor to a variable for which it inherits a final assignment. The Assignment object has the following definition:

Variables

The above examples use variables including String and Integer. Variables are child objects that allow value assignment to this object and objects derived from it. Predefined Variable subclasses are as follows. The value notation for these types follows the C standard except where noted: For convenience and standardisation, a predefined Boolean enumeration is provided:

It is anticipated that a special syntax for defining enumerations will be defined in future.

Extending objects

Any object's context may be re-entered to add new variables and sub-objects, for example the definition:

has an identical meaning to both the following:

and

This is useful to provide forward declaration. Note that only the first definition of Customer may provide a base object.

It's also possible to extend system objects in this way:

or the shorter way of saying the same thing:

provides a new Comment variable, available for assignment on any Object.

Contextual extension

The examples of extension above show extensions originating in the same context as the object being extended. Contextual extension occurs when an object is extended from a context other than its home context:

This states that from the point of view of Customers (or anyone using the Customer's point of view), any Order has a Status, but these Status assignments are not relevant to (or visible from) any other context.

Values may be assigned contextually as well, so for example, a German context object may be defined which overrides value assignments containing English language strings:

Note that the OperationNames object has been re-opened outside its original context, so the added objects form a contextual extension.

When the object OperationNames is interpreted in the German context, the German values will apply, overriding the default values. This demonstrates why Assignments are treated as objects; they also are inherited and their values may be overridden. If no Assignment is visible for a given Variable, the variable has no value.

References

Objects may refer to each other by either 1-to-1 or 1-to-many references, which are declared using the operators -> and => respectively. To the right of the operator is the name of the target object or referent, of which an instance or instances may be reached using this reference. To the left of the operator is the reference name if any.

The target object name may be followed by a list of variables enclosed in square brackets and separated by semi-colons. The variables must exist in the referent. In the case of a 1-to-1 reference, the instances are expected to have a distinct set of values for the variables. References thus serve the purpose of both indices and foreign keys in conventional systems.

PartyId	: String;

BusinessPartner:
{
	PartyId;		// Define a new PartyId variable of type PartyId
}
->BusinessPartner[PartyId];	// All BusinessPartners have distinct PartyIDs

Customer : BusinessPartner
{				// definition left blank for this example
}

SalesRepresentative:
{				// definition left blank for this example
}

Order:
{
	OrderNumber : Integer;
	->Customer;		// Each order is for one customer
	->SalesRepresentative;	// and was credited to one Sales Rep.
}

OrderItem:
{
	OrderNumber : Integer;
	->Order;
	->Product;
}

Order
{
	=>OrderItem[OrderNumber]; // All items for this order.
}

SalesRepresentative
{
	Accounts => Customer;	// Each Rep handles a number of accounts
}

References may also contain child objects, which are particularly used to control the behaviour of underlying implementations. Just follow the reference with an open brace and declare the children - or do it in an implementation context:

Note that the variable list should not be re-specified when re-opening a reference.

Builtin Objects

To recap and (slightly) extend, here are the builtin objects in ADL: Obviously, it wouldn't be possible to process this specification; these are the objects needed before you can process others. In particular, the object Value cannot be defined; it is defined by the notation of the Variable to which it pertains.

Notes: