Values¶
Expressions are evaluated into values at run-time (or live performance). There are two kinds of values:
-
scalar or atomic values, described in chapter Scalar Value, include the undefined value, booleans, integers, floats (IEEE double), symbols, function definitions, process definitions and running processes (exec);
-
data structures or compound values like strings (sequences of characters), tabs (tables, vectors), maps (dictionaries), and interpolated functions NIMs. Such data structures, described in chapter Data Structures, can be arbitrarily nested, to obtain for example a dictionary linking strings with vectors of interpolated functions.
A compound value is referred to using a handle (or pointer). So, the same compound value can be shared between variables or shared between nested data structures (see data structure).
This is important because a compound value \(v\) is a mutable data structure: you can change an element in the data structure and this does not change the value itself. It means that the variables referring to the value \(v\) will refer to the changed data structure. On the contrary, atomic values are immutable: you cannot change an atomic value, you can only build a new atomic value.
Functions can be used to combine values and build new ones. The programmer can define his or her own functions (see chapter Function), also having access to a large predefined Functions Library. The figure below shows a simple score excerpt employing a simple expression and value. The text score on the right declares four expressions to be sent to receivers “hr1-p” to “hr4-p” (harmonisers) whose final value is being converted from semi-tones to pitch-scale factor. This graphical representation shows their evaluation.
In this example we are able to use the final values of the expression in the graphical display of the score by AscoGraph since the arguments of the expression are constant. So these expressions are recognized itself as constant and their value is computed when the score is loaded (a mechanism known as “constant propagation”). If a variable were to be used, the expression would stay intact in the visual representation to be evaluated at run-time. Variables will be discussed in section Variable.
Dynamic Typing¶
From a programming language perspective, Antescofo is a dynamically typed programming language: value types in Antescofo do not need to be explicitly specified; the type of values are checked during the performance and this can lead to an error at run-time.
When a wrong argument is provided to an operator or a predefined function, an error message is issued on the console and the returned value depends of the operators involved (often, the undef value). See section Dealing with Errors for useful hints on how to debug an augmented score.
Compound values are not necessarily homogeneous : for example, the first element of a vector (tab) can be an integer, the second a string and the third a boolean.
Note that each kind of value can be interpreted as a boolean or as a string. The string representation of a value is the string corresponding to an Antescofo program fragment that can be used to denote this value.
Checking the Type of a Value¶
Several predicates check if a value is of some type:
-
@is_numeric (which returns true if the argument is either @is_int or @is_float),
-
@is_fct (which returns true if the argument is an intentional function)
-
@is_function (which returns true if the argument is either an intentional function or a map)
-
@is_obj_xxx (where
xxx
is the name of an object definition).
Value Comparison¶
Two values can always be compared using the relational operators
< <= = != => >
and the @min
and @max
operators.
The comparison of two values of the same type is as expected: arithmetic comparison for integers and floats, lexicographic comparison for strings, etc. When an integer is compared against a float, the integer is first converted into the corresponding float. Otherwise, comparing two values of two different types is well defined but implementation dependent.
The various kind of values are reviewed in chapters Scalar Values and Data Structures. Antescofo is a high-order language, so Functions and Processes are also values, as well as Actors.
In the rest of this chapter, we review: