Mapping functions are the consumers and producers, the sources and the sinks, for marks, but what can a mapping function do with all of these marks?
The AccessorType mark we described above demonstrates how mapping rules are selected depending on the mark's value. If the value of the mark is isRemote, the mapping uses the rules that produce a component enabled for remote access. Otherwise, the rules for local access are used. Rule selection is one way in which a mapping function uses marks.
In cases where the mapping function has to fill in a blank in the target model, the mark acts as a value provider. As another example, we may decide to postfix certain class names with "_C." This string is a value that would be provided to the mapping function.
Selector marks may also be quantities used to optimize the target implementation. Consider a source model that must be transformed into an implementation that occupies as small an amount of memory as possible. We can save memory if we observe that a particular class has no actions that require references to instances of a related class. For example, if no action ever queries the set of Customers, the Customer class can be marked as extentLess, and no container need be generated for instances of that class. By extension, there is no need to generate accessor code.
In some cases, a mark may take on both roles. For example, in an automotive system that assists braking (an ABS), there are only four wheels, there always will be four wheels, and it ain't gonna change. In this case, an efficient implementation may be to construct an array of a fixed size (we're guessing, um, four). Other classes may have different fixed sizes, or may be of variable size on the heap, as usual. In this case, each class will have a mark, FixedSize, that, if set to any value other than zero, causes the mapping rule that creates an array to be invoked.