Chapter 13. Modules

Modules enable you to break your program into smaller and more understandable parts. They make it possible to reuse parts of the code and enable people to build on other programmers' work. Rax does not have a formal module concept such as Pascal or Python. It does, however, enable you to include source files and therefore split larger scripts into logical parts. To include another file in your script use the %include directive:

    %include "another-rax-script.rax";
       

For example, if you have a couple of functions that you often reuse in your script, you could create a separate Rax file containing these functions:

    //
    // my_favorite_functions.rax
    // author: me
    //
    & <- [&:x, &:y]: myNumericalFunction <-
    {
      out := 0.3456*sqrt(in.x) + in.y ** -3.3435;
    };

    & <- {&}: myStatisticalFunction <-
    {
      // Compute the sum of the square roots of the input set elements
      out := fold [/sum(sqrt(.#1)] in;
    };
       

Then, you can include my_favourite_functions.rax in your scripts:

    //
    // very_useful_script.rax
    // author: me
    //
    %include "my_favorite_functions.rax";

    {&,&}: realNumbers := project [(&).#1, (&).#1] {1..1000};
    {&}: interestingNumbers := myNumericalFunction(realNumbers);
    &: interestingResult := myStatisticalFunction(interestingNumbers);
       

Notice that in the example above, myNumericalFunction is defined on a tuple of a tuple of two real numbers. It is called, however, on a set of such tuples. This is an example of auto-iteration: allowed and results in auto-iteration: the Rax interpreter will automatically call the function on each element of the set and will return the set of results.

Rax searches for files to satisfy an include directive in a manner patterned after that used by GCC when resolving include files. Like the C language, Rax provides for system includes and user includes. In order to resolve user includes, Rax checks the current directory first, followed by the user search path, before finally checking the system search path. System includes use the same rules, but do not check the current directory first (unless it is part of the user search path, of course). The user search path can be modified using the %raxpath directive, while the system search path cannot be modified by the user. For a full discussion of the search path rules used by Rax, see the section called “%include” and the section called “%raxpath”.

By default, Rax will include each file only once. If you try to include the same file twice, Rax will issue a warning:

    Error: Rax warning: re-inclusion of "include.rax" ignored.
       

If for some reason you want to force Rax to include a file twice, use '!':

    %include !"include.rax";
       

To make your code even cleaner, you can use tuples as namespaces in the include file, and the 'with' clause in the including file. The example below shows two ways of doing the same thing using three variables and a function, imported from some include file:

    %include "mynumbers.rax";

    // variables k, l, m and function F are defined in "mynumbers.rax"
    //
    mynumbers.k := 40;
    mynumbers.l := 02;
    mynumbers.m := 42;
    `print mynumbers.F(k,l,m);

    // Use the with construct to avoid repeating the module name
    //
    mynumbers.{
      k := 40;
      l := 02;
      m := 42;
      `print F(k,l,m);
    };