While Glish supports the ``usual" form of single-element vector access familiar to C and FORTRAN programmers, it also provides ways for accessing or modifying more than one vector element at a time.

Glish vector indices needn't be scalar values; the indices can also
be multi-element vectors. The indices have different meanings depending
on whether their type is `integer` or `boolean`. We discuss
each of these in turn below.

If the index's type is `integer` (or *numeric* and hence convertible
to `integer`; but *not* `boolean`),
then the values of the index indicate
the desired elements of the indexed vector. For example, if we have

a := [5, 9, 0, -3, 7, 1] b := [4, 2]then

a[b]yields the vector

[-3, 9]since

a[[4,2]](which is equivalent to

a[b+2]yields

[1, -3]since those are the 6th and 4th elements of

Since the `:` operator yields an integer vector, you can
use it to access a contiguous sequence of elements in a vector:

a[3:5]yields

[0, -3, 7]since those are the 3rd through 5th elements of

a[2:1]yields

[9, 5]as those are the 2nd and 1st elements of

rev_x := x[len(x):1]

The `ind` function provides a convenient way for generating
a vector value's indices:

ind(x)is equivalent to:

1:len(x)

The `seq` function provides a somewhat more flexible way to generate
vector indices. `seq` takes one, two, or three arguments. For our
purposes here we will limit these arguments to be integers; see
§ 9.3, page , for a complete discussion of `seq`.
If `seq` is invoked with just one scalar argument then it returns a
vector of the integers from 1 to that value:

seq(7)yields

[1, 2, 3, 4, 5, 6, 7]for example. If it is invoked with a single non-scalar argument then it returns a vector of the integers from 1 to the length of the argument:

seq([3, 1, 4, 1, 5, 9])yields

[1, 2, 3, 4, 5, 6]

If `seq` is invoked with two arguments then it returns
the integers between the two, inclusive:

seq(5,2)yields

[5, 4, 3, 2]If the first argument is a non-scalar then its first element is used to determine where the sequence begins.

If
invoked with three arguments then `seq` returns the integers between
the first two using the third as a *stride*. It starts with the first
value and works its way to the second, each time incrementing by the
stride. It stops when it passes the second argument. So

seq(3,10,2)yields

[3, 5, 7, 9]and

seq(20,8,-4)yields

[20, 16, 12, 8]while

x[seq(1,len(x),2)]yields every other element of

seq(20,8,4)would result in a run-time error. If a stride is given then it must reflect the direction in which the sequence will proceed. (This is perhaps a bug.)

A `boolean` vector index forms a *mask*
that picks out those elements for which the mask is true. For example,

a := "hello there, how are you?" print a[[F,T,T,F,F]]will print ``there, how". Similarly,

y := x[x > 5 & x < 12]will assign to

max(x[x < 10])will return the largest element of

Often we want to know the *indices* of those vector elements with a
certain property, rather than the *values* of those elements. The
following illustrates the idiom for doing so:

neg_indices := ind(x)[x < 0]Here we have assigned to

`neg_indices`

the indices of those
elements of x[neg_indices]and

x[x < 0]are equivalent expressions.

Boolean indices must have the same number of elements as the indexed vector, or else a run-time error occurs.

In addition to using vector indices to *access* multiple vector
elements, you can also use them to *modify* multiple elements.

a[[5,3,7]] := 10:12assigns to the 5th, 3rd, and 7th values of

a[[5,3,7]] := 0sets those same elements to 0.

The same sorts of operations can be done using masks:

a[a > 7] := 32changes all elements of

x[x < 0] := -x[x < 0]is the same as

x := abs(x)(indeed, this is how

As with simple, scalar assignments, the types on both sides
of the `:=` operator must be compatible, as discussed in
§ 3.1.3, page .

The right-hand-side must either be a scalar or have the same number of elements as indicated by the indices or mask used on the left-hand-side. For example,

a[1:3] := [2,4]is illegal.

As with vectors, you can access and modify multiple record fields using multi-element indices. For records the index must be a vector of strings. For example,

a := [foo=1, bar=[3.0, 5.3, 7], bletch="hello there"] b := a[["foo", "bar"]]assigns to

b := a["foo bar"]

You can assign multiple record fields in a similar fashion:

a["foo bar"] := [x=[9,1], y=T]will change

r := [x=[9,1], y=T, z="ignore me"] a["foo bar"] := r["x y"]For the assignment to be legal, the right-hand-side must be a record with the same number of fields as the left-hand-side (as in the example above). The field names are ignored but the assignment is done field-by-field, left-to-right.

As discussed in § 3.4.4, page , you
can access records using *numeric* subscripts, and just as can be
done with vector values, you can use multiple numeric subscripts to
access and modify more than one field in the record. For example,
the following reverses the fields of `r`:

r := [x=1, y=T, z="hello"] r[3:1] := rso that now