|
<< Click to Display Table of Contents >> PROCEDURE |
![]() ![]()
|
PROCEDURE is used to define user-defined procedures. Such procedures do not return variables like a user-defined FUNCTION, but are instead used in a similar way to in-built Gekko statements. A procedure without arguments is similar to running a program file, cf. RUN. See the LOCAL keyword if you need variables defined inside the procedure to be inaccessible/nonexistent outside the procedure.
Libraries It is possible to organize user-defined functions and procedures in libraries. These are basically just .zip-files that are loaded with the LIBRARY statement. |
Beware: arguments with negative numbers Procedures are basically simplified user functions, omitting parentheses and commas for convenience. Hence, a function call like f(1, -2, 3) would look like f 1 -2 3; as a procedure call. However, Gekko would interpret this as f -1 3; because 1-2 = -1. To remedy this: •Put a parenthesis around the negative number when calling the procedure, for instance f 1 (-2) 3;. •Transform the procedure into an equivalent stand-alone user function f(1, -2, 3), cf. FUNCTION. |
You may decorate a procedure with a <>-option field containing an optional time period. Procedures allow optional parameters with default values, and the procedure may prompt (ask) the user about these parameters, if f? is used instead of f, where f is the name of the procedure. See the LOCAL keyword if you need variables defined inside the procedure to be inaccessible/nonexisting outside the procedure.
Syntax
procedure procname <date t1, date t2>, type1 var1 label1 = default1, type2 var2 label2 = default2, ...;
body ;
end;
t1, t2 |
(Optional). You may state optional time period parameters inside <>-brackets, for instance procedure f <date %t1, date %t2>, series x; after which %t1 and %t2 are assigned to for instance 2020 and 2030 in the call f <2020 2030 z;. If the procedure is called without <>-brackets, for instance f z; , the parameters %t1 and %t2 are assigned to the local/global time period instead. Using <>-brackets in a procedure call does not in itself change the local time period inside the procedure: use for instance the BLOCK structure to do that. See examples. |
type1, ... |
Types of variables: series, val, date, string, list, map, matrix. You may also use the special name type for parameters, which behaves 100% as a string inside the procedure, but where the single quotes are omitted when calling the procedure from outside (the shorter call f y is used instead of f 'y'). |
var1, ... |
The parameters/variables/expressions |
label1, ... |
(Optional). A label for the parameter, used if the procedure is promting (called with f?). See more about prompting below. |
default1, ... |
(Optional). A default value for the parameter. If the parameter is omitted, the default value is used. If the procedure is asked to prompt (called with f?) and the parameter is omitted, the default value is shown in the dialog box. In the dialog box, Enter or Escape will return the default value, and fire up the next dialog box (for the next optional parameter). If a ; is entered in the dialog box, all the remaining parameters attain their default values, and no more dialog boxes are shown. For string input, the use of quotes (') in the input box is optional. At the moment, only val, date and string types can be used for prompting input boxes. |
procname |
The procedure name. The name cannot be the same as an existing Gekko statement name. |
body |
The procedure body, that is, the statements to be performed. If the body contains a RETURN statement, the procedure will abort at that point (just like a normal program file, cf. RUN). |
Tip: if you need to stop execution at a specific point/line to inspect variables etc., try inserting a STOP statement. This will abort from all called program files/procedures/functions, without executing anything more after the STOP (this is not the case regarding RETURN). Therefore, STOP can be practical for debugging, etc.
When calling the procedure, the arguments are separated with blanks, not commas (this makes procedures syntactically more similar to Gekko statements than Gekko functions).
Examples
The following examples illustrate the use of PROCEDURE. This procedure has no arguments, and functions rather like a .gcm file (cf. RUN):
procedure now; |
The following procedure multiplies two values, and prints out the result:
procedure mulval val %x, val %y; |
Note that the mulval arguments are separated with blanks, not commas. The following procedure adds three periods to the date 2000, printing out 2003:
procedure add3 date %x; |
The following procedure prints out 'sunshine':
procedure shine string %x; |
If you prefer to call the procedure with shine sun; instead of shine 'sun';, you may use the name type:
procedure shine name %x; |
The following procedure adds 'a' to a list, printing the elements 'x1', 'x2', 'a':
procedure adda list #x; |
Dividing pairs of series:
procedure div list #x, list #y; |
The following multiplies two matrices:
procedure mulmatrix matrix #x, matrix #y; |
This following procedure divides two series and prints the result:
procedure divser series x, series y; |
Alternatively, the same kind of procedure can be made with name types:
procedure divser name %x, name %y; |
Using name instead of series type has some advantages if, for instance, you wanted to pick out the second series from the Ref databank instead. In that case, you could just use prt {%x}/@{%y}; instead of prt {%x}/{%y}; inside the procedure body.
Local period example
procedure f <date %t1, date %t2>; |
When calling f;, the global time period is used for %t1 and %t2, whereas when calling f <2003 2003>;, we get %t1 = %t2 = 2003 inside the procedure. See also the similar example regarding user-defined functions.
Prompt and default values example
Gekko procedures allow default values, and prompting regarding these.
procedure f val %x1, val %x2 'parameter 2' = 1, val %x3 'parameter 3' = 2; |
Beware that f or f? will fail with an error, since the first parameter is required. As shown regarding the last procedure call, you may terminate a sequence of input boxes with ;, which means the default values are used for the current and following parameters. Pressing Enter or Escape returns the default value, and opens up the next input box. For prompt input, only the variable types val, date, string and name are supported at the moment (for name type, use for instance ... , name %x2 'parameter 2' = 'x', ...).
Note
Procedures and user functions do not live in databanks, and are hence not affected by CLEAR, CLOSE, READ, etc., but are removed with RESTART or RESET. See also FUNCTION if you need to use return variables.
If a procedure is defined without <>-brackets to indicate time, it may still be called with <>-brackets. In that case, the time period inside the brackets is just ignored.
If you need to run the same piece of code many times (for instance inside a loop), defining and calling a procedure is efficient. Running a .gcm file entails some fixed loading, parsing and compiling costs each time it is called. These costs are not present when calling a procedure.
You may at most use 14 arguments, else use maps to bundle incoming arguments. Per default, all arguments are passed by value, not by reference (cf. option system clone). This means that procedures cannot have so-called side-effects on the incoming arguments.
It is planned to introduce the type namelist in addition to the name type, so that an argument like (a, b, c) can mean ('a', 'b', 'c') internally.
Related statements