| Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
| Version 1.9 Build 1556 |
|
This chapter begins with an overview and a brief description of the types of values supported by Glish. You will be introduced to each type, the notions of dynamic typing, type conversion, and vector and array values. Each type is discussed in detail in § 3.2-§ 3.10 below.
There are sixteen types of values in the Glish type system:
);
Every value in a Glish script has one of these types. The function type_name returns as a string the name of its argument. For example,
type_name(2.71828)
returns ``double". type_name is more fully described in
§ 10.1, page
.
For most types there are ways of specifying constants representing values of the type. In the example above, 2.71828 is a constant of type double. The discussion of types in § 3.2-§ 3.10 below includes a description of how to specify constants for the types.
Glish variables are dynamically typed, meaning that their type can change with each assignment. Before any assignment has been made to a variable its value is F, the ``false" constant, and its type is thus boolean. So in the following example:
a := 5
a := 2.71828
a := "hello there"
a's type is boolean before the first statement is executed,
integer after the first statement,
double after the second, and after the third, string.
To see if a value has a particular type X, call the function is_X. This returns true if the value has that type or false otherwise. For example, the function name
is_integer(5)
returns a boolean value of true, while
is_double(5)
returns a value of false. The one exception is there is no
is_reference() function
for determining whether a value is a reference type; instead
you must use the type_name() function (§ 10.1, page
).
For example,
is_integer(ref 5)
returns true (see below, § 3.8, page
).
Some types are automatically converted to other types as needed. For example, an integer value can always be used where a double value is expected. In the following:
a := 5
b := a * .2
b is assigned the double value 1.0 and a's type
remains integer. Similarly, a double value can be converted
to a dcomplex value.
Automatic conversions are limited to converting between numeric types,
and converting a reference type to the type it refers to.
Other types require explicit conversion. For example, the following expression is illegal:
5 * "1234foo"
but the string can be explicitly
converted to an integer using the function as_integer. The
following yields an integer value of 6170:
5 * as_integer("1234foo")
The following functions are available for explicit type conversion:
as_boolean
as_byte
as_short
as_integer
as_float
as_double
as_complex
as_dcomplex
as_string
Details on how they do their conversions can be found in
§ 10.2, page
.
There are types that cannot be converted at all. For example, a function type cannot be converted to any other type.
Type mismatches result in run-time errors.
Most Glish types correspond to a vector of values rather than a single value. For example,
a := [1, 2, 6]
assigns to a a vector of three elements, each an integer.
A vector with only one element is called a scalar.
For example,
[5]
is an integer scalar and is identical in all ways to the constant:
5
In general,
you create vectors by enclosing a comma-separated list of
values within
square brackets ([]). The values must all be automatically
convertible to a single type (see § 3.1.3, page
). This
means that they must either all be numeric or they must all be the
same type. If they are numeric then they are converted to the ``highest"
type among them, as discussed in § 3.2.2, page
.
The individual values inside the []'s are not restricted to scalars; vectors can be included, too, and will be expanded ``in-line". For example,
[1, 7, [3, 2, [[[5]]]], 4]
is equivalent to
[1, 7, 3, 2, 5, 4]
integer vectors can also be created using the built-in : operator, which returns a vector of the integers between its operands. For example,
3:7
yields
[3, 4, 5, 6, 7]
and
3:-2.7
yields
[3, 2, 1, 0, -1, -2]
You don't have to list a value inside the brackets:
a := []
assigns to a an empty vector of type boolean. Note that
such empty vectors have the special property that they can be intermixed
with vectors of types that would otherwise be incompatible. For example,
["foo", "bar", []]
yields a two-element string vector, while
["foo", "bar", [T]]
results in an error because the elements of the constructed
vector do not have compatible types.
You can also create vectors using the seq function. (See § 3.6 and § 10.3 for a description.)
The length function returns the length of one or more vectors. It can be abbreviated as len. For example,
len( [3, 1, 4, 1, 5, 9] )
returns the integer value 6, and
1:len(a)
is a vector of the integers from 1 to the length of a.
If more than one vector is supplied as arguments to length, a vector is returned where each element of the resultant vector is the length of the corresponding parameter, so
len( 1:3, 1:9, 4:15 )
returns the vector
[3, 9, 12]
because the length of the first parameter was 3,
the length of the second parameter was 9, and the
length of the final parameter was 12.
The various arithmetic, logical, and comparison operators all work element-by-element when given two equal-sized vectors as operands. For example,
[1, 2, 6] * [5, 0, 3]
yields the vector
[5, 0, 18]
(See § 3.2.3, page
for more information on the behavior of arithmetic operators.)
Single-element vectors are referred to as scalars. If one operand is a multi-element vector and the other a scalar then the scalar is paired with each vector element in turn. For example,
[1, 2, 6] * 3
yields
[3, 6, 18]
If neither operand
is a scalar but the two vectors have different sizes
then a run-time error occurs.
Vector elements are accessed using the [] operator. For example,
a[5]
returns the 5th element of a. Here 5 is a vector index.
The first element
is retrieved using an index of 1 (a[1]; not
a[0] as would be the case in C). Indices less than 1
or greater than the size of the vector result in run-time errors.
For example,
(5:10)[3]
yields 7. The [] operator has higher precedence than the
: operator, so
5:10[3]
results in an error because the vector being indexed (the scalar [10])
has only one element and not three.
You can also set a vector element using the [] operator:
a[1] := 3
assigns 3 to the first element of a. The new element value
must either be of the same type as the vector, or both the vector and the new
element must be of numeric type, in
which case the vector's type becomes the
``highest" of the two types, as discussed in § 3.2.2, page
.
For example, if in the above assignment a's type was double then
the value of 3 would be converted to 3.0; if a's type
was boolean then a would first be converted to integer
and then its first element set to the integer 3.
It is possible to extend a numeric vector by setting an element beyond its end. Any ``holes" between the previous end of the vector and its new end are filled with zeroes (``false" for boolean values). So for example,
a := 1:5
a[8] := 32
results in a having the value [1, 2, 3, 4, 5, 0, 0, 32].
Furthermore, a previously undefined variable can be set to a vector
value by setting an element to a numeric value:
b[4] := 19
sets b to the value [0, 0, 0, 19].
You also can access or modify more than one vector
element at a time. (See § 3.6, page
, for a description.
.)