Procedural Programming
This section shows you how to use the procedural features of the Analytica modeling language, including:
- Begin-End, (), and “;” for grouping expressions
- Declaring local variables and assigning to them
- For and While loops and recursion
- Local indexes
- References and data structures
- Handles to objects
- Dialog functions
- Miscellaneous functions
A procedural program is list of instructions to a computer. Each instruction tells the computer what to do, or it might change the sequence to execute the instructions. Most Analytica models are non-procedural — that is, they consist of an unsequenced set of definitions of variables.
Each definition is a simple expression that contain functions, operators, constants, and other variables, but no procedural constructs controlling the sequence of execution. In this way, Analytica is like a standard spreadsheet application, in which each cell contains a simple formula with no procedural constructs. Analytica selects the sequence in which to evaluate variables based on the dependencies among them, somewhat in the same way spreadsheets determine the sequence to evaluate their cells. Controlling the evaluation sequence via conditional statements and loops is a large part of programming in a language like in Fortran, Visual Basic, or C++. Non-procedural languages
like Analytica free you from having to worry about sequencing. Non-procedural models or programs are usually much easier to write and understand than procedural programs because you can understand each definition (or formula) without worrying about the sequence of execution.
However, procedural languages enable you to write more powerful functions that are hard or impossible without their procedural constructs. For this reason, Analytica offers a set of programming constructs, described in this chapter, providing a general procedural programming language for those who need it.
You can use these constructs to control the flow of execution only within the definition of a variable or function. Evaluating one variable or function cannot (usually) change the value of another variables or functions. Thus, these procedural constructs do not affect the simple non-procedural relationship among variables and functions. The only exception is that a function called from an event handler such as OnChange or a button OnClick attribute can change the definition of a global variable. See “Creating buttons” on page 128.
An example of procedural programming
The following function, Factors(), computes the prime factors of an integer x. It illustrates many of the key constructs of procedural programming.
See below for an explanation of each of these constructs, and cross references to where they are.
Numbers identify features below |
Function Factors(x) Definition: |
---|---|
1 | VAR result := [1];
|
2 | VAR n := 2;
|
3 | WHILE n <= x DO
|
4 | BEGIN
|
2 | VAR r := Floor(x/n);
|
5 | (result := Concat(result, [n]);
|
6 | x := r)
|
4,7 | END; /* End While loop */
|
7, 8 | result /* End Definition */
|
This definition illustrates these features:
VAR x := e
construct defines a local variable x, and sets an initial value e. See “Defining a local variable: Var v := e” on page 376 for more.- You can group several expressions (statements) into a definition by separating them by “;” (semicolons). Expressions can be on the same line or successive lines. See “Begin-End, (), and “;” for grouping expressions” on page 376.
While test Do body
construct tests conditionTest
, and, if True, evaluatesBody
, and repeats until conditionTest
is False. See “While(Test) Do Body” on page 381.- Begin
e1; e2; … End
groups several expressions separated by semicolons “;” — in this case as the body of a While loop. See “Begin-End, (), and “;” for grouping expressions” on page 376. (e1; e2; …)
is another way to group expressions — in this case, as the action to be taken in the Then case. See “Begin-End, (), and “;” for grouping expressions” on page 376.x := e
lets you assign the value of an expressione
to a local variablex
or, as in the first case, to a parameter of a function. See “Assigning to a local variable: v := e” on page 377.- A comment is enclosed between /* and */ as an alternative to { and }.
- A group of expressions returns the value of the last expression — here the function
Factors
returns the value ofresult
— whether the group is delimited by Begin and End, by parentheses marks ( and ), or, as here, by nothing.
Summary of programming constructs
Construct | Meaning: | For more, see |
---|---|---|
e1; e2; … ei | Semicolons join a group of expressions to be evaluated in
sequence. |
|
BEGIN e1; e2; …
ei END |
A group of expressions to be evaluated in sequence | |
(e1; e2; … ei) | Another way to group expressions. | |
m .. n | Generates a list of successive integers from m to n. | |
Var x := e | Define local variable x and assign initial value e. | |
Index i := e | Define local index i and assign initial value e. | |
x := e | Assigns value from evaluating e to local variable x.
Returns value e. |
|
While Test Do
Body |
While Test is True, evaluate Body and repeat. Returns
last value of Body. |
|
{ comments }
/* comments */ |
Curly brackets { } and /* */ are alternative ways to enclose comments to be ignored by the parser. | |
'text'
"text" |
You can use single or double quotes to enclose a literal
text value, but they must match. |
|
For x := a DO e | Assigns to loop variable x, successive atoms from array a
and repeats evaluation expression e for each value of x. Returns an array of values of e with the same indexes as a. |
|
For x[i, j…] := a DO e | Same, but it assigns to x successive subarrays of a, each
indexed by the indices, [i, j … |
|
\ e | Creates a reference to the value of expression e. | |
1 | VAR result := [1];
|
|
\ [i, j …] e | Creates an array indexed by any indexes of e other than i,
j … of references to subarrays of e each indexed by i, j …. |
|
# r | Returns the value referred to by reference r. |
Enable comment auto-refresher
Lchrisman