Functions/procedures

<< Click to Display Table of Contents >>

Navigation:  Details >

Functions/procedures

Previous pageReturn to chapter overviewNext page

Gekko user-defined functions and procedures are defined with either FUNCTION or PROCEDURE. Functions and procedures are basically the same: a procedure is interpreted as a stand-alone function without return value (just with a different syntax).

The code basically gets converted into suitable Func<> delegates, and is stored in the object Program.libraries. This object is derived from the Libraries class, which contains a List<Library> libraries of normal libraries, and a Library called globalLibrary.

When the library features (cf. the LIBRARY command) are not used, Gekko just puts user-defined functions and procedures into the globalLibrary. The Library class contains info like name, file path, but the most important part is a Dictionary<string, GekkoFunction>, which stores the functions by name. GekkoFunction contains elements like .function0, .function1, .function2, etc. These are Func<>s, for each number of parameters. So a function f() ends up in .function0, a function f(x1) ends up in .function1, a function f(x1, x2) ends up in .function2, etc.

Normal functions/procedures are only searched for in Library globalLibrary, whereas libraries defined by the LIBRARY command end up in the list of loaded libraries (which is a List<Library>).

When a function or procedure is called with an argument, this argument is used whenever it is present in the body of the function/procedure. You may envision this function:

function val f(val %x);
  %= 2 * %x;
  return %+ 1;
end;
 
prt f(5);  //will print 11

 

Now, when f(5) is called, %x in the function definition attains the value %x = 5. What happens subsequently in the body of the function is that all occurrences of %x get "controlled" by the definition %x = 5, so whenever there is a %x, this occurrence is simply pointed to the variable %x present in the method definition. So a %x like that does not get looked up in databanks, but is simply referred to the definition (which in turn refers to a ScalarVal variable with value 5).

 

As mentioned here, user-defined functions/procedures have some capabilities regarding optional parameters. You may define the following function:

 

function val g(val %x1, val %x2 'Value of x2' = 100);
  %= 2 * %x1;
  return %+ %x2;
end;

 

Here, if you call g(5), %x2 will attain the default value 100 (and you may use g?(5) to activate prompting). What should be noted is that if a function g() has n optional arguments, the function will actually get constructed and stored (as a C# Func<>) in n+1 variants. This is done to keep function calls speedy, even in variants where default parameters are used.