This is ../../doc/qdoc.info, produced by makeinfo version 4.8 from ../../doc/qdoc.texi. INFO-DIR-SECTION Programming Languages START-INFO-DIR-ENTRY * Q: (qdoc). The Q programming language and system. END-INFO-DIR-ENTRY The Q Programming Language, Version 7.11, 23 February 2008. Copyright (c) 1992-2008 by Albert Graef. This manual has been published in the series `Musikinformatik und Medientechnik', Bereich Musikinformatik, Musikwissenschaftliches Institut, Johannes Gutenberg-Universitaet Mainz 55099 Mainz Germany ISSN 0941-0309 The Q programming system is distributed under the terms of the GNU General Public License. See the software license accompanying the distribution for details. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the author.  File: qdoc.info, Node: Setting up your Environment, Next: Running Scripts from the Shell, Prev: Command Language, Up: Using Q B.3 Setting up your Environment =============================== There are basically two ways in which you can tailor the Q interpreter to your needs: you can provide your own prelude providing "preloaded" function and variable definitions; and you can use the `qinitrc' and `qexitrc' command files to execute a sequence of interpreter commands when an interactive instance of the interpreter starts up and exits. We describe each of these in turn. The prelude, which has already been discussed in *Note Scripts and Modules::, is just an ordinary Q script which is by default imported in all your scripts. Normally the prelude includes the standard library modules, but you can also provide your own prelude into which you can put any "standard" definitions you want to have available in all your scripts. To customize the prelude, you can either modify the version provided with the standard library (to provide your definitions system-wide), or put your private version somewhere on your library path where the compiler will find it prior to the standard one. In the latter case you can still have your version of the prelude include the standard prelude by renaming the latter using an `as' clause (see *Note Scripts and Modules::). E.g., your `prelude.q' script may contain something like the following (assuming the standard prelude is in `/usr/share/q/lib'): // include the standard prelude as `stdprelude' include "/usr/share/q/lib/prelude.q" as stdprelude; // my own definitions here ... Let us now turn to the interpreter's initialization and termination files. As already mentioned, when the interpreter runs in interactive mode, it automatically sources a startup file (usually named `~/.qinitrc', but you can change this with the `--initrc' option) before entering the command loop. Thus you can put some commands in this file which set up your initial environment, e.g., initialize some variables and load variable definitions from a previous session. A typical startup file may look as follows (lines with initial `//' are comments): // sample init file // common constants //var e = exp 1.0 //var pi = 4.0*atan 1.0 // set your preferred defaults here //path .:~/q:/usr/share/q/lib:/usr/lib/q //fix 2 //cstacksize 1024 //stacksize 1024000 //memsize 4096000 //break on //debug pathnames=y detail=all maxchars=80 prompt "\n\\M>> " // read variable definitions from .q_vars file load Similarly, when the interpreter is exited, it normally sources the `~/.qexitrc' file (or the file named with the `--exitrc' option), which might take care of saving the values of currently defined variables: // sample exit file // autosave variables save // want your daily epigram? //! fortune  File: qdoc.info, Node: Running Scripts from the Shell, Next: Translating Scripts to C, Prev: Setting up your Environment, Up: Using Q B.4 Running Scripts from the Shell ================================== The Q programming system has been designed primarily to facilitate interactive usage. However, with a little additional effort it can also be used to create standalone application programs which are invoked directly from the shell. We discuss how to do this in some detail below. Using "Shebangs" ---------------- For the purposes of this section, your script should be equipped with some "main" function which acts as the entry point to your application. On UNIX systems, you can then use the `#!' ("shebang") notation to specify the Q interpreter as a language processor to be invoked on the script instead of the shell: #!/usr/bin/q -cmain If you include this line (which will be treated as a comment by the Q interpreter) at the top of your main script and give the script execute permissions, most UNIX shells will be able to execute the script just like any other program. You can pass the script's command line parameters as an argument to the `main' function using a shebang line like the following: #!/usr/bin/q -cmain ARGS In any case, your main function should normally use the `exit' function (cf. *Note Process Control::) to explicitly terminate the script with an exit code (unless you specifically want the interpreter to print the result of the `main' function on standard output). Alternatively, you may include the call to `exit' in the shebang line: #!/usr/bin/q -cmain||exit 0 Or your main function can return an integer exit code, in which case you would call it as follows: #!/usr/bin/q -cexit main Note that the "shebang" feature is generally only available on UNIX-like systems. On Windows, you'll have to work with "batch file" wrappers for your script, or you can compile your script to a standalone executable with the `qcwrap' program as described in *Note Translating Scripts to C::. A Simple Example ---------------- For the sake of a concrete example, let us write a little program which takes a number as a command line parameter and prints out all the Fibonacci numbers up to the given index on standard output: #!/usr/bin/q -c main (val (ARGS!1)) fib N = A where (A,B) = fibs N; fibs N = (B,A+B) where (A,B) = fibs (N-1) if N>0; = (0,1) otherwise; main N:Int = do (printf "%s\n".str) $ map fib [0..N] || exit 0; main _ = printf "Usage: %s \n" (ARGS!0) || exit 1 otherwise; Note that in this case we simply passed the Q value of the first command line parameter into the `main' function and have that function do all the remaining processing. We also handle the case that the parameter is missing or does not denote an integer value, and print a little usage message in this case. (At least on UNIX-like systems it is customary to print the real program name in such diagnostics, which is readily available as `ARGS!0', see the second line of `main''s definition.) Also note that we print the numbers in the list `map fib [0..N]' using `printf "%s\n".str' rather than simply `printf "%d\n"', since the numbers get pretty large pretty soon, so the `%d' format (which only supports 32 bit integers on most systems) would not be able to handle them. Save the above script as a file, say, `fibs.q', and make it executable. That is all that is needed, the script should now be ready to go. Run it as, e.g., `./fibs.q 100' to see it in action. Command Line Parameters ----------------------- Most shells only accept a single argument with `#!'. This means that you _must_ pass all compiler and interpreter options in one argument. For instance: #!/usr/bin/q -dcmain ARGS Obviously, this can be cumbersome and it also prevents you from having more than one parameterized option. As a remedy, the Q compiler and interpreter let you pass options by including any number of additional "shebang" lines in the format #! OPTION at the beginning of the main script. This even works if there is no `#!/usr/bin/q' line at the top of the script, but in this case it is a good idea to leave the first script line empty, so that the option line is not mistaken for an ordinary shell shebang line. Note that this is not a shell feature, but an extension provided by the Q programming tools, and hence also works on Windows. Also note that here the `#!' symbol and the option _must_ be separated with whitespace, like so: #!/usr/bin/q #! -ofoo #! -cmain ARGS Using these facilities, fairly elaborate application setups can be handled which require setting the environment for a certain installation directory with additional modules and data files used by the main script. For instance, you can modify the Q path and set a `PROGDIR' variable to the installation directory as follows: #!/usr/bin/q #! -p/usr/share/myprog: #! -cdef PROGDIR="/usr/share/myprog" #! -cmain ARGS By these means, all the necessary setup information is collected at the beginning of your main script where it can be changed easily at installation time. Locating Data Files ------------------- Another common trick is that you can also have the built-in `which' function (see *Note Miscellaneous Functions::) search the application's data files for you. This only requires that you have set up a search path pointing to the application directory containing your data files with `-p' as described above (which you'll probably have to do anyway, so that the script can find its auxiliary imports). For instance: myconfig = which "myconfig.rc"; Because of the way the interpreter does its path searches (see *Note Running Compiler and Interpreter::), this even works if the file is located in some subdirectory of the application directory: myconfig = which "etc/myconfig.rc"; Here is a reasonable "standard" setup that should work for most applications: Install the entire code for your application, including any needed data files and auxiliary modules, in the directory `/usr/share/q/apps/myprog' (assuming that the interpreter lives under `/usr'), where `myprog' denotes the name of your application. Locate data files in your program using `which' as described above (you might want to check the return value of `which' and abort the program with a suitable error message if a data file cannot be found). Using this setup, a shebang line like the following should do the trick (add other command line options as needed): #!/usr/bin/q #! -p/usr/share/q/apps/myprog: #! -cmain ARGS During installation, make sure to edit the `/usr' prefix in the second line with a program like `sed' to reflect the actual installation prefix. Finally, make your main script in `/usr/share/q/apps/myprog' executable and create a symbolic link to it in `/usr/bin' (or any other directory on the system `PATH'). Your script should now be executable from the command line no matter where you actually installed it. Using Env --------- The shell shebangs we have been using so far all required that the absolute path of the interpreter executable be given. However, many UNIX systems also offer the `env' command which executes a given command and also performs a path search. This enables you to write something like: #!/usr/bin/env q Using this method, you do not have to know where the interpreter executable is located; `env' will search for it on the system `PATH' as usual. Passing additional command line parameters can then be done via secondary shebangs as described above. Embedding Q Programs in Shell Scripts ------------------------------------- As of Q 7.8, the interpreter allows you to specify `-' as the name of the main script, to indicate that the script is to be read from standard input. This allows you to employ shell "here" documents in order to embed a Q program in an ordinary shell script. This has the disadvantage that first another shell has to be invoked to execute the embedded program, but in return you get the possibility to do much more elaborate preprocessing of program parameters than a simple shebang can offer. Moreover, it is also possible to include several different Q programs in a single shell script and execute them in sequence or even in a loop, which is great for testing purposes or any other kind of "automation". One word of caution: When you specify a Q script as a "here" document, shebangs in the included script are _not_ processed; they are simply treated as comments. But this is not a problem at all since of course our shell script contains an explicit command invoking the interpreter, so we can easily specify any interpreter options that we might need. For example, here is another version of the Fibonacci program from above, this time written as a shell script. #!/bin/sh # Note that we pass the real script name as ARGS!1 here (and the number # parameter as ARGS!2), so that we can give proper diagnostics. q - "$0" "$1" -c 'main (val (ARGS!2))' <0; = (0,1) otherwise; main N:Int = do (printf "%s\n".str) $ map fib [0..N] || exit 0; main _ = printf "Usage: %s \n" (ARGS!1) || exit 1 otherwise; EOF Encoding Options ---------------- As of Q 7.0, there is one additional compiler option, `--encoding', which, in difference to all other options, is also interpreted while the compiler parses each script file belonging to a program (not just the main script). This option can be used to tell the compiler about the encoding of scripts on a per-file basis, employing a "shebang" line like the following: #! --encoding=UTF-8 This is useful if a script file contains non-ASCII text and may be deployed in environments where you cannot be sure that the encoding of the file matches the system encoding.  File: qdoc.info, Node: Translating Scripts to C, Prev: Running Scripts from the Shell, Up: Using Q B.5 Translating Scripts to C ============================ As of version 5.1, the Q programming system also includes a little utility, `qcwrap', which employs Q's interpreter interface library `libqint' (see *Note Embedding Q in C/C++ Applications::) to turn a Q script into a C program which can be compiled to a binary executable. This will be a _real_ executable for the host operating system, i.e., no `#!' magic is required, and you don't have to distribute the Q source with the executable program, as the binary also contains the entire bytecode of the script. Similar to a self-hosting compiler, the `qcwrap' program is implemented by a Q script which is run on itself to turn it into an executable. Note, however, that `qcwrap' does not really "translate" the source script to C code, i.e., it is _not_ a "real" Q-to-C compiler. It just creates a C wrapper for running the Q interpreter on the script's bytecode. The compiled script is still executed by the Q interpreter (in its `libqint' incarnation), so it will not run any faster or use less memory than the source script. Nevertheless, `qcwrap' is quite useful whenever a Q application has to be shipped in a self-contained binary form. The `qcwrap' program is simply invoked with the filename of the script file to be converted: $ qcwrap myscript.q Be patient, generating the C source for the bytecode of the script takes a while ... If all went well, you should now have a `myscript.c' file. Compile the C program as follows (taking gcc as an example): $ gcc -o myscript myscript.c -lqint Just as with scripts executed via shebangs, the converted script must "do" something when invoked from the command line. The usual way to accomplish this is to include a shebang in your script, as discussed under *Note Running Scripts from the Shell::, above. The `qcwrap' utility interprets the `-c' options in the shebang lines at the beginning of the script and generates corresponding C code for each of them. (Note that _only_ the `-c' options are interpreted. Moreover, only valid Q expressions can be executed this way, other special interpreter commands will _not_ work.) The compiled script still depends on the Q runtime and any other non-Q source files it uses, but it is not a great deal to create a minimal runtime including `libqint' and the required module binaries (i.e., shared libraries), which can be distributed with the compiled script and other support files needed by the script itself. (You could even do without the module binaries when linking everything statically; otherwise you'll just have to make sure that `libqint' and the module binaries are installed in a place where the system finds them.) E.g., if your script uses the standard library and nothing else, a package including your script binary and the `libqint' and `clib' binaries should work, even without any Q installation on the target system.  File: qdoc.info, Node: C Language Interface, Next: Debugging, Prev: Using Q, Up: Top Appendix C C Language Interface ******************************* The Q interpreter provides an interface to the C programming language, which allows you to extend the interpreter with your own collections of "built-ins" in C modules, in order to access functions in C libraries and to take advantage of the higher processing speed of C functions for time-critical applications. We also refer to such C modules interfacing to the Q interpreter as "external modules". On most systems supporting "shared" libraries (a.k.a. "dll"s), external modules are loaded dynamically at runtime, otherwise they have to be linked statically with the interpreter's main program to create a new interpreter executable. The Q interpreter has its own external module support for MS Windows; on UNIX systems, it uses the `libtool' package to implement this functionality. *Note GNU Libtool: (libtool)Top. Conversely, Q scripts can also be executed from C, which allows you to use Q as an embedded macro or programming language or a term rewriting engine in your C/C++ applications. In the following we first discuss Q's C module interface, `libq', in some detail. In the final section of this appendix we then give a brief description of the `libqint' interface which is used to embed Q in C/C++ applications. NOTE: As of version 6.0, Q now also has support for SWIG, the "Simplified Wrapper and Interface Generator", see http://www.swig.org. SWIG considerably simplifies the process of interfacing to existing C and C++ code. This feature still needs to be documented; for the time being, please refer to the README-SWIG file in the distribution for more information. * Menu: * Compiling a Module:: * Writing a Module:: * Linking and Debugging a Module:: * Embedding Q in C/C++ Applications::  File: qdoc.info, Node: Compiling a Module, Next: Writing a Module, Prev: C Language Interface, Up: C Language Interface C.1 Compiling a Module ====================== To provide for a platform-independent way of compiling and linking external modules, the Q programming system includes two tiny additional utilities which take care of the necessary and sometimes messy compilation details: `qcc' and `qld'. `Qcc' is the module compiler. After you have prepared an external module (as explained in *Note Writing a Module::), you run `qcc' to compile your module to a "library", a binary file which can be loaded by or linked into the interpreter. The `qcc' program will compile each given source file and then invoke the linker on all object files to produce the output library. The synopsis of the `qcc' program is as follows: qcc [OPTIONS] [SOURCE-OR-OBJECT-FILE ...] [-- CC-OPTIONS ... [--link LD-OPTIONS...]] As indicated, `qcc' can process both C source and object files, and extra options can be passed on to compiler and linker after the `--' option. All options understood by the `qcc' utility are listed below: `--dry-run, -n' Only print compilation commands, do not actually execute them. `--ext' Print the default output file extension and exit. This is usually `.la' on UNIX systems which denotes a `libtool' library, or `.dll' on Windows. `--help, -h' Print a short help message and exit. `--keep, -k' Do _not_ delete intermediate files (object files and such) produced during the compilation process. `--mingw' Select the mingw compiler driver. Mingw is the native Windows port of the well-known GNU C compiler, gcc. This option is the default for dll compilation on MS Windows. `--msc' Select the MS Visual C compiler driver. Use this if you want to compile your module with the Visual C compiler on Windows. `--output=FILE, -o FILE' Specify the name of the library output file. `--verbose, -v' Echo compilation commands as they are processed. `--version, -V' As with the other Q programming utilities, this option causes version number and copyright information to be displayed, after which the program terminates. The Q module linker, `qld', is implemented as a shell script (thus it is not supported on Windows) which simply invokes `libtool' with the specified `-dlopen' and `-dlpreopen' options to create a new interpreter executable. This is only necessary if your system does not support shared libraries. `Qld' is invoked as follows: qld --help | --version | -o PROGNAME [-dlopen MODULE ...] The `--help' and `--version' options (which may also be abbreviated as `-h' and `-V', respectively) work as usual. All other options are simply passed on to the `libtool' program, thus you can actually use any option recognized in libtool's "link" mode. (*Note GNU Libtool: (libtool)Invoking libtool, for details.) The interpreter executable is written to the specified output file PROGNAME (there is no default for the output file name, so the `-o' option must _always_ be specified). For a closer description of how `qld' is used see *Note Linking and Debugging a Module::, below.  File: qdoc.info, Node: Writing a Module, Next: Linking and Debugging a Module, Prev: Compiling a Module, Up: C Language Interface C.2 Writing a Module ==================== Writing a real external module can be a complicated task, just like any bit of C programming which goes beyond mere exercising. We cannot cover this process in detail here, although we hopefully provide enough information to get you started. You should take a look at the external modules bundled with the Q distribution for more substantial examples. The procedure for making a C function callable from the Q interpreter is fairly straightforward. You first need a Q script (called a "stub") which declares the external C functions you would like to use in your Q program. Next you have to write a C module which implements these functions. Finally, you run `qcc' to translate the C module to a library file which can be loaded by or linked into the interpreter. We discuss each of these steps in turn. As a running example, let us implement list reversal in C. Our C version of this function will be called `creverse'. We first create a Q script `creverse.q', which declares the `creverse' function as `extern': // creverse stub public extern creverse Xs; This tells the interpreter that when the `creverse' function is applied to a single argument, it should invoke the corresponding C function, which is assumed to be found in a shared library named after the stub script. To implement the `creverse' function, we create a C module `cerverse.c'. The Q programming system comes with an interface library called `libq' which provides the necessary operations to inspect Q expressions given as argument values, and to construct new expressions which can be returned as the result of the function invocation. The interface operations are declared in the `libq.h' header file which we include in our C module. The C module must provide the necessary code for being initialized by the interpreter, which is done by putting a `MODULE' "header" at the beginning of the source file. The `MODULE' macro takes one argument, the name of the module. The external functions are then declared with the `FUNCTION' macro, which takes four arguments: the name of the module, the name of the external function (as given in the stub script), the name of the argument count variable, and the name of the argument vector variable. The `FUNCTION' macro is followed by the C block giving the definition of the function. In our example, the `creverse.c' module contains the following C code: #include MODULE(creverse) FUNCTION(creverse,creverse,argc,argv) { /* to be sure, check number of arguments */ if (argc == 1) { /* expr is the data type used by libq to represent Q expressions; x is set to the argument expression, y is initialized to the empty Q list (mknil value) */ expr x = argv[0], y = mknil, hd, tl; /* iscons(x,...) checks that x is a [|] expression and returns its head element and tail list */ while (y && iscons(x, &hd, &tl)) { /* use mkcons to prepend the head element to the list y constructed so far */ expr z = mkcons(hd, y); y = z; x = tl; } if (!y) /* signal error condition */ return __ERROR; else if (isnil(x)) /* well-formed list argument, return the constructed reversal */ return y; else { /* argument was not a well-formed list; throw away the constructed value and indicate failure */ dispose(y); return __FAIL; } } else return __FAIL; } A description of the various macros and functions provided by the `libq' library can be found in the `libq.h' header file. Extern functions are treated very much like the built-in functions provided by the interpreter. The external definition may be thought of as an "external rule" being applied to a Q expression. The definition may either return a Q expression, in which case the rule applies, or `__FAIL', in which case the rule fails, and the interpreter goes on to try other equations supplied by the programmer. As a third alternative, the external definition may also return `__ERROR', which causes evaluation to be aborted with an error message. Also note that built-in functions always take priority. Thus the interpreter first checks for a built-in rule, then for an external definition, and finally considers the equations in the Q script. Therefore it is possible to override an equational function definition with an external function. For instance, we might rename the `creverse' function in the declaration in `creverse.q' to `stdlib::reverse', and to `reverse' in `creverse.c'. This makes our definition override the definition of `reverse' in `stdlib.q'. The latter definition will then only be applied when the external definition fails. (This is what the `clib' module actually does to override the definition of `reverse' as well as other operations in `stdlib.q', see *Note Clib::.) Also note that in order to prevent name clashes between external functions and ordinary C function names, the external function names are stropped with a special prefix (this is taken care of by the `FUNCTION' macro). To call an external function declared with `FUNCTION' from within your C module, you must therefore use the `FUNCALL' macro, which is invoked with the module name, function name and the `argc' and `argv' parameters as arguments. For instance, you would call the `creverse' function defined above as follows: FUNCALL(creverse,creverse,argc,argv) Back to our example. Before we can actually use the above function in the interpreter, we have to run `qcc' to translate the C module to a library object. In our example the process is fairly simple: $ qcc creverse.c If all went well, we now have a `libtool' library named `creverse.la' which is accompanied by some other `libtool'-generated files. (If you are trying this on a Windows system, you will see a dll file named `creverse.dll' instead.) If your system supports shared libraries then you can now simply run the `creverse.q' script with the Q interpreter as usual: $ q creverse.q (If at startup the interpreter complains that it could not load the module then your system probably does not support shared libraries. In this case you will have to create a new interpreter executable which links the module into the interpreter, as explained in *Note Linking and Debugging a Module::.) Let's try it: You probably want to compare the running time of our list reversal function against a Q version of the same operation, which can be defined as follows (include this in the `creverse.q' script): public qreverse Xs; qreverse Xs:List = foldl push [] Xs; The following results were obtained on an Intel PIII-800 PC running Linux: ==> var l = [1..50000] ==> var r = creverse l; stats 0.033 secs, 1 reduction, 50000 cells ==> def r = qreverse l; stats 0.471 secs, 100002 reductions, 50004 cells Not very surprisingly, the C function is indeed much faster, which is due to the extra pattern matching, value extraction and function call overhead of the interpreter. It is also possible to declare a Q _type_ as `extern', and realize the type in C. Such a type must always be abstract (i.e., it must not have any constructor symbols, cf. *Note Types::), and the only way to get a value of such a type is by means of corresponding extern functions. For this purpose, the `libq' library provides the `mkobj' operation, which takes as its argument a pointer to the corresponding C object. For instance, consider an extern type `Bar' and a corresponding construction function `bar' declared as: public extern type Bar; public extern bar I J; // I and J integer We might implement this type as a C struct containing a pair of integers as follows: #include MODULE(ctype) typedef struct { long i, j; } Bar; FUNCTION(ctype,bar,argc,argv) { long i, j; if (argc != 2 || !isint(argv[0], &i) || !isint(argv[1], &j)) return __FAIL; else { Bar *v = malloc(sizeof(Bar)); expr x; if (!v) return __ERROR; v->i = i; v->j = j; return mkobj(type(Bar), v); } } Note that objects of an external type are completely "opaque" as far as the interpreter is concerned (just like file values). In particular, they will be printed using the notation `<>' in the interpreter: ==> bar 1 2 <> The only way to access the contents of an external object is by means of corresponding C functions. For instance, an extern function which converts a `Bar' object to a tuple may be implemented as follows. The declaration: public extern bartuple B; The corresponding definition in the C module: FUNCTION(ctype,bartuple,argc,argv) { Bar *v; if (argc == 1 && isobj(argv[0], type(Bar), (void**)&v)) return mktuplel(2, mkint(v->i), mkint(v->j)); else return __FAIL; } Compile and load the script, using the same procedure as above, and try the following: ==> bartuple (bar 1 2) (1,2) (It is worth noting here that the `isint' and `mkint' functions used above only allow you to access and create integer values fitting into a machine integer. Integers of arbitrary sizes, which are represented as GMP `mpz_t' values, can be dealt with using the `ismpz' and `mkmpz' functions, see the `libq.h' header files for details.) As indicated in our example, external objects are usually allocated dynamically, and will be freed automatically by the interpreter when they are no longer needed. This default behaviour is appropriate in most cases. However, you can also explicitly define a "destructor" function for objects of an external type in your C module as follows: DESTRUCTOR(ctype,Bar,v) { /* we could perform any other necessary cleanup here */ free(v); } If such a destructor function is present, it will be used instead of the interpreter's default action to call `free()' when it disposes a Q expression of the corresponding type. Occasionally, a module will also have some global internal data structures which have to be initialized and/or finalized. For this purpose, you can declare parameterless functions using the `INIT' and `FINI' macros, which will be executed before the script's initialization code, and just before the interpreter exits, respectively. Both macros take the module name as their single argument: INIT(name) { /* any code to be executed at startup goes here */ } FINI(name) { /* any code to be executed at termination goes here */ } Note that the actual order in which the initialization/finalization routines of different modules are executed is unspecified. Furthermore, initialization routines will be executed before any of the script's initialization code (`def' and `undef'). Thus these routines should only be used to perform initializations and cleanup of private data structures of the module. Other initializations can be performed using appropriate `def' statements in the stub script.  File: qdoc.info, Node: Linking and Debugging a Module, Next: Embedding Q in C/C++ Applications, Prev: Writing a Module, Up: C Language Interface C.3 Linking and Debugging a Module ================================== If your system does not support shared libraries, or provides no means to dynamically load a shared library at runtime, you must run the `qld' program to produce a new interpreter executable which links in the required module. For instance, we could link the `creverse' module from the preceding section into the interpreter as follows: $ qld -o myq -dlopen creverse.la (You can also use the `-dlpreopen' option instead of `-dlopen' to force the module to be linked at load time, even if your system supports runtime loading. *Note GNU Libtool: (libtool)Link mode, for more information.) You then run the script as usual, but using the custom interpreter executable built with `qld' instead of the standard `q' program: $ ./myq creverse.q Building such a "preloaded" interpreter is also required when you want to debug a module, in which case the module usually _must_ be linked statically into the interpreter. You can do this as follows (assuming that your C compiler understands the `-g' debugging flag): $ qcc creverse.c -- -g $ qld -o myq -static -g -dlopen creverse.la If you now let your debugger execute `myq creverse.q', you should be able to debug `creverse.c' at the source level.  File: qdoc.info, Node: Embedding Q in C/C++ Applications, Prev: Linking and Debugging a Module, Up: C Language Interface C.4 Embedding Q in C/C++ Applications ===================================== To call the Q interpreter from a C/C++ application, your program must link to the Q interpreter interface library, `libqint'. This library provides a number of operations with which you can load a script into the interpreter and then evaluate Q expressions. A closer description of the operations can be found in the `qint.h' header file of the library. Before you can evaluate anything, you have to invoke the `qexecv()' or `qexecl()' routine to load a script or byte code file into the interpreter. These two routines work pretty much like the `run' command in the interpreter. The `qexecv()' function takes the script parameters as a vector of `char*' values, while `qexecl()' allows you to pass the parameters directly as `char*' arguments; otherwise the two functions operate in exactly the same way. As with the interpreter's `run' command, only one script can be loaded at any one time; if a new script is loaded with `qexecv()' or `qexecl()', it replaces an existing one. Two additional routines are provided, `qexecvx()' and `qexeclx()', which work exactly like `qexecv()' and `qexecl()', respectively, but take the script (or byte code file) itself as a binary string in the first argument. This allows you to specify the script to be executed directly in your application, without relying on some external script file. Once a script has been loaded, you can repeatedly evaluate expressions with the `qeval()' routine, which takes the expression to be evaluated as a string argument. The contents of the string must be in Q expression syntax. The result is returned as a malloc'd string which must be freed by the caller; it contains the unparsed evaluated expression in the same format as it would be printed by the interpreter. Here is a complete C example which employs the `qeval()' routine to implement a simple read-eval-print loop. The name of the script to be loaded and its parameters are taken from the command line of the program. /* poor man's Q interpreter */ #include #include #include #include #define BUFSIZE 1024 int main(int argc, char **argv) { int status; char s[BUFSIZE], *t; /* First load the script with args as given on the command line. */ if ((status = qexecv(argv[1], argc-1, argv+1))) { char msg[1000]; sprintf(msg, qstrerror(status), argv[1]); fprintf(stderr, "Error starting interpreter: %d: %s\n", status, msg); exit(1); } /* The read/eval/print loop. */ printf("%s loaded, ready to rumble!\n", argv[1]?argv[1]:"empty script"); printf("\nin> "); fflush(stdout); while (fgets(s, BUFSIZE, stdin)) { int l = strlen(s); if (l > 0 && s[l-1] == '\n') s[l-1] = 0; t = qeval(s, &status); if (status) printf("err> %d: %s\n", status, qstrerror(status)); if (t) { printf("out> %s\n", t); free(t); } printf("\nin> "); fflush(stdout); } printf("\n"); exit(0); } On Linux and most other Unix-like systems you should be able to compile and then run this program as follows (assuming that the C source is in a file named `myq.c'): $ gcc -o myq myq.c -lqint $ ./myq /usr/share/q/examples/fac.q (On some systems it might be necessary to add more linker options to resolve additional dependencies. E.g., under Cygwin you'll need something like `-lqint -liconv -lgmp -lq'.) A sample session with the program is shown below. /usr/share/q/examples/basics.q loaded, ready to rumble! in> 1+ err> 17: Syntax error in> 1+1 out> 2 in> fact 12 out> 479001600 in> foldl (*) 1 [1..12] out> 479001600 Obviously, the `qeval()' function is of limited usefulness if your application needs to construct the input expression from a C data structure, and/or inspect the evaluated result, e.g., to translate the result back to another C structure. For such applications `libqint' provides the `qevalx()' function which receives a binary expression object (of type `qexpr') as input and returns the evaluated expression as another `qexpr' object. Operations are provided to construct and inspect `qexpr' objects which are analogous to the corresponding `libq' routines. Here is a simple example which constructs and evaluates a `qexpr' object using `qevalx()' and then checks the result value. It also illustrates the use of `qexeclx()' to load an "inlined" script into the interpreter. #include #include #include #include int main(int argc, char **argv) { int status; char *t; qexpr x; /* Our little hello world script. */ char *script = "hello = writes \"Hello, world!\\n\";"; /* Load the script into the interpreter, also pass arguments (the first argument is always the (fake) script name which becomes ARGS!0). */ qexeclx(script, strlen(script), 2, "Hello!", "Hello world example."); /* Just for fun, print the arguments passed to the script. (We don't do any error checking, since there's not much that can go wrong here.) */ t = qeval("ARGS", &status); printf("ARGS ==> %s\n", t); free(t); /* Evaluate the `hello' function from the script and print the result. */ t = qeval("hello", &status); printf("hello ==> %s\n", t); free(t); /* Here's how to employ qevalx() to evaluate binary expression objects instead of their string representations. We construct the function application `writes "Hello, world #2!\n"' and evaluate it. Note that the string value *must* be allocated dynamically since it is taken over by the interpreter (and freed automatically together with the rest of the input expression when qevalx() is finished with it). */ x = qevalx(qmkapp(qmksym(qsym(writes)), qmkstr(strdup("Hello, world #2!\n"))), &status); /* Check the result. */ if (status) printf("evalx() returned error code %d: %s\n", status, qstrerror(status)); else if (qisvoid(x)) printf("writes was executed successfully\n"); else { t = qprint(x, &status); printf("writes returned some unexpected value: %s\n", t); free(t); } /* Get rid of the result. */ qdispose(x); exit(0); } The program produces the following output: ARGS ==> ["Hello!","Hello world example."] Hello, world! hello ==> () Hello, world #2! writes was executed successfully Using the `qdef()' function, it is also possible to set variables in the interpreter. You can either change existing variables of the script or create new variables in the global scope. Here is a simple example: #include #include #include #include int main(int argc, char **argv) { int status; char *script = "def TEST = 99;"; qexeclx(script, strlen(script), 0); /* change the value of an existing variable */ printf("TEST ==> %s\n", qeval("TEST", &status)); status = qdef("TEST", qevalx(qparse("TEST+2", &status), &status)); printf("TEST ==> %s\n", qeval("TEST", &status)); /* create a new variable in the global scope */ printf("MYTEST ==> %s\n", qeval("MYTEST", &status)); status = qdef("MYTEST", qevalx(qparse("TEST+2", &status), &status)); printf("MYTEST ==> %s\n", qeval("MYTEST", &status)); exit(0); } The program produces the following output: TEST ==> 99 TEST ==> 101 MYTEST ==> MYTEST MYTEST ==> 103  File: qdoc.info, Node: Debugging, Next: Running Scripts in Emacs, Prev: C Language Interface, Up: Top Appendix D Debugging ******************** The Q interpreter includes a simple symbolic debugger which can be used to trace the reductions performed during an expression evaluation. In order to use this tool successfully, you should be familiar with the way the Q interpreter evaluates expressions; see, in particular, *Note Performing Reductions on a Stack::. The debugger is subject to activation when one of the following conditions arises: * The interpreter has been invoked with the `-d' option, or the user has activated debugging using the `debug on' command (see *Note Using Q::). * The interpreter executes the built-in `break' function on the right-hand side of a rule (see *Note Exception Handling::). * The user interrupts an evaluation with `Ctl-C' (see *Note Error Handling::). * A qualifying condition of a rule does not not evaluate to a truth value (cf. *Note Conditional Rules::). * An exception is raised by the running script, either by using `throw' or through a trapped signal, see *Note Exception Handling::. * A breakpoint has been set on a function symbol (using the `break' command, see below), and the interpreter is about to invoke a user-defined rule for evaluating an application of that function. In the first case, the debugger is always invoked as soon as an evaluation is started. In the remaining cases the debugger is _only_ invoked if the `break' flag is `on'. The `break' flag is an internal flag of the interpreter which can be controlled with the `break' command, cf. *Note Command Language::. If `break' is `off' then all kinds of exceptions normally cause evaluation to be aborted immediately with an appropriate error message, and invocations of the `break' function are simply ignored. (The `break' flag is `off' by default, so you must set it to `on' before you can catch any break points with the debugger.) Also note that if there is a pending `catch' (see *Note Exception Handling::) then the debugger will only be invoked for a call to the `break' function, if the `break' flag is `on'. The `break' command can also be invoked with a list of function symbols as arguments, which sets breakpoints on the given symbols. When a breakpoint has been set on a function symbol, the debugger will be invoked, just as if the `break' function had been called, whenever the interpreter is about to reduce an application of that function employing a user-defined rule. When invoked without arguments, `break' prints the current status of the `break' flag and a list of currently active breakpoints. You can use the `clear' command to delete a breakpoint on the given function symbols (or all breakpoints if no argument is specified). Moreover, there also is a `tbreak' command which sets temporary breakpoints on the given symbols which will be removed automatically once they are hit. (In the breakpoint list produced with `break', such temporary breakpoints are signaled by a trailing `*'.) All these commands can be used either from the debugger or on the interpreter's command line. When active, the debugger prints each reduction by a built-in or user-defined rule performed during evaluation in the following format: ** LEFT-HAND-SIDE ==> RIGHT-HAND-SIDE "Tail reductions" (see *Note Tail Recursion::) are signaled by a leading `++' instead of `**', global and local variable bindings (cf. *Note Free Variables::, and *Note Local Variables::) with a leading `--'. Whenever a new rule is activated, and also after processing a qualifier, the debugger interrupts the evaluation and displays the current rule together with the corresponding source file name and line number in the following format: LEVEL> SOURCE-FILE, line LINE-NUMBER: LEFT-HAND-SIDE ==> RIGHT-HAND-SIDE QUALIFIER (To remove clutter, the debugger only prints one qualifier at a time, namely the condition or local definition which is currently being processed.) The level number printed in front of the rule indicates the position of the printed rule on the reduction stack (the topmost rule is at level 0). At the `:' prompt, you may then enter one of the following commands: `?, help' Print a short help message which lists the debugger commands. `help options' Print a help message which briefly describes debugger options that can be set with the `.' command. `break [on|off|FUNCTION ...], tbreak FUNCTION ..., clear [FUNCTION ...]' Change the `break' flag and list, set or remove breakpoints (see above). `. [ARG ...]' Reprint the current rule (if invoked without arguments), or set debugger options. `l [OFFS] [LINES]' List source lines of the current rule. You may specify the number of lines to be listed (the default is 1), as well as an offset taken relative to the line number of the current rule (this must be a signed number, with the default being `+0'). `p [ARG]' Print stacked rules. `m' Print memory usage. `v' List the local variables of the current rule. `u [ARG], d [ARG]' Move up or down on the rule stack. `t, b' Move to the top or bottom of the stack. `' Step into the current reduction. `n' Next: step over the current reduction. `c' Continue: resume evaluation. `h' Halt: abort evaluation. `q, ' Quit: exit from the interpreter. All other input is interpreted as an expression to be evaluated in the context of the current rule, with local variables bound to their current values. This lets you inspect the values of local variables and perform arbitrary calculations with these values. Note that debugging mode is suspended while the expression is evaluated, so only the result (or an error message) will be printed. As on the interpreter's main command line, you can use `? EXPRESSION' to escape an expression which looks like a debugger command. When evaluating an expression, the result is printed with custom pretty-printing (cf. *Note Views::) enabled, just like when evaluating an expression on the interpreter's command line. All other expressions are printed in the debugger with custom pretty-printing disabled, so that you can see exactly the "raw" data processed by the interpreter. Command line editing works in the debugger as usual. Note, however, that the debugger maintains its own command history which is _not_ remembered across different invocations of the interpreter. With the debugger being activated, you can simply keep on hitting the carriage return key to go through an evaluation step by step. The `n' ("next" a.k.a. "step over") command causes the interpreter to finish the current rule and also step over any tail reductions; it then leaves you in the context from which the current rule was invoked (which might be the interpreter's command prompt, if you just stepped over the toplevel rule). The `p' command can be used to print the stack of active rules. The optional integer argument of this command sets the maximum number of stacked rules to print. The `u', `d', `t' and `b' commands let you move around on the reduction stack; `u' and `d' move up and down the given number of levels (default: 1), while `t' and `b' take you to the top (i.e., topmost rule) and bottom (active rule) of the stack, respectively. The `l' command lists the source of the current rule. By default, only the line at which the rule starts is printed. You can specify the number of lines to be listed; e.g., `l 5' causes five lines to be printed. To have some context of the rule printed, you can also specify a signed integer denoting the relative offset from the source line; e.g., `l -2 5' causes five lines to be printed, starting two lines above the current rule. (Both the line count and the offset are remembered across different invocations of the `l' command.) The `v' command lists the local (i.e., "bound") variables of a rule. This comprises the variables which are bound by the left-hand side or have already been bound in a `where' clause while the rule is being processed. (Note that in the current implementation only those variables will be listed whose values are actually _used_ somewhere on the right-hand side or in the qualifiers of the rule.) At any point, you can use the `c', `h' and `q' commands to continue evaluation without the debugger, abort an evaluation and return to the interpreter's prompt, or quit the interpreter, respectively. The `m' command prints the current memory usage, i.e., the total number of allocated stack and heap expression cells, along with the corresponding numbers of cells which are actually in use. For the heap, it also prints the number of expression cells in the free list, i.e., temporarily unused expression cells below the current heap top. If limits are set on the maximum number of stack and heap cells, these figures are printed as well. The current rule can be reprinted using the `.' command. Because Q expressions can get very large, the debugger usually only prints expression "outlines"; otherwise you could end up scrolling through pages and pages of printouts for each reduction and rule. The `.' command accepts some options which allow you to set the level of detail you want to see in the printed reductions and rules; these options will be remembered during an interpreter session. The options are generally specified in the format `OPTION=VALUE' and must not contain any whitespace (blanks or tabs). Multiple options can be specified with a single `.' command, separating different options with whitespace. Option values can also be specified in the same format on the interpreter's command line, using the `debug' command (see *Note Command Language::), or with the interpreter's `--debug-options' option (see *Note Running Compiler and Interpreter::). The following options are provided: `. detail=N' Set the maximum depth (a.k.a. levels of nested parentheses, 2 by default) up to which expressions are displayed. The debugger will omit all subexpressions below the current level. Level 1 (`. detail=1') means to just print the toplevel expression, level 2 adds the first-level parentheses, level 3 all second-level parentheses, etc. All omitted parts in the expression outline will be represented using an ellipsis `...'. If you set the level to zero, or specify the symbolic value `all', all expressions will be printed to arbitrary depth. `. maxitems=N' Set the maximum number of elements to print for each list or tuple. The default is 3. A value of `0' or `all' causes all list and tuple elements to be printed. `. maxchars=N' Set the maximum number of characters to print for each string value. The default is 33. A value of `0' or `all' causes all characters to be printed. `. maxstack=N' Set the number of stack levels to print with the `p' command. The default is 6. A value of `0' or `all' causes the entire rule stack to be printed. This value is also modified when an argument is specified with `p'. `. pathnames=y|n' Print full pathnames of scripts (`y' = yes, `n' = no). The default value of this option is `n', i.e., only the basenames of scripts are printed. Change this value to `y' if you want to see the complete path of a script file when a rule is printed. `. options' Print the current settings. This option does not modify any settings, but simply prints all current option values on a single line. Let us now take a look at a typical session with the debugger. For an example, we take the definition of the `fac' function from *Note Writing a Script::: fac N = N*fac(N-1) if N>0; = 1 otherwise; The commented session with the debugger follows. ==> fac 1 evaluate `fac 1' 0> fac.q, line 1: fac 1 ==> 1*fac (1-1) if 1>0 try the first rule ... (type ? for help) : ** 1>0 ==> true evaluate the qualifier 0> fac.q, line 1: fac 1 ==> 1*fac (1-1) : ** 1-1 ==> 0 evaluate `1-1' argument 1> fac.q, line 1: fac 0 ==> 0*fac (0-1) if 0>0 try the first rule on `fac 0' : p stack size: 2 now two rules are on the stack 0> fac.q, line 1: fac 1 ==> 1*fac (1-1) 1> fac.q, line 1: fac 0 ==> 0*fac (0-1) if 0>0 : ** 0>0 ==> false qualifier fails 1> fac.q, line 2: fac 0 ==> 1 try the second rule ... : ** fac 0 ==> 1 bingo! reduce `fac 0' to `1' 0> fac.q, line 1: fac 1 ==> 1*fac (1-1) return to the suspended rule : ** 1*1 ==> 1 ** fac 1 ==> 1 final reduction ... 1 ... and the result printed by the interpreter ==>  File: qdoc.info, Node: Running Scripts in Emacs, Next: References, Prev: Debugging, Up: Top Appendix E Running Scripts in Emacs *********************************** The Q programming system also includes an Emacs Lisp program which lets you edit and run Q scripts in GNU Emacs or XEmacs. The program implements two major modes `q-mode' and `q-eval-mode' for Q source scripts and Q interpreter processes, respectively. The following discussion is rather terse and incomplete, but if you know Emacs then it should provide enough information to get you started. To install Q mode on your system, copy the file `q-mode.el' from `PREFIX/share/q/etc' (where PREFIX is the installation prefix you selected at installation time) to your Emacs `site-lisp' directory and paste the following lines into your Emacs startup file: (require 'q-mode) (setq auto-mode-alist (cons '("\\.q$" . q-mode) auto-mode-alist)) If you want syntactic fontification (`font-lock' mode), you also have to add the following lines: (add-hook 'q-mode-hook 'turn-on-font-lock) (add-hook 'q-eval-mode-hook 'turn-on-font-lock) More installation options are described at the beginning of the `q-mode.el' file. Once Q mode is installed and loaded, you can also customize it in Emacs; see the description of the `Customize' option below. Q mode is used for editing Q scripts. With the startup configuration described above, it is invoked automatically on all files having the `.q' extension. Q mode provides auto-indentation and filling, as well as syntactic fontification of keywords, strings, comments, and variable and type symbols using the `font-lock' mode which is part of the Emacs library. The indentation rules for Q scripts are somewhat unusual for a programming language, so we briefly summarize them here: * Declarations start in the first column, with continuation lines being indented by a certain (configurable) amount. Moreover, initial `=', `|' and `;' symbols are all aligned in data type declarations. * Inside rules, an initial `=' is aligned with the most recent equation. The default amount of `=' indentation can be configured. Auto indentation is also provided for the right-hand side and qualifier part of a rule. Qualifiers (introduced with `if', `otherwise' and `where') use an extra amount of indentation which can be configured as well. * In addition, expressions are indented according to their parenthetical structure, as in Lisp mode. As usual, indentation of a line is performed with the `Tab' key. There also is a menu command for indenting a selected region. Moreover, you can use `Esc-Tab' at the end of a line to move the cursor to the indentation position for the `=' symbol in an equation, and certain "electric" delimiter symbols like `=' will automatically perform indentation when typed at the beginning of a line. The `q-run-script' command (usually bound to `C-c C-c') compiles and runs the script in the current buffer; you can also use the `run-q' command (which has no keybinding by default) to invoke the interpreter without a script. Both commands create a new buffer named `*q-eval*' (if that buffer does not already exist) in which it runs the interpreter. The `*q-eval*' buffer is also used to display error messages from the compiler, if any. The interpreter is used in this buffer as usual, with the only difference that input and output is done through the buffer. Since this is an ordinary Emacs buffer, you can also save the buffer to some file to obtain a transcript of your interpreter session. The `*q-eval*' buffer uses `q-eval-mode' as its major mode which is based on `comint-mode', a generic command language interpreter mode which is also part of the Emacs library. In addition to the facilities provided by Comint mode (such as cycling through a history of recent commands), Q-Eval mode provides fontification of some special items (strings, comments and source file references printed by the interpreter), as well as some commands for locating the source lines referenced by compiler or debugger messages from the interpreter. In particular, pressing the return key (or the middle mouse button, when running under X-Windows) on such a message visits the corresponding source file with the cursor positioned at the line indicated by the message. You can also scan through the messages found in the buffer with the following commands: `q-next-msg (C-c C-n), q-prev-msg (C-c C-p)' Show the next/previous compiler/debugger message and visit the corresponding source line in another window. An optional prefix argument may be used to specify the number of messages to advance. `q-first-msg (C-c C-a), q-last-msg (C-c C-e)' Show the first/last line in a contiguous sequence of compiler/debugger messages above/below the current message and visit the corresponding source line. The above commands can be invoked in both Q and Q-Eval mode, and they are also accessible from the corresponding Q and Q-Eval menus in the menubar (or the buffer popup menu obtained with the right mouse button). Some other commands are provided as well, but you can easily find out about these using the online help facilities of Emacs. In particular, you should try the `describe-mode' (`C-h m') command which describes the currently active mode. Another useful command is `describe-key' (`C-h k'). You can also invoke the online version of this manual with `C-c C-h'. The `Customize' option in the `Q'/`Q-Eval' menus can be used to set various options of the interpreter in the Q customization group, which belongs to Emacs' "Programming Languages" group. In particular, you should enable the `q-gnuclient' option in the "Options" subgroup which synchronizes Emacs with the Q interpreter; e.g., this option allows you to edit files and read online help using the interpreter's `edit' and `help' commands directly in Emacs. (For this to work, you must have the `gnuserv' package, which can be obtained from the usual elisp archives; see the `q-mode.el' file for details.)  File: qdoc.info, Node: References, Next: Index, Prev: Running Scripts in Emacs, Up: Top References ********** H. Abelson and G.J. Sussman. `Structure and Interpretation of Computer Programs.' Second edition. MIT Press, Cambridge, Mass., 1996. Adobe Systems Incorporated. `PostScript Language Reference Manual. Second Edition.' Addison-Wesley, Reading, Mass., 1990. R. Bird and P. Wadler. `Introduction to Functional Programming.' Prentice Hall, New York, 1988. N. Dershowitz and J.-P. Jouannaud. Rewrite Systems. In J. van Leeuwen, editor, `Handbook of Theoretical Computer Science. B: Formal Models and Semantics,' pages 243-320. North-Holland, Amsterdam, 1990. A. Graef. Left-to-right tree pattern matching. In `Proceedings Rewriting Techniques and Applications '91,' LNCS 488, pages 323-334. Springer, Berlin, 1991. M.C. Henson. `Elements of Functional Languages.' Blackwell Scientific Publications, Oxford, 1987. R. Hubbard. `"Q+Q": Q Rational Number Library.' 2006. (Available in pdf format in the "Q+Q" package on http://q-lang.sourceforge.net.) M.J. O'Donnell. `Equational Logic as a Programming Language.' MIT Press, Cambridge, Mass., 1985. G.L. Steele, Jr. and G.J. Sussman. Scheme: An interpreter for the extended lambda calculus. Memo 349, MIT Artificial Intelligence Laboratory, 1975. P. Wadler. Views: A way for pattern matching to cohabit with data abstraction. In `Proc. Principles of Programming Languages,' ACM, 1987.  File: qdoc.info, Node: Index, Prev: References, Up: Top Index ***** [index] * Menu: * .: Command Language. (line 357) * .qexitrc: Setting up your Environment. (line 61) * .qinitrc: Setting up your Environment. (line 32) * @: Rule Priorities. (line 29) * \": Strings. (line 15) * \0: Constants and Variables. (line 20) * \\: Strings. (line 15) * \b: Strings. (line 15) * \f: Strings. (line 15) * \n: Strings. (line 15) * \r: Strings. (line 15) * \t: Strings. (line 15) * _ <1>: Command Language. (line 93) * _: Equations. (line 98) * _FAIL_: Exception Handling. (line 25) * abs <1>: Complex Numbers. (line 23) * abs: Standard Functions. (line 10) * abstract data type (ADT): Using Type Guards. (line 51) * abstract type <1>: Sub- and Supertypes. (line 15) * abstract type: Type Guards. (line 53) * accept: Sockets. (line 95) * access: File and Directory Functions. (line 10) * acos: Mathematical Functions. (line 15) * acosh: Mathematical Functions. (line 24) * active: Thread Creation and Management. (line 55) * active rules: Performing Reductions on a Stack. (line 43) * add_history: Readline Interface. (line 11) * aliasing: Cross-Checking of Declarations and Aliases. (line 26) * all: Standard Functions. (line 13) * and: Logical and Bit Operators. (line 6) * anonymous variable <1>: Command Language. (line 93) * anonymous variable: Equations. (line 98) * any: Standard Functions. (line 17) * append <1>: C Replacements for Common Standard Library Functions. (line 9) * append <2>: Arrays. (line 59) * append: Standard Functions. (line 21) * applicable equation: Normal Forms and Reduction Strategy. (line 11) * application: Applications. (line 6) * applicative order evaluation: Normal Forms and Reduction Strategy. (line 121) * arc: Path Construction. (line 42) * arct: Path Construction. (line 52) * arg: Complex Numbers. (line 23) * ARGS: Command Language. (line 81) * argument: Applications. (line 6) * argument list: Declaration Syntax. (line 101) * arithmetic operators: Arithmetic Operators. (line 6) * arity: Declaration Syntax. (line 101) * array: Arrays. (line 11) * Array: Arrays. (line 6) * array.q: Arrays. (line 6) * array2: Arrays. (line 14) * arrays: Arrays. (line 6) * as: Unqualified Imports. (line 87) * asctime: Time Functions. (line 37) * asin: Mathematical Functions. (line 15) * asinh: Mathematical Functions. (line 24) * assert: Diagnostics and Error Messages. (line 6) * assert.q: Diagnostics and Error Messages. (line 6) * assertions: Diagnostics and Error Messages. (line 6) * associative arrays: Hashed Dictionaries. (line 6) * atan: Numeric Functions. (line 22) * atan2: Numeric Functions. (line 25) * atanh: Mathematical Functions. (line 24) * AVL tree: Sub- and Supertypes. (line 33) * await: Conditions. (line 18) * bag: Bags. (line 6) * Bag: Bags. (line 6) * bag.q: Bags. (line 6) * bags: Bags. (line 6) * basic expressions: Expressions. (line 15) * batch mode: Running Compiler and Interpreter. (line 334) * bcat: Byte Strings. (line 51) * bcmp: Byte Strings. (line 51) * bfloat: Byte Strings. (line 51) * binary search tree: Using Type Guards. (line 6) * bind: Sockets. (line 84) * binding clause: Conditionals and Comprehensions. (line 173) * bindtextdomain: Internationalization. (line 113) * bint: Byte Strings. (line 51) * bit operations <1>: Arithmetic Functions. (line 6) * bit operations: Logical and Bit Operators. (line 69) * bit shift functions: Arithmetic Functions. (line 6) * bitsets: Arithmetic Functions. (line 50) * bitwise logical operators: Logical and Bit Operators. (line 69) * Bool: Built-In Types. (line 38) * bound variable <1>: Free Variables. (line 6) * bound variable: Equations. (line 28) * bounded_semaphore: Semaphores. (line 32) * bounding box (EPSF): DSC and EPSF Comments. (line 33) * bread: Low-Level I/O. (line 36) * break <1>: Command Language. (line 238) * break: Exception Handling. (line 19) * breakpoint: Exception Handling. (line 46) * broadcast: Conditions. (line 18) * bsize: Byte Strings. (line 51) * bstr: Byte Strings. (line 51) * bsub: Byte Strings. (line 51) * built-in constants: Constants and Variables. (line 27) * built-in equations: Normal Forms and Reduction Strategy. (line 45) * built-in special forms: Built-In Special Forms. (line 6) * built-in types: Built-In Types. (line 6) * bwrite: Low-Level I/O. (line 36) * byte: Byte Strings. (line 51) * byte order: Byte Strings. (line 174) * bytecode: Using Q. (line 15) * bytecode file: Scripts and Modules. (line 12) * bytes: Byte Strings. (line 51) * bytestr: Byte Strings. (line 24) * ByteStr: Byte Strings. (line 12) * C interface: C Language Interface. (line 6) * C programming language: C Language Interface. (line 6) * c_cc ATTR;: Terminal Operations. (line 13) * c_cflag: Terminal Operations. (line 13) * c_iflag: Terminal Operations. (line 13) * c_ispeed: Terminal Operations. (line 13) * c_lflag: Terminal Operations. (line 13) * c_oflag: Terminal Operations. (line 13) * c_ospeed: Terminal Operations. (line 13) * call by name: Special Forms. (line 6) * call by need: Memoization and Lazy Evaluation. (line 62) * call by pattern: Special Constructors and Streams. (line 106) * call by value: Special Forms. (line 6) * cancel: Thread Creation and Management. (line 38) * canceled: Thread Creation and Management. (line 55) * case: Conditionals and Comprehensions. (line 83) * casefun: Conditionals and Comprehensions. (line 106) * cat <1>: C Replacements for Common Standard Library Functions. (line 9) * cat: Standard Functions. (line 24) * catch: Exception Handling. (line 28) * cd: Command Language. (line 295) * ceil: Mathematical Functions. (line 12) * Char: Built-In Types. (line 6) * character conversion: Conversion Functions. (line 61) * character sequences <1>: Constants and Variables. (line 20) * character sequences: Strings. (line 6) * charpath: Path Construction. (line 58) * chars <1>: C Replacements for Common Standard Library Functions. (line 9) * chars: String Functions. (line 13) * chdir <1>: Command Language. (line 295) * chdir: File and Directory Functions. (line 10) * chmod: File and Directory Functions. (line 10) * chown: File and Directory Functions. (line 10) * chr: Conversion Functions. (line 36) * cis: Complex Numbers. (line 35) * clear: Command Language. (line 267) * clear break: Command Language. (line 272) * clear profile: Command Language. (line 276) * clib.q <1>: Clib. (line 6) * clib.q: The Standard Library. (line 144) * clip: Clipping. (line 10) * clippath: Path Construction. (line 16) * clipping path: Overview of Graphics Operations. (line 53) * clock: Time Functions. (line 81) * close: Low-Level I/O. (line 11) * closepath: Path Construction. (line 13) * closesocket: Sockets. (line 77) * closing a file: File I/O. (line 33) * closing a path: Overview of Graphics Operations. (line 31) * Color: Graphics State. (line 70) * combinatorial calculus: Equations. (line 249) * command: Pipes. (line 6) * command language: Command Language. (line 6) * command line arguments: Running Compiler and Interpreter. (line 16) * commands: Command Language. (line 120) * comment: Whitespace and Comments. (line 7) * completion_matches: Command Language. (line 426) * complex: Complex Numbers. (line 6) * Complex: Complex Numbers. (line 6) * complex numbers (complex.q): Complex Numbers. (line 6) * complex.q <1>: Complex Numbers. (line 6) * complex.q: The Standard Library. (line 137) * compound expressions: Expressions. (line 15) * concatenation: String List and Tuple Operators. (line 6) * concrete type: Sub- and Supertypes. (line 15) * cond: Conditionals and Comprehensions. (line 64) * cond.q: Conditionals and Comprehensions. (line 6) * condfun: Conditionals and Comprehensions. (line 106) * condition: Conditions. (line 18) * Condition: Conditions. (line 18) * condition <1>: Conditions. (line 6) * condition: Equations. (line 42) * conditional clause: Conditionals and Comprehensions. (line 187) * conditional equation: Equations. (line 42) * conditional expression: Basic Concepts. (line 6) * conj: Complex Numbers. (line 32) * connect: Sockets. (line 104) * cons: Standard Functions. (line 27) * const: Declaration Syntax. (line 70) * constant symbol: Declaration Syntax. (line 70) * constructor: Declaration Syntax. (line 70) * constructors: Equations. (line 135) * container data structures: Standard Types. (line 12) * container data structures, equality: Standard Types. (line 21) * container data structures, size operator: Standard Types. (line 21) * container data structures, view: Standard Types. (line 29) * conversion functions: Conversion Functions. (line 6) * coordinate system: Coordinate System. (line 6) * copies: Miscellaneous Operations. (line 19) * copying: Command Language. (line 136) * copypage: Miscellaneous Operations. (line 10) * cos: Numeric Functions. (line 19) * cosh: Mathematical Functions. (line 21) * creverse: Writing a Module. (line 20) * critical section: Mutexes. (line 26) * crypt: System Information. (line 84) * cst: Standard Functions. (line 30) * cstacksize: Command Language. (line 189) * ctermid: Low-Level I/O. (line 58) * ctime: Time Functions. (line 37) * curry: Standard Functions. (line 33) * curry3: Standard Functions. (line 37) * currying: Applications. (line 35) * curveto: Path Construction. (line 34) * cycle: Streams. (line 53) * dash pattern: Graphics State. (line 77) * data structure: Using Type Guards. (line 6) * daylight: Time Functions. (line 37) * dcgettext: Internationalization. (line 113) * dcngettext: Internationalization. (line 113) * debug: Command Language. (line 231) * debugger: Debugging. (line 6) * debugger commands: Debugging. (line 86) * debugger session: Debugging. (line 264) * debugger, activation of: Debugging. (line 12) * dec: Command Language. (line 166) * declarations: Declarations. (line 6) * declarations, consistency: Cross-Checking of Declarations and Aliases. (line 6) * def: Command Language. (line 36) * default case: Equations. (line 42) * default declaration: Declaration Syntax. (line 114) * deferred value: Basic Concepts. (line 33) * delete <1>: Dictionaries. (line 59) * delete: Sets. (line 50) * delimiters, special (lexical syntax): Operator Symbols. (line 56) * den: Rational Numbers. (line 24) * destructor function: Writing a Module. (line 233) * dgettext: Internationalization. (line 113) * diagnostics: Diagnostics and Error Messages. (line 6) * dict: Dictionaries. (line 16) * Dict: Dictionaries. (line 6) * dict.q: Dictionaries. (line 6) * dictionaries: Dictionaries. (line 6) * dictionaries, hashed: Hashed Dictionaries. (line 6) * digit sequence: Numbers. (line 6) * disambiguating rules: Normal Forms and Reduction Strategy. (line 141) * div: Arithmetic Operators. (line 6) * dngettext: Internationalization. (line 113) * do: Standard Functions. (line 40) * document structuring conventions: DSC and EPSF Comments. (line 6) * double quotes: Strings. (line 6) * dowhile: Conditionals and Comprehensions. (line 135) * dowith: Standard Functions. (line 43) * dowith3: Standard Functions. (line 47) * drawing: Overview of Graphics Operations. (line 39) * drop: Standard Functions. (line 50) * dropwhile: Standard Functions. (line 53) * DSC: DSC and EPSF Comments. (line 6) * dup: Low-Level I/O. (line 11) * dup2: Low-Level I/O. (line 11) * eager evaluation: Special Forms. (line 6) * echo: Command Language. (line 286) * edit: Command Language. (line 312) * emacs: Running Scripts in Emacs. (line 6) * empty list: Constants and Variables. (line 27) * empty stream: Constants and Variables. (line 27) * empty tuple: Constants and Variables. (line 27) * emptyarray: Arrays. (line 17) * emptybag: Bags. (line 6) * emptydict: Dictionaries. (line 13) * emptyhdict: Hashed Dictionaries. (line 32) * emptyheap: Heaps. (line 21) * emptyset: Sets. (line 11) * encapsulated PostScript: DSC and EPSF Comments. (line 6) * enum <1>: The Standard Library. (line 78) * enum <2>: Arithmetic Functions. (line 10) * enum: Enumeration Types. (line 71) * enum_from <1>: Arithmetic Functions. (line 10) * enum_from: Enumeration Types. (line 78) * enumeration <1>: Enumeration Types. (line 71) * enumeration: Lists Streams and Tuples. (line 49) * enumeration type: Enumeration Types. (line 6) * enumeration, of numbers: The Standard Library. (line 78) * eoclip: Clipping. (line 10) * eof: I/O Functions. (line 47) * eofill: Painting. (line 13) * EPSF: DSC and EPSF Comments. (line 6) * eq: Standard Functions. (line 57) * equality operator, at toplevel of equation: Equations. (line 185) * equality, container data structures: Standard Types. (line 21) * equality, lists: The Standard Library. (line 89) * equality, streams <1>: Streams. (line 16) * equality, streams: The Standard Library. (line 89) * equality, tuples: The Standard Library. (line 89) * equation: Equations. (line 6) * erasepage: Miscellaneous Operations. (line 16) * errno: System Information. (line 10) * ERROR: Command Language. (line 81) * error: Diagnostics and Error Messages. (line 18) * error conditions: Error Handling. (line 6) * error message: Diagnostics and Error Messages. (line 6) * error.q: Diagnostics and Error Messages. (line 6) * errorchecking_mutex: Mutexes. (line 35) * escape sequences: Strings. (line 12) * evaluation stack: Performing Reductions on a Stack. (line 65) * exception: Exception Handling. (line 6) * exceptions: Exception Handling. (line 102) * exec: Process Control. (line 21) * exists: File I/O. (line 28) * exit: Process Control. (line 21) * exitstatus: Process Control. (line 62) * exp: Numeric Functions. (line 7) * exponential function: Numeric Functions. (line 33) * expression: Expressions. (line 6) * expression value: Normal Forms and Reduction Strategy. (line 65) * extern <1>: Writing a Module. (line 20) * extern: Declaration Syntax. (line 70) * extern symbol: Declaration Syntax. (line 70) * extern type: Writing a Module. (line 161) * external C function: Writing a Module. (line 12) * external rule: Writing a Module. (line 85) * fac: Writing a Script. (line 25) * factorial function: Writing a Script. (line 25) * factorial function, tail-recursive implementation: Tail Recursion. (line 38) * fail: Exception Handling. (line 22) * fchdir: Low-Level I/O. (line 11) * fchmod: Low-Level I/O. (line 11) * fchown: Low-Level I/O. (line 11) * fclose <1>: File I/O. (line 49) * fclose: I/O Functions. (line 20) * fcntl: Low-Level I/O. (line 74) * fconv: Extended File Functions. (line 8) * fcopy <1>: Low-Level I/O. (line 42) * fcopy: File I/O. (line 78) * fdatasync: Low-Level I/O. (line 11) * fdopen: Extended File Functions. (line 8) * feof: I/O Functions. (line 47) * fflush: I/O Functions. (line 50) * fget: Extended File Functions. (line 8) * fgetc: Extended File Functions. (line 101) * fgets: Extended File Functions. (line 8) * fib <1>: Expression References. (line 49) * fib <2>: Tail Recursion. (line 68) * fib: Equations. (line 86) * Fibonacci function: Equations. (line 86) * Fibonacci function, hashed implementation: Expression References. (line 49) * Fibonacci function, tail-recursive implementation: Tail Recursion. (line 68) * File: Built-In Types. (line 6) * file I/O: File I/O. (line 6) * file object: File I/O. (line 6) * file object, flushing output: File I/O. (line 100) * file object, unparsing: File I/O. (line 64) * file, binary: File I/O. (line 16) * filedev: Graphics. (line 38) * filename: File I/O. (line 16) * fileno: Extended File Functions. (line 8) * files, binary: File I/O. (line 121) * fill <1>: Expression References. (line 150) * fill: Painting. (line 13) * filling: Overview of Graphics Operations. (line 39) * filter: Standard Functions. (line 60) * first <1>: Dictionaries. (line 49) * first <2>: Sets. (line 41) * first <3>: Heaps. (line 42) * first: Arrays. (line 50) * fix: Command Language. (line 175) * flip: Miscellaneous Functions. (line 37) * float: Conversion Functions. (line 18) * Float: Built-In Types. (line 6) * floating point number: Constants and Variables. (line 6) * floor: Mathematical Functions. (line 12) * flush: I/O Functions. (line 50) * flushpage: Miscellaneous Operations. (line 13) * fnmatch: Filename Globbing. (line 10) * foldl: Standard Functions. (line 63) * foldl1: Standard Functions. (line 66) * foldr: Standard Functions. (line 69) * foldr1: Standard Functions. (line 72) * font: Graphics State. (line 88) * fopen <1>: Extended File Functions. (line 8) * fopen <2>: File I/O. (line 16) * fopen: I/O Functions. (line 14) * for: Conditionals and Comprehensions. (line 145) * force operator: Basic Concepts. (line 110) * fork: Process Control. (line 21) * forkpty: Low-Level I/O. (line 58) * formal parameters: Equations. (line 28) * fprintf: C-Style Formatted I/O. (line 10) * fputc: Extended File Functions. (line 101) * fputs: Extended File Functions. (line 101) * frac: Conversion Functions. (line 26) * fread: I/O Functions. (line 23) * freadc: I/O Functions. (line 29) * freadq: I/O Functions. (line 26) * freads: I/O Functions. (line 32) * free variable: Free Variables. (line 6) * freopen: Extended File Functions. (line 8) * fscanf: C-Style Formatted I/O. (line 10) * fseek: Extended File Functions. (line 8) * fst: Tuple Functions. (line 10) * fstat: Low-Level I/O. (line 11) * fsync: Low-Level I/O. (line 11) * ftell: Extended File Functions. (line 8) * ftruncate: Low-Level I/O. (line 11) * Function: Lambda Abstractions. (line 6) * function: Applications. (line 6) * function composition <1>: Built-In Special Forms. (line 60) * function composition: Function Composition. (line 6) * function symbol: Identifiers and Reserved Words. (line 6) * fungetc: Extended File Functions. (line 8) * fwrite: I/O Functions. (line 35) * fwritec: I/O Functions. (line 41) * fwriteq: I/O Functions. (line 38) * fwrites: I/O Functions. (line 44) * gcd: Additional Integer Functions. (line 96) * get <1>: Expression References. (line 13) * get: Semaphores. (line 32) * get_bound: Semaphores. (line 32) * get_size: Semaphores. (line 32) * getc: Extended File Functions. (line 101) * getcwd: File and Directory Functions. (line 10) * getegid: Process Control. (line 88) * getenv: Process Control. (line 80) * geteuid: Process Control. (line 88) * getgid: Process Control. (line 88) * getgrent: System Information. (line 69) * getgrgid: System Information. (line 69) * getgrnam: System Information. (line 69) * getgroups: Process Control. (line 88) * gethostbyaddr: System Information. (line 99) * gethostbyname: System Information. (line 99) * gethostent: System Information. (line 99) * gethostname: System Information. (line 61) * getlogin: Process Control. (line 88) * getopt: Option Parsing. (line 6) * getopt.q: Option Parsing. (line 6) * getpeername: Sockets. (line 115) * getpgid: Process Control. (line 88) * getpgrp: Process Control. (line 88) * getpid: Process Control. (line 21) * getppid: Process Control. (line 21) * getprotobyname: System Information. (line 117) * getprotobynumber: System Information. (line 117) * getprotoent: System Information. (line 117) * getpwent: System Information. (line 69) * getpwnam: System Information. (line 69) * getpwuid UID: System Information. (line 69) * gets: Extended File Functions. (line 8) * getsched: Realtime Scheduling. (line 24) * getservbyname: System Information. (line 130) * getservbyport: System Information. (line 130) * getservent: System Information. (line 130) * getsid: Process Control. (line 88) * getsockname: Sockets. (line 115) * getsockopt: Sockets. (line 115) * gettext: Internationalization. (line 113) * getuid: Process Control. (line 88) * Ghostscript: Graphics. (line 18) * glob: Filename Globbing. (line 10) * gmtime: Time Functions. (line 37) * GNU emacs: Running Scripts in Emacs. (line 6) * gr_gid: System Information. (line 69) * gr_members: System Information. (line 69) * gr_name: System Information. (line 69) * gr_passwd: System Information. (line 69) * GRAPHICS: Graphics. (line 18) * graphics: Graphics. (line 6) * graphics state: Overview of Graphics Operations. (line 44) * graphics.q: Graphics. (line 6) * grestore: Graphics State. (line 15) * grouping: Lists Streams and Tuples. (line 138) * gsave: Graphics State. (line 12) * gsdev: Graphics. (line 29) * gvdev: Graphics. (line 32) * h_addr_list: System Information. (line 99) * h_addr_type: System Information. (line 99) * h_aliases: System Information. (line 99) * h_name: System Information. (line 99) * halt: Exception Handling. (line 13) * hash: Conversion Functions. (line 30) * hash codes: Conversion Functions. (line 66) * hashes: Hashed Dictionaries. (line 6) * hd: Standard Functions. (line 75) * hdict: Hashed Dictionaries. (line 32) * HDict: Hashed Dictionaries. (line 6) * hdict.q: Hashed Dictionaries. (line 6) * hdlazy: Streams. (line 89) * hds: Standard Functions. (line 78) * hdstrict: Streams. (line 89) * header: Declaration Syntax. (line 101) * heap: Heaps. (line 24) * Heap: Heaps. (line 6) * heap.q: Heaps. (line 6) * heaps: Heaps. (line 6) * help: Command Language. (line 139) * hex: Command Language. (line 166) * higher-order functions: Equations. (line 208) * histfile: Command Language. (line 185) * histsize: Command Language. (line 185) * i: Complex Numbers. (line 6) * I/O functions: I/O Functions. (line 6) * iconv: Internationalization. (line 80) * iconv_close: Internationalization. (line 80) * iconv_open: Internationalization. (line 80) * id: Standard Functions. (line 81) * identifier: Identifiers and Reserved Words. (line 6) * identifier, qualified <1>: Unqualified Imports. (line 38) * identifier, qualified: Identifiers and Reserved Words. (line 32) * ifelse: Conditionals and Comprehensions. (line 29) * im: Complex Numbers. (line 26) * implicit import: Implicit Imports and the Prelude. (line 6) * import <1>: Command Language. (line 333) * import: Scripts and Modules. (line 20) * import, cyclic: Unqualified Imports. (line 46) * import, implicit: Implicit Imports and the Prelude. (line 6) * import, qualified: Qualified Imports. (line 6) * import, unqualified: Unqualified Imports. (line 6) * imports: Command Language. (line 398) * in: Conditionals and Comprehensions. (line 178) * include: Scripts and Modules. (line 20) * indexing: String List and Tuple Operators. (line 6) * inf: Mathematical Functions. (line 6) * infix application operator: Application and Sequence Operators. (line 11) * infix operator symbols: Expressions. (line 15) * information hiding: Using Type Guards. (line 51) * inheritance: Sub- and Supertypes. (line 6) * init: Standard Functions. (line 84) * INPUT <1>: Command Language. (line 81) * INPUT: File I/O. (line 69) * input and output: I/O Functions. (line 6) * insert <1>: Dictionaries. (line 55) * insert <2>: Sets. (line 47) * insert <3>: Heaps. (line 48) * insert: Arrays. (line 56) * int: Conversion Functions. (line 22) * Int: Built-In Types. (line 6) * integer: Constants and Variables. (line 6) * interactive mode: Running Compiler and Interpreter. (line 334) * interrupt key: Error Handling. (line 10) * intsqrt: Additional Integer Functions. (line 14) * invmod: Additional Integer Functions. (line 23) * isactive: Process Control. (line 62) * isalnum: Additional String Functions. (line 15) * isalpha: Additional String Functions. (line 15) * isarray: Arrays. (line 26) * isascii: Additional String Functions. (line 15) * isatty: Low-Level I/O. (line 54) * isbag: Bags. (line 6) * isbool: Type-Checking Predicates. (line 12) * isbytestr: Byte Strings. (line 12) * ischar: Type-Checking Predicates. (line 15) * iscntrl: Additional String Functions. (line 15) * iscomplex: Type-Checking Predicates. (line 18) * iscompval: Type-Checking Predicates. (line 63) * iscondition: Conditions. (line 18) * isconst: Miscellaneous Functions. (line 26) * isdef: Miscellaneous Functions. (line 33) * isdict: Dictionaries. (line 22) * isdigit: Additional String Functions. (line 15) * isenum: Type-Checking Predicates. (line 103) * isexact: Type-Checking Predicates. (line 88) * isexcept: Type-Checking Predicates. (line 21) * isexited: Process Control. (line 62) * isfile: Type-Checking Predicates. (line 24) * isfloat: Type-Checking Predicates. (line 27) * isfun: Miscellaneous Functions. (line 29) * isfunction: Type-Checking Predicates. (line 30) * isgraph: Additional String Functions. (line 15) * ishdict: Hashed Dictionaries. (line 32) * isheap: Heaps. (line 27) * isinexact: Type-Checking Predicates. (line 91) * isinf: Type-Checking Predicates. (line 94) * isint: Type-Checking Predicates. (line 33) * isintval: Type-Checking Predicates. (line 66) * islist: Type-Checking Predicates. (line 36) * islower: Additional String Functions. (line 15) * ismutex: Mutexes. (line 35) * isnan: Type-Checking Predicates. (line 97) * isnum: Type-Checking Predicates. (line 39) * isprime: Additional Integer Functions. (line 36) * isprint: Additional String Functions. (line 15) * ispunct: Additional String Functions. (line 15) * isrational: Type-Checking Predicates. (line 42) * isratval: Type-Checking Predicates. (line 69) * isreal: Type-Checking Predicates. (line 45) * isrealval: Type-Checking Predicates. (line 72) * isref: Expression References. (line 13) * isreflist: Expression References. (line 130) * isreflist2: Expression References. (line 130) * isrefstream: Expression References. (line 130) * isrefstream2: Expression References. (line 130) * isreftuple: Expression References. (line 130) * isreftuple2: Expression References. (line 130) * issemaphore: Semaphores. (line 32) * issentinel: Expression References. (line 78) * isset: Sets. (line 17) * issignaled: Process Control. (line 62) * isspace: Additional String Functions. (line 15) * isspecial: Miscellaneous Functions. (line 23) * isstopped: Process Control. (line 62) * isstr: Type-Checking Predicates. (line 48) * isstream: Streams. (line 21) * issym: Type-Checking Predicates. (line 51) * isthread: Thread Creation and Management. (line 14) * istuple: Type-Checking Predicates. (line 54) * isupper: Additional String Functions. (line 15) * isvar: Miscellaneous Functions. (line 29) * isxdigit: Additional String Functions. (line 15) * iter: Standard Functions. (line 87) * iterate: Streams. (line 57) * iterative algorithm: Tail Recursion. (line 76) * jacobi: Additional Integer Functions. (line 113) * join <1>: C Replacements for Common Standard Library Functions. (line 9) * join: String Functions. (line 16) * keys: Dictionaries. (line 43) * kill: Process Control. (line 21) * Lambda: Lambda Abstractions. (line 30) * lambda: Lambda Abstractions. (line 6) * lambda abstraction: Lambda Abstractions. (line 203) * lambda calculus: Equations. (line 249) * lambda function: Lambda Abstractions. (line 203) * lambdax: Lambda Abstractions. (line 30) * last <1>: Dictionaries. (line 49) * last <2>: Sets. (line 41) * last <3>: Arrays. (line 50) * last: Standard Functions. (line 91) * lazy <1>: Streams. (line 33) * lazy: Memoization and Lazy Evaluation. (line 38) * lazy evaluation: Memoization and Lazy Evaluation. (line 62) * lazy_strict: Streams. (line 89) * lcm: Additional Integer Functions. (line 96) * left-hand side: Equations. (line 6) * leftmost-innermost evaluation: Normal Forms and Reduction Strategy. (line 127) * lexicographic order, lists: The Standard Library. (line 89) * lexicographic order, streams: The Standard Library. (line 89) * lexicographic order, strings: Relational Operators. (line 6) * lg: Mathematical Functions. (line 18) * libq library: Writing a Module. (line 32) * libq, DESTRUCTOR macro: Writing a Module. (line 233) * libq, FINI macro: Writing a Module. (line 249) * libq, FUNCALL macro: Writing a Module. (line 85) * libq, FUNCTION macro: Writing a Module. (line 32) * libq, INIT macro: Writing a Module. (line 249) * libq, module initialization and finalization: Writing a Module. (line 249) * libq, MODULE macro: Writing a Module. (line 32) * libq.h header file: Writing a Module. (line 32) * lineto: Path Construction. (line 26) * link: File and Directory Functions. (line 10) * list <1>: Streams. (line 27) * list <2>: Dictionaries. (line 40) * list <3>: Sets. (line 38) * list <4>: Heaps. (line 39) * list <5>: Arrays. (line 44) * list: Conversion Functions. (line 39) * List: Built-In Types. (line 26) * list: Lists Streams and Tuples. (line 9) * list comprehensions <1>: Conditionals and Comprehensions. (line 160) * list comprehensions <2>: Lists Streams and Tuples. (line 49) * list comprehensions: Expressions. (line 15) * list enumerations: Expressions. (line 15) * list functions: String List and Tuple Functions. (line 6) * list operators: String List and Tuple Operators. (line 6) * list2: Arrays. (line 47) * listen: Sockets. (line 95) * listof: Conditionals and Comprehensions. (line 155) * literal expression: The Quote Operator. (line 6) * ln: Numeric Functions. (line 10) * load: Command Language. (line 362) * local variable: Local Variables. (line 6) * localeconv: Internationalization. (line 13) * localtime: Time Functions. (line 37) * lock: Mutexes. (line 35) * log: Mathematical Functions. (line 18) * logarithm: Numeric Functions. (line 33) * logical operators: Logical and Bit Operators. (line 6) * lpdev: Graphics. (line 35) * ls <1>: Command Language. (line 301) * ls: Pipes. (line 18) * lseek: Low-Level I/O. (line 50) * lstat: File and Directory Functions. (line 10) * map: Standard Functions. (line 94) * math.q: Mathematical Functions. (line 6) * mathematical functions: Numeric Functions. (line 6) * mathematical functions (math.q): Mathematical Functions. (line 6) * max: Standard Functions. (line 97) * member <1>: Dictionaries. (line 28) * member: Sets. (line 23) * members <1>: Dictionaries. (line 40) * members <2>: Sets. (line 38) * members <3>: Heaps. (line 39) * members: Arrays.