For the reader unfamiliar with the LISP programming language, the following few paragraphs give a brief overview of the peculiarities of the language. For more detailed information, the literature should be consulted [WH89] [Bet89] [Ins96a].
The programming language LISP has been designed primarily for use in artificial intelligence research and applications. It is an interpreting language, byte-code compilers exist. LISP provides automatic memory management and dynamic type binding. Due to its unique - some say, ugly - syntax, LISP, despite its many advantages, has not grown very popular with the scientific community. LISP uses operators in prefix notation and is notorious for the multitude of parentheses that intersperse the code. Figure A.1 shows the same statement twice, on the left side coded in C [KR88], on the right side coded in LISP, Figure A.2 shows the definition of a simple function in the C and in LISP.
Figure A.1:
Value assignment in C and LISP. setq is the
LISP assignment statement and reads set quote to indicate
that x should not be evaluated but should be used as a name.
Figure A.2:
Function declaration and definition in C and
LISP. Note that no type declaration is provided in LISP, allowing
values of any types to be passed to the function. If necessary, the
type of an argument can be checked.
A LISP function automatically returns the result of the
last statement of the function code.
A LISP function declaration may contain various classes of function arguments as shown in Figure A.3. The list of arguments starts with required symbols that have to be assigned when the function is invoked. After the &optional statement, optional arguments may be passed. The &key statement starts the list of key parameters which are passed by specifying the name together with the value. &optional and &key parameters can also carry default values to be used when they are not specified by the caller.
Figure A.3:
LISP function header.
A LISP function accepts required, optional,
and key arguments. The given function print-time prints the
time information passed in time to the standard output or to
an optionally specified file. The pretty key selects a
pretty-print mode. The semicolon is used as the comment
character in LISP.
All LISP data are stored in nodes , which are allocated, collected, and reused automatically by the interpreter; no explicit memory management is required. As long as a node is visible to any procedure it is protected from garbage collection. LISP uses lexical scoping to determine the visibility of a symbol.
LISP nodes carry type information , which is established at the moment when a symbol is bound to a specific value. In the example of Figure A.3, the symbol time of the function print-time accepts a value of any type. In order to work properly, however, a value of the correct type has to be passed to the print routine (not shown in the figure). LISP provides predicate functions to inquire the type of a symbol at run-time.
XLISP by D. Betz [Bet89] is a publicly available LISP implementation including object-oriented extensions completely written in the programming language C; it is easily extended with user written built-in functions and classes.
Vienna LISP (VLISP) is based on XLISP version 2.1 and has been enhanced by various extensions of the original implementation. New data types and procedure libraries have been added to support handling of system processes, regular expressions, operating-system independent file-specifications, timeouts, and time stamps (cf. Tables 3.2 and 3.3). The main event loop has been adapted to accommodate the callback mechanism (cf. Appendix B) used throughout VLISP as means of asynchronous communication with system processes, the graphical user interface, and timers. It runs on a variety of operating systems and platforms and has proven a very reliable and robust basis of implementation even for very large systems.