Home Online Manual
Back: LIB commands
Forward: template_lib
FastBack: Procedures
FastForward: Debugging tools
Up: Libraries
Top: Singular Manual
Contents: Table of Contents
Index: Index
About: About this document

3.8.6 Procedures in a library

Here asre hints and requirements on how procedures contained in a library should be implemented. For more on procedures, see Procedures.

  1. Each procedure not meant to be accessible by users should be declared static.
  2. The header of each procedure not declared static must comply with the guidelines described in Procedure definition and Help string. In particular, it must have a help and example section, and assumptions made should be carefully explained. If the assumptions are checked by the procedure on run-time, errors may be reported using the ERROR function.
  3. Names of procedures should not be shorter than 4 characters and should not contain any special characters. In particular, the use of _ in names of procedures is discourraged. If the name of the procedure is composed of more than one word, each new word should start with a capital letter, all other letters should be lower case (e.g. linearMapKernel).
  4. No procedures should be defined within the body of another procedure.
  5. A procedure may print out comments, for instance to explain results or to display intermediate computations. This is often helpful when calling the procedure directly, but it may also cause confusions in cases where the procedure is called by another procedure. The SINGULAR solution to this problem makes use of the function dbprint (see dbprint) and the reserved variables printlevel and voice (see printlevel and see voice). Note that printlevel is a predefined, global variable whose value can be changed by the user, while voice is an internal variable, representing the nesting level of procedures. Accordingly, the value of voice is 1 on the top level, 2 inside the first procedure, and so on. The default value of printlevel is 0, but printlevel can be set to any integer value by the user.

If the procedure Test below is called directly from the top level, then `comment1' is displayed, but not `comment2'. By default, nothing is displayed if Test is called from within any other procedure. However, if printlevel is set to a value k with k>0, then `comment1' (resp. `comment2') is displayed -- provided Test is called from another procedure with nesting level at most k (resp. k-1).

The example part of a procedure behaves in this respect like the procedure on top level (the nesting level is 1, that is, the value of voice is 2). Therefore, due to the command printlevel=1;, `comment1' will be displayed when entering example Test;. However, since printlevel is a global variable, it should be reset to its old value at the end of the example part.

The predefined variable echo controls whether input lines are echoed or not. Its default is 0, but it can be reset by the user. Input is echoed if echo>=voice. At the beginning of the example part, echo is set to the value 2. In this way, the input lines of the example will be displayed when entering example Test;.

      proc Test
      "USAGE:   ...
      EXAMPLE: example Test; shows an example
      {   ...
         int p = printlevel - voice + 3;
         // dbprint prints only if p > 0
      { "EXAMPLE:"; echo = 2;
         int p = printlevel;   //store old value of printlevel
         printlevel = 1;       //assign new value to printlevel
         printlevel = p;       //reset printlevel to old value

SINGULAR functions such as pause or read allow and require interactive user-input. They are, thus, in particular useful for debugging purposes. If such a command is used inside the procedure of a library to be distributed with SINGULAR, the example section of the procedure has to be written with some care -- the procedure should only be called from within the example if the value of printlevel is 0. Otherwise, the automatic build process of SINGULAR will not run through since the examples are carried out during the build process. They are, thus, tested against changes in the code.