Cursor provides iterative access to a list progressing in either the forward or reverse direction. There are a number of operations a cursor can perform, summarized as follows:
Postfix | |
---|---|
++ | Step forward |
-- | Step backward |
Prefix | |
+ | Move to first position |
- | Move to last position |
Expression | |
cursor | Reference item at current position |
cursor[n] | Reference item at relative position n |
cursor = n | Move to specified position n |
cursor += n | Move to relative position n |
fact cursor | true if position is in range |
cursor.index() | Current position of cursor |
Notice that cursor[0] is identical to just cursor. In addition, if the cursor is bound to an axiom list, then cursor-> can reference terms of the axion at the current position by name.
Format
There are two types of cursor reflecting how the binding to a list occurs:
- Closed - the list is bound by unification to a list with the same name as the cursor
- Open - the bound list is referenced by qualified name
The closed type hides the bound list so it can only be accessed via the cursor. The open type type allows the list to be modified independently of the cursor. Both cursor types can be declared in template scope, but a closed cursor can also be declared in a flow body.
Open Cursor
An open cursor is always declared in template scope. The bound list name is a single identifier which is resolved to a fully qualified name by performing a list search. The cursor may optionally be assigned a type if type conversion is desired, for example, decimal to currency:
[ reverse ] cursor [ <type> ] name(list-name)
Insert Sort
high-cities-sorted2.taq performs an insert sort using a cursor to access the insertion list. This is much more elegant that accessing the list by index`. Here is the insert_sort' flow with cursor "city":
flow insert_sort
{
cursor city(high_cities)
(
altitude? > 5000,
// Append next city from source
high_cities += axiom high_city { name, altitude },
// Point cursor at city just inserted
-city,
// Save city and point to preceding city in list
inserted = city--,
// Skip case only one city is in the list
? fact city,
// Remember start position
start = city.index(),
// Shuffle list until sort order restored
{
city[1] = city--,
? fact city
// All done if inserted city was in sort order
?: city.index() == start,
// Place latest city in correct position
city[1] = inserted
Note how the offset access city[1] can work even after the cursor has decremented out of range according to fact city .