independent cycle bodies that will be executed in
parallel, and which will not, will be selected on the
basis of the costs associated with the compiler and the
system, and also on the options set by the
programmer.
The names “A” and “B” inside the loop body
should not be viewed as reusing these names in the
sense of assigning a variable in an imperative
program. Here, these names are used to denote values
in the loop body, and in fact they most likely will not
actually exist in the executable program. The
important point here is that each instance of the loop
body, containing specific values for i and j, will
independently calculate specific instances of integer
values, defined as i * j and i + j; then all of these
individual values will be collected together in a
couple of arrays and returned. The positions of the
values in the result arrays, as well as the total size and
dimension of the returned arrays, are determined by
their shapes and ranges of cycle indices. In this case,
two arrays are returned, each of which consists of N
2
integers: a two-dimensional array with an index from
1 to N in each dimension and a one-dimensional array
with an index that varies from 1 to N
2
. The use of
temporary names in the loop is optional, and the
above return condition can be rewritten as follows:
returns array [.., ..] of i * j;
array of i + j
without changing the final results. With such a
change, the body of the loop will become empty, and
essentially the language treats the expressions in the
“array of” as anonymous temporal.
The language offers the user a rich set of various
standard reductions, and also allows the definition
and use of its own reductions. The use of reductions
is good in that their implementation may depend on
the target computing system. When a program is
executed in a single-threaded environment, the
reduction can be performed sequentially, but when
executed in several threads it can be executed in
parallel.
The Try-catch mechanism is quite popular today
for error handling, but this approach has conflicts
with parallel program execution. When an exception
occurs, all execution threads must be stopped, the
pipeline is cleared, etc. Also, there are difficulties
with maintaining software determinism in the case of
parallel execution and the occurrence of exceptions.
For the Cloud Sisal language, such problems do not
exist, because it uses the semantics of “always
completed calculations”, which means that the Cloud
Sisal program execution flow never stops and always
returns the resulting value (possibly containing
“error” values) even if any erroneous situations. For
this, there is a distinguished erroneous value in each
type, for example, a Boolean type consists of the
values of true (true), false (false) and error value
(error [Boolean]). Unless otherwise stated, and any
arguments of operations on built-in types or
predefined functions are erroneous, their results will
also be erroneous values. It is always possible to find
out if the value of an expression is wrong, using a
special operation.
The language supports annotated programming
(Kasyanov, 1989) and concretizing transformations
(Kasyanov, 1991), allowing the user to describe the
semantic properties of the program, which are known
to him, in the form of formalized comments. A
comment that begins with the dollar symbol “$” is
called an annotation (or a pragma) and sets the
properties of the construction that follows (one
construction can be compared with several
annotations). The result of a unary expression in the
annotation to which it refers is denoted by a single
underscore “_”, and the arity of an n-ary (n> 1)
expression is denoted as “_ [1]”, ..., “_ [n]”. An
annotation can have the form “name” or “name = list
of expressions”, where names that are visible at the
location of the annotation can take part in list
expressions. Unrecognized annotations cause
compiler warnings.
Let us give some examples of annotations.
Before each expression there can be an annotation
“assert = Boolean condition”, which should be true
immediately after the expression is evaluated.
The assertions can be placed in function
declarations both before the returns keyword and
impose conditions on the returned values, and in front
of the first formal parameter and set conditions on the
formal parameter names specified in them, which
should be valid when the function is called
immediately before executing body function.
It is allowed also to replace the Boolean condition
in the assertion with the so-called extended Boolean
condition, which has either the form “(all <name>:
<Boolean condition>: <extended Boolean
condition>)” or the form “(is <name>: <Boolean
condition>: <extended Boolean condition>)” and
defines the scope for the name specified in it. For
example, the extended Boolean condition (all i: i> 2:
A [i] = 0) is true if all elements in the array or stream
A are zero for which the index is greater than two and
condition (is i: i> 2 : A [i] = 0) true if there is at least
one zero element in A with an index greater than two.
For example, the assertion in the header of the
function definition indicates that the specified
ICEIS 2019 - 21st International Conference on Enterprise Information Systems
626