This section describes the different kinds of IBAL values, how each kind is produced, how they are displayed, and other details. Values in IBAL are classified as follows.
All values
|
|---------- ADTs and anonymous tuples
|
Internal values
|
|---------- Tuples
|
Atomic values
|
|---------- Function values
|
Primitive values
At the bottom of the hierarchy are the primitive values,
representing the basic units with which IBAL works. These consist of
three kinds of values: strings, integers, and Booleans. Each of these
is produced by a literal of the corresponding kind. Integers are
displayed in the obvious way. The Booleans are displayed as
True and False regardless of the case of the literal
that produced them. Strings are displayed without the accompanying
quotation marks.
The primitive values are a subset of the atomic values, which represent values that cannot be broken up into components. The non-primitive atomic values are the function values, representing functions from one set of values to another. The function values consist of the operators and the closures.
There is a finite set of operators, or built-in functions
operating on primitive types, whose behavior is predetermined.
These are the Boolean conjunction, disjunction and negation
operators, the integer negation, addition, subtraction, multiplication,
division, remainder, increment and decrement operators, and the
string concatenation operator. The operators can be used in infix
notation, using the tokens described above. The - token is
recognized to be the unary negation operator or the binary subtraction
operator by context.
Operator values can be produced by the expression op x where x
is the operator token. In the case of -, op - is
defined to produce the binary operator. To produce the unary
operator, the expression op _ is used.
Operators are displayed as their tokens.
Closures represent defined functions. They have a set of arguments, a
body, and the context in which the function was defined. A closure
may optionally have a name.
Closure values are produced by fix and lambda
expressions, and by variable definitions in which the variable has an
argument list. In the case of a fix expression and variable
definition, the closure has the given name, while the closure produced
by a lambda expression is anonymous.
A closure is displayed as its name if it has one, otherwise it is
displayed as Fun i, where i is a unique integer
identifying the closure. Closure values cannot be compared for
equality.
All non-atomic values are called compound values.
The atomic values are a subset of the internal values, which
represent the values that IBAL manipulates in its evaluation process,
and presents to the user.
The compound internal values are the tuple values
<n_0 : v_0, ..., n_m : v_m> where each n_i is an lident
and v_i is an internal value.
The <n_i> are called components of the tuple value, and the
component <n_i> is simple if <v_i> is atomic,
otherwise it is complex (in which case <v_i> must be a
tuple).
The embedded components of a tuple v are defined as
follows.
Each of the components is an embedded component,
and if n_i is a complex component and c is an embedded
component of v_i, then n_i.c is an embedded
component of v.
The simple embedded components of a tuple are its embedded
components in which the final component is simple.
Dot notation can be used with tuples of any form.
If x is an entity associated with y, and y is a
tuple with component a, then x.a refers to the entity
associated with component a of y.
The prefix x itself may be defined using dot notation, thus if
x is z.b then z.b.a is the same as
x.a.
Any sequence of one or more names separated by dots is called a
chain.
Lexically, a chain is produced by a longvar or ulongvar.
Tuple values are produced using tuple expressions. To display a tuple value, IBAL uses a column for each simple embedded component, and displays the atomic values associated with that component. The order of components is not significant in a tuple value. Two tuple values are equal if they have the same set of components, and the values associated with corresponding components are equal.
In contrast to the internal values, the external values represent values that appear in IBAL programs but are not used in its evaluation process, and are not displayed. External values are converted to internal values for processing. The external values include the anonymous tuples and ADT values.
Anonymous tuples are similar to tuples, except that the components are
not named and the order does matter. An anonymous tuple has the form
<v_0, ..., v_m> where each v_i is a value.
It is produced with an anonymous tuple expression,
and is considered to be equivalent to the tuple value
<0 : v_0, ..., m : v_m>.
Algebraic data types (ADTs) are types that have multiple fields like
tuples, and also have multiple forms. Each form has a constructor
together with an associated set of fields. An ADT value has the form
C(v_0,...,v_m) where C is a uident representing the
constuctor, and the v_i are the values of a fields. It is
produced using a constructor expression, and is considered to be
equivalent to the tuple value
<! : 'C, C_0 : v_0, ..., C_m : v_m>.
The first component ! represents the constructor, and is used as
a tag indicating what form of the ADT is being used.
The other components represent the field values.
As a result of this conversion, different values of the same ADT may
be represented by tuples with different components, because the
constructors may be different.
When displaying different possible tuple values, where the tuple
values may have different components, IBAL uses a table with a column
for every embedded simple component that appears in any of the tuple
values. As a result, each of the individual tuple values may only
have embedded simple components for some of the columns. The display
# is used to indicate those components that are
undefined for a particular tuple value.