Expression Pattern Language (eXPL)

Basic Lists

Lists in eXPL contain ordered sequences of basic type values, terms or axioms. A list can be declared to contain items of one specific basic type. such as integer or string, or the terms of a single axiom or a collection of axioms. There are a total of seven list types, which were introduced in the Lists application of tutorial3. There are 5 basic type lists, which are described here, and the remaining lists relating to axioms are treated separately as they have special characateristics.

These are the aspects of lists to be covered:

  • Declaration
  • Export
  • Access
  • Navigation

List Declaration

A Basic Type List declaration has format:

list<type> name [ = { initializer-list}]

The optional initializer-list is a comma-delimited sequence of values or expressions used to populate the list. Type conversion is supported. for example, a decimal list is initialized here with formatted number string literals:

list<decimal> huges = {
"9,223,372,036,854,775,808",
"-9,223,372,036,854,775,808" };

A list declaration cannot be located as a template term but it can be attached to a template using a plus sign. Here is an example where an attached list declaration which creates a list of dice face values:

template dice
+ list<integer> dice = { 1, 2, 3, 4, 5, 6 };
(
dice[0], dice[1], dice[2],dice[3], dice[4], dice[5]
);

An attached list is not visible outside the template, but can be exported to the query result by using the export modifier.

List Range

Another option is to declare a list with range values that define a start offset and a limit to how big the list can grow:

list<type> name ( start,end )

The "start" value is first valid index value and "end" is the last valid index value. When a range is set, then an item can be inserted at any location within the range. Without a range set, a list can only grow by appending items to the end of it. Care must be used when a range is set as a list will contain empty locations unless/until the program fully populates it.

Application AssignMarks of tutorial6 shows a list with range of 1 to 18 initialized in reverse order so the alphabetical items it contains are arranged in descending order. Without the range, the only choice is ascending order.

In DeclareMarks application of tutorial6, a blank item is placed at the start of a declaration initializer list to a achieve an effective range starting at 1.

Export

When an eXPL query is executed, a result object is returned containing all exported artifacts. Declared lists are not normally exported, but this can be changed for a particular list by using modifier export at the start of it's declaration. The list is made available by the result object using type-specific methods eg. to get the dice items of the previous example, you could use decimalIterator to iterate through the list from start to end.

Here is an example of list named "amount_list" declared with the export modifier:

calc all_amounts
+ export list<currency> amount_list;
...

The exported list is referenced by name. The name of a list which is attached to a template includes the name of the template. The recommended name format is the "artifact" format, which is like an email address. The artifact name for the above example, assuming it is in the global scope, is amount_list@all_amounts.global. A shorter equivalent is amount_list.all_amounts@ as global scope is the default if scope is omitted. You could also use the part format, where the order is reversed, eg all_amounts.amount_list. You can experiment with all three name variants in the CurrencyList application of tutorial6.

Access

Any list can be accessed for read or write using array notation as seen in list examples already presented. If a list is declared with only type and name, then the start offset is determined by the first insertion. For example, if you want a list to start at 1 instead of 0, then insert the first item at position 1. You can try this with the AssignMarks application of tutorial6 by removing the range from the list declaration and reversing the order of insertion:

list<string> mark;
  mark[1] = "f-";
  mark[2] = "f";
  ...
  mark[18] = "a+";

A list item is accessed using a list variable, which is similar to an ordinary variable in that the operations it can perform are determined by variable type. The list variable will have a composite structure if the index value is evaluated. The terms in such a structure are subject to unification and evaluation, though the list variable itself is only subject to evaluation.

Navigation

Lists are typically traversed incrementally, for which access using an iterator is preferred over indexing an array. There is both a read and write iterator available for navigating lists, but not one to allow both read and write access. The read iterator is called a cursor and the write iterator is called an appender.

Appender

An appender is a variable named the same as the list to be accessed. The concatenation += operator is used to append items. An example of this can be found in application AppendMarks of tutorial6. This has a template which declares a string list called "student_marks" and appends a text report to the list using a variable also named "student_marks". Note that the list is referenced in the application in artifact format as "student_marks.score@".

Cursor

A cursor is a list variable which performs a small number operations for navigating a list, for example - postfix ++ advances the cursor to the next item in the list in the forward direction. A cursor works well when used in a loop in order to traverse a list. Therefore, a full description of cursor is delayed until the topic of loops has been covered - see Cursor. A first look at a cursor is given in application CursorMarks of tutorial6. This declares a global integer list named "student_grades" and sets up a cursor variable named "grade" to read this list using the following declaration attached to a template:

cursor grade(student_grades);

Other notable facts about cursor is that it is capable of performing type conversion and it has the same access to a list as any other list variable, but indexes are offset by the current position of the cursor in the list.