KL records

Records gives you a way to conveniently and efficiently store related information together. Each piece of information is called an attribute. Thus a record consists of record attributes. Each attribute has a type. For information about defining the type of an attribute, see the Variable/Attribute Types section of the documentation.

There is little difference between a record attribute and a local variable in a Command Implementation. In fact, each Command Implementation can be thought of as having a record containing all its local variables as attributes.

Example of defining a record (this is a record definition):

```
record TPerson;
    atr name, TText;
    atr emailAddress, TText;
    atr streetAddress, TText;
    atr height, uint16;
    atr weight, uint16;
    atr age, uint8;
erecord;

```

By convention, record definitions are usually named beginning with a capital letter "T" for Type, because the name will be used as a variable/attribute type. This helps distinguish the record definition name from variable names, and Command Implementation names, etc, thus avoiding conflicts and confusion.

The "atr" command can optionally have a third parameter, the initial/default value of the attribute (must be a constant value). If no initial/default value is specified, then the initial/default value is zero or empty or null (depending on the type of attribute, with null having preference over zero if both are possible). The initial/default value can be an expression (an arithmetic calculation) but it must be possible to calculate the answer/result at compile-time (as opposed to runtime).

## Records versus Tuples

Records and tuples are the same thing, except that a record defined using the "record" command is boxed, whereas a tuple defined using the "tuple" command is unboxed. Boxed means an instance is stand-alone / free-standing / independent, whereas unboxed means an instance can only exist embedded inside another tuple or record instance. Boxed cannot be embedded, unboxed must be embedded.

Example of defining a tuple (this is a tuple definition):

```
tuple TRect;
    atr left, sint32;
    atr top, sint32;
    atr right, sint32;
    atr bottom, sint32;
etuple;

```

A tuple definition can be used inside a record (or another tuple) like this:

```
record TSuperWidget;
    atr bounds, TRect;
    atr isVisible, bool;
    {...}
erecord;

tuple TRectAndName;
    atr r, TRect;
    atr name, TText;
etuple;

```

However a record definition cannot be used inside a tuple or another record (except by reference). The following example is illegal:

```
record TSuperWidget;
    {...}
erecord;

record TWidgetMaster;
    atr widgey, TSuperWidget; {ILLEGAL}
    {...}
erecord;

tuple TDoubleWidget;
    atr widg1, TSuperWidget; {ILLEGAL}
    atr widg2, TSuperWidget; {ILLEGAL}
etuple;

```

Likewise a local variable in a Command Implementation can contain a tuple but not a record. A variable can contain a reference to a record instance, but not a record instance directly. Example:

```
record TSuperWidget;
    {...}
erecord;

cmd Test;
    var r, TRect; {ACCEPTABLE}
    var widgey, TSuperWidget; {ILLEGAL}
    var widgey2, RefN TSuperWidget, null; {ACCEPTABLE}
    {...}
ecmd;

```

## Definitions versus Instances

It is important to understand the difference between a definition of a record (a record definition), and an instance of a record (a record instance).

The "record" and "tuple" commands create a definition, but NOT an instance. This means that they define HOW some data should be stored, but they do not actually create a place to store the data. After a definition is created, the definition can be used to create one or more instances, and then data can be stored into an instance. Definitions and instances are separate because it allows multiple instances to be created from the one same definition, and that is a very useful ability.

For example, you can create 1 record definition named "TPerson", and then create 3 instances of it. The first instance is for the person named "Tom", the second instance is for the person named "Dick", and the third instance is for the person named "Harry". All 3 instances have the same attributes, but different values stored in the attributes.

## Creating an Instance

\*\*\*\*\* TO DO: Explain command for creating an instance of a record. Don't forget issue of providing a value for UnchangingSize and unnullable ref attributes. \*\*\*\*\*

When creating a record instance, all the attributes in the new instance will be set to their initial/default value, as specified in the record definition. If no initial/default value was specified for an attribute, then the initial/default value is zero or empty or null.

It is not possible to create a stand-alone instance of a tuple (unboxed) definition. Instead you can create an instance of a record (boxed) definition that contains an attribute defined to use the tuple definition, and then the act of creating the record instance also causes the creation of an embedded tuple instance.

## Accessing Attributes in a Record Instance

\*\*\*\*\* TO DO: Explain how to use dot "." to access attributes in an instance. \*\*\*\*\*

Dot (".") is used regardless of whether the variable directly contains the record/tuple, or is a reference to the record/tuple (it works in both cases).

## Attribute Aliases

The "alias" command can be used to provide an alias (alternate name) for an attribute in a record or tuple definition.

In the following example, a tuple is defined containing 2 attributes named "x" and "y". And "h" is defined as an alternate name for attribute "x", and "v" is defined as an alternate name for attribute "y".

```
tuple TPoint;
    atr x, sint32;
    atr y, sint32;
    alias h, x;
    alias v, y;
etuple;

```

An alias command cannot appear before the attribute it defines an alias for. The attribute must be defined before any aliases that use it.

## Storage

The compiler is permitted to store record attribute values in any order it wants. For example, the first attribute in the record definition is not necessarily stored at the beginning of the memory allocated for an instance of the record. This allows the compiler to organize the storage in whatever way it determines is most efficient. It attempts to maximize speed and minimize wasted memory.

## Order of Evaluation

When a tuple definition uses another tuple definition, either can be specified first. The compiler achieves this by deferring evaluation (or full evaluation) of the contents (sub-commands) of the tuple definition until all tuple definitions have been found and their names registered. Other evaluations may also be deferred where necessary.

Here is an example of the order of evaluation:

```
cmd MakeNacho;                {1}
    var info, TWidgetInfo;    {12}
    set info.isVisible, true; {13}
ecmd;                         {2}

tuple TWidgetInfo;            {3}
    atr location, TPoint;     {7}
    atr name, TText;          {8}
    atr isVisible, bool;      {9}
etuple;                       {4}

tuple TPoint;                 {5}
    atr x, sint32;            {10}
    atr y, sint32;            {11}
etuple;                       {6}

```

The compiler may also use "on demand" strategies for determining when to evaluate commands, or when to finish evaluating a definition.