8.2.5. Type identifiers

Top level model types, like contexts and roles, have names that are scoped to model namespaces. This means that their name is prefixed with a namespace identifier. For example, the type PerspectivesSystem is identified by:

model://perspectives.domains#System$PerspectivesSystem

8.2.5.1. Type versioning

Peers send deltas to a Distributed Runtime, so the installation may update its instances. A delta contains type information. We have to accommodate the situation where a peer might have another version of the model containing the type, than the receiver. Therefore we need to version types, too:

model://perspectives.domains#System$PerspectivesSystem@1.0.0

Consider a domeinfile, representing a model at version 1.0.0. Now the author modifies the context PerspectivesSystem, but nothing else. This means that just the identifier of PerspectivesSystem changes: all other identifiers will retain their previous version.

model://perspectives.domains#System$PerspectivesSystem@1.1.0

Obviously, all references to PerspectivesSystem in the model will be updated, too (but this does not cause those referring types to have version 1.1.0, too).

This allows for quick checks when a delta comes in to create an instance. All deltas from a peer using model version 1.1.0 will be allowed, only a delta to create an instance of PerspectivesSystem will be reason for further analysis.

Newer type versions may be downward compatible. For example, a context with an extra role is shape-compatible with instances without that role.
8.2.5.2. Type renaming

A frequent kind of change is when the author chooses a new local name for a type. For example, PerspectivesSystem might be renamed to PSystem. This is not a structural change and has no consequences whatever, in runtime. Obviously, it does have consequences in model time:

  • Existing references to the name in the model text must be updated;

  • Existing references to the name in other model texts must be updated, too.

However, type renaming does not cause an increase of the semantic version of a model. If there are other reasons to increase the version, renamed types retain their original version.

Nevertheless, instances refer to types by identifier. How can we make that work? How can a type identifier change, while existing instances do not change their reference?

This is because a reference to a type name is not by its visible name (the local name entered by the author, prefixed by namespace), but by a generated local name (prefixed by namespace). The domeinfile contains a table that maps the two to each other.

When a model is first parsed and saved, all local names are replaced by an integer. Integers start with 0 (for the root type, i.e. the namespace itself, the model identifier) and then increasing by 1 for every next type that the parser encounters. For example:

model://perspectives.domains#System$PerspectivesSystem@1.0.0

is referred to in the domeinfile and in instances with:

model://perspectives.domains#System$0@1.0.0

If the author modifies PerspectivesSystem to PSystem, he should provide an instruction to the parser:

context PSystem [renamed from PerspectivesSystem]

After a successful parse and save, he may (but need not) remove the instruction. The parser looks up the old name in its table and replaces it with the new name.

8.2.5.3. Handling backwards-incompatible changes in instances

Let’s say that an author changes the type of a property from Boolean to Integer. Role instances that have a value for that property are no longer described by the new type. A property change like that needs to be followed by a change of the shape of the value in the instances.

We may construct a scheme of automatic repairs to be carried out on data on the occasion of such model changes. Lacking that, some changes can be carried out automatically to ensure proper functioning, but possibly to the cost of semantics. For example, every type can be mapped to a String. Booleans may be mapped to Numbers according to some scheme (e.g. 0 for false, 1 for true), etc.

It turns out that very few model changes do actually cause a problem with the shape of the instances (see [Model versions and compatibility]).

8.2.5.4. Imports

A model text imports dependencies in this way:

use sys for model://cw.perspectives.domains#System@1.1.0

Type names imported from another namespace will be replaced by using the name table of the corresponding domeinfile.

If the author updates the version of an import, the parser MAY compare the name table of the previously used version with the that of the new version, if the author provides an instruction:

use sys for model:cw.perspectives.domains#System#1.15.0 [up from 1.11.0]

Imported names must be fully qualified (either written in full, or with a prefix). Hence the parser can scan the model text for names that are replaced in the import (using the prefix, if applicable) and replace them automatically in the text.

The next parse is then guaranteed to be able to replace the each imported identifier by its number.

The model text may refer to types that have been dropped in the new version of the import. The parser MAY report these to the author.