Chapter 19. Meta instructions and macros

Table of Contents

Meta instructions
%help
%csv
%epsilon
%digits
%raxpath
%include
%logfile
%missing
%order
%outfile
%remove
%sql
%symtab
%time
%tree
%warn
Macros

For convenience reasons, Rax provides several meta instructions and macros, which we will describe in more detail in this chapter.

Meta instructions

Meta instructions are different from normal instructions in three ways. First, they can have side effects (even outside the Rax environment), second, they can reveal information about the internal state of Rax interpreter, and third, they are executed when encountered even when inserted halfway a function definition, i.e., a meta statement in a function will be executed when the function is defined, not when it is called. The below example code illustrates the last difference between regular and meta statements:

    $ <- #: f <-
    {
      %include "mycode.rax";
      out := ($)in;
    }

    `print f(1);
    `print f(2);
    `print f(3);
         

The above code, when executed, would try to include the file mycode.rax only once. Please be advised that using %include in a function, as in the above example, is considered harmful, though it might be acceptable in exceptional cases. Meta instructions should be used with care. They can be used to remove a file or a database table.

%help

%help;

Prints a list of meta instructions with a short explanation. This will display a list not unlike the list below:

    %csv ["separator" [,"escaper" [,"escapees" [,"quote" [,"quote"]]]]];
    %epsilon [real]; // Get or set the real comparison epsilon value.
    %digits [<#>[,<#>]]; // Get/set the minimum width and precision to display reals.
    %help; // Print out this message.
    %include [!] <filename>; // Include a file (use '!' for force).
    %logfile <off|stderr|stdout|[+]"filename">; // Redirect log output or hush it.
    %missing [<#&$?@^~|> <expr>]; // Set substitute values for missing values.
    %order <expr>; // Print the order index of an oset on stdout.
    %outfile <off|stdout|stderr|[+]"filename">; // Redirect output or hush it.
    %remove [!]<"filename">; // Remove a file, (use '!' for force).
    %round <[asymmetric|symmetric] [half] <down|up>|to <even|odd>|random|alternate>;
    %sql <on|off>; // Switch SQL tracing on/off.
    %sql <[!]drop>; // Drop all current Rax tables or, with '!', all Rax tables.
    %sql <"cmd">; // Execute an SQL command.
    %symtab <on|off>; // Trace symtab on/off.
    %symtab [drop]; // Dump or drop the current symbol table.
    %time <on|off|start|lap|stop>; // Set timing on/off or time and interval.
    %tree <on|off>; // Trace parse-trees on/off.
    %warn <"message">; // Emit warning.
    %warn [#]; // Get or set the warning level. 4:a lot .. 1:a little.
         

The list above just serves as a reminder, each meta instruction is discussed in detail in the sections that follow.

%csv

%csv ["separator" [,"escaper" [,"escapees" [,"quote" [,"quote"]]]]];

Used to set (or display) the way strings are represented when reading or writing Character-Separated Value files. For example, the code below writes table S in four different ways:

    {[$,#,$,$]}: S := {["aap", 44, "a\tb", "&\\@\"/"]};
    %csv "/", "&", "<>'", "``", "''"; // Use HTML like escaping.
    <\S:"htmlish.csv"> := S;
    %csv ",", "", "", "\"";           // Use regular .csv escaping.
    <\S:"regular.csv"> := S;
    %csv ";;", "", "@", "\"";         // Use two semicolons and doubling up.
    <\S:"semiat.csv"> := S;
    %csv "\t", "\\", "\t", "E'", "'"; // Use tab and backspace.
    <\S:"tabback.csv"> := S;
         

In principle, any string can be used as a field separator (separator), though traditionally comma, tab, and semicolon are used. The escape sequence escaper can also be any arbitrary string, though backslash, ampersand, and empty string are special. Setting the escaper to backslash, \, causes \t, \n, \v, \f, \\, and \r to have the same meaning as they have in literal strings. Also \x34 would stand for the character with hex value 0x34 and this goes for all number up to 0xFF. Likewise, the ampersand, &, causes translation of &, <, >, and " into &amp;, &lt;, etc. like in HTML. Also &#x34; would stand for the character with hex value 0x34 and this goes for all number up to 0xFF. Note that &apos; is not recognized as it is in XML. Leaving the escaper empty causes escaping by doubling up. Most commonly the quote character is doubled up, though it would work with any escapees requested. The escapees argument can be used to set additional characters that need to be prefixed with the escaper. The quotes arguments can be used to set the opening and closing quote character, typically a single or double quote. Note that if only one quote character is specified, it is used for both opening and closing quote. Usually, the open and close quote will be the same, notable exception would be additional string type specifiers, like E' for opening and ' for closing. An output line for each of the four files from the previous example is given below:

    htmlish.csv:   ``aap''/44/``a  b''/``&amp;\@"/''
    regular.csv:   "aap",44,"a     b","&\@""/"
    semiat.csv:    "aap";;44;;"a   b";;"&\@@""/"
    tabback.csv:   E'aap'  44      E'a\tb' E'&\\@"/'
         

Almost every combination of parameters is allowed. However, Rax will issue a warning for several of the most unusual or incompatible values. The example code above would trigger two warnings:

    warning: Field separator (";;") longer than single character.
    warning: Oddly matching open and close quotes "``" and "''".
         

It is nearly impossible to catch each and every suspect combination, therefore user discretion is advised.

%epsilon

%epsilon [real_number];

Used without a parameter, returns the current epsilon value. Used with a parameter, set a new epsilon value. The parameter must be not negative. The epsilon is used when comparing real numbers - two reals are considered equal, if their absolute difference is less than epsilon.

%digits

%digits [width[,precision]];

Used without parameters, returns the current printing settings for reals: the minimum width and precision. The precision is the number of digits after the decimal point. If the total number of characters in the string representing the real is less than the minimum width, the string will be padded with spaces on the left. Used with parameters, sets the printing settings for reals. The %digits affects the output of the `print and `log commands.

%raxpath

%raxpath [+] ["path"] [+];

Get, set, or modify Rax's user search path. Calling %raxpath; with no arguments will simply return the current user search path as a string, while passing a string argument (i.e., %raxpath "PATHSTRING";) to the directive will set the current user search path. If the path string is preceded by a '+' (i.e., %raxpath +"PATHSTRING";), the given path will appended to the current user search path. Alternatively, if the provided path string is followed by a '+' (i.e., %raxpath "PATHSTRING"+;), the given path will be prepended to the current user search path.

%include

%include [!] [<filename>|"filename"];

Include a Rax file. By default, Rax ignores files included for the second time. Use '!' to force Rax to include the file anyway. This directive will treat a file name wrapped in quotes ("filename") as a user include, and a file name wrapped in angle brackets (<filename>) as a system include. Rax will attempt to resolve system includes as follows:

  1. Search (from left to right), all paths provided by the user. In Rax, these are specified by setting a RAXPATH environment variable before executing the interpreter, or by using the meta command %raxpath, described in the section called “%raxpath”.

  2. Search (from left to right) the default system directories. In Rax, these are: /usr/local/include/rax /usr/lib/rax/<version>/include /usr/include/rax

In the case of a user include, Rax will first check the current directory for the requested file. If a matching file is not found in the current directory, Rax will attempt to resolve the include in the same manner as for system includes.

%logfile

%logfile [off|stderr|stdout|[+]"filename"];

Switch the log output off (off), redirect it to the standard error (stderr), standard output (stdout), or to a file ("filename"). If a + before the file name is used, the log output is appended to the file. Otherwise, the file is overwritten. If used without parameters, the %logfile meta instruction will print the current settings of the log output.

%missing

%missing [<#&$?@^~|> <expr>];

Set substitute values for missing values. Outer joins can cause "holes" in tables. These holes are missing values that cannot be represented in Rax. Variables can be created but left with an undefined value. Ordered sets can be indexed out of bounds. Undefined functions have no value to return. In Rax, these missing values are automatically filled in by default values. For example if a time value is missing, it will be replaced by January first, 2000. This "hole stuffing" happens for example when executing the code below:

    {[$:city, @:date1]}: State := {
      ["Delft",?@?],
      ["Leek",?@?],
      ["Rotterdam",?@?]
    };

    {[$:city, @:date2]}: Area := {
      ["Delft",?@?],
      ["Rotterdam",?@?],
      ["Sneek",?@?]
    };

    `print State =>< Area;
         

A possible output of this code snipped is shown below:

        city   |          date1          |          date2
    -----------|-------------------------|-------------------------
      "Delft"  |2272-01-07T00:41:18.13850|2577-03-14T01:54:00.99620
       "Leek"  |2432-06-25T10:09:26.15160|   2000-01-01T00:00:00
    "Rotterdam"|1938-10-26T03:10:48.94270|2583-10-05T20:25:43.58290
         

Since there is no "Leek" in the city column of the right hand side table, there is no date2 value for the "Leek" row in the resulting table. Therefore the value "start of 2000" is used. Since there is no one-size-fits-all default substitute value, Rax provides the %missing meta instruction to set a more appropriate value. If in the above example the beginning of the year 3000 would have been more appropriate, the last line of the code snippet could have been replaced by:

    %missing @ "3000-01-01";
    `print State =>< Area;
         

The %missing command without any arguments will show a list of all current default substitute values for missing values for all (simple) types. Note that the default replacement value for ordered sets can not be changed, it is fixed at the empty set. The default replacement value for a missing tuple is fixed at the tuple of default replacements values. And, likewise, default replacement value for a function is fixed at the empty function. As noted above, a property of the empty function is that it will return the default missing value when called.

%order

%order set_expr;

Displays the current ordering of a set on the standard output.

%outfile

%outfile [off|stderr|stdout|[+]"filename"];

Switch the print output off (off), redirect it to the standard error (stderr), standard output (stdout), or to a file ("filename"). If a + before the file name is used, the print output is appended to the file. Otherwise, the file is overwritten. If used without parameters, the %outfile meta instruction will print the current settings of the print output.

%remove

%remove [!]"filename";

Remove a file. Use ! to force.

%sql

%sql [on|off];

Turn the SQL trace on or off. When the SQL trace is on, Rax will print the SQL commands it sends to the SQL database to the standard output.

%sql [!]drop;

Drop all tables created in the current session. If you use !, Rax will drop all Rax tables, also from previous or concurrent sessions. Use %sql !drop with extreme care!

%sql "sql_statement";

Execute the SQL statement in the current back end. Note, Rax will not print the results of this command, so it is only useful for things like "CREATE TABLE", "DROP TABLE", "INSERT", etc.

%symtab

%symtab [on|off];

Turn the trace of the symbol table on or off. If the trace is on, Rax will print the contents of the symbol table after each statement.

%symtab drop;

Drop all variables from the symbol table. This operation clears the whole Rax environment, as if you have restarted Rax interpreter.

%time

%time [on|off];

Turn on or off the timing of Rax statements. If timing is on, Rax will measure and print the time each statement took.

%time [start|lap|stop];

Use these instructions to time parts of Rax scripts than single statements. %Time start starts the timer, %time lap prints the current time and restarts the timer and %time stop prints the current time and stops the timer.

%tree

%time [on|off];

Turn the tracing of Rax parse trees on or off. If the tracing is on, Rax will print a parse tree after each statement.

%warn

%warn "msg";

Emit a warning.

%warn [integer];

Used without a parameter, returns the current warning level. Used with a parameter, sets the warning level. The parameter should be an integer between 1 and 4. 4 means: emit all possible warnings. 1 means: only critical ones. The default warning level is 3.