070 5607 01_4404P30_Franz_Lisp_Programmers_Reference_Jul85 01 4404P30 Franz Lisp Programmers Reference Jul85

070-5607-01_4404P30_Franz_Lisp_Programmers_Reference_Jul85 070-5607-01_4404P30_Franz_Lisp_Programmers_Reference_Jul85

User Manual: 070-5607-01_4404P30_Franz_Lisp_Programmers_Reference_Jul85

Open the PDF directly: View PDF PDF.
Page Count: 319

Download070-5607-01_4404P30_Franz_Lisp_Programmers_Reference_Jul85 070-5607-01 4404P30 Franz Lisp Programmers Reference Jul85
Open PDF In BrowserView PDF
rt-EK
I
I

Part No. 070-5607-01
Product Group 07

PROGRAMMERS
REFERENCE

4400P30
FRANZ LISP

MANUAL REVISION STATUS
PRODUCT: 4400P30 Franz Lisp Programming Language
This manual supports the following versions of this product: Version 42

DESCRIPTION

REV DATE

JAN 1985

Original Issue

FEB 1985

Revised: Pages 13-1 through 13-6.
Added: Pages iv, v, vi, 13-7, and 13-8.

JUL 1985

Completely revised and rewritten.

4404P30 FRANZ LISP PROGRAMMERS

Contents
1. FRANZ LISP

Introduction to FRANZ LISP, details of data types, and description of notation

2. Data Structure Access
Functions for the creation, destruction and manipulation of lisp data obiects.

3. Arithmetic Functions
Functions to perform arithmetic operations.

4. Special Functions
Functions for altering flow of control. Functions for mapping other functions over
lists.

5. I/O Functions
Functions for reading and writing from ports. Functions for the modification of
the reader's syntax.
'

6. System Functions
Functions for storage management, debugging, and for the reading and setting of
global Lisp status variables. Functions for doing operating system-specific tasks
such as process control.

7. The Reader
A description of the syntax codes used by the reader. An explanation of character
macros.

8. Program Forms
A description of various types of functional obiects including the use of foreign
functions.

9. Arrays and Vectors
A detailed description of the parts of an array and of Maclisp compatible arrays.

10. Exception Handling
A description of the error handling sequence and of autoloading.

11. The Lister Trace Package
A description of a very useful debugging aid.

12. Liszt, the Lisp Compiler
A description of the operation of the compiler and hints for making functions compilable.

13.The Top Level
A description of FRANZ LISP's top level which includes access to debugging tools, a
history mechanism, and single stepper.

14. Advanced Structured Programming: DeCstruct
15. The Lisp Stepper and Fixit
Programs which permits you to single-step through a Lisp program, and also
examine and modify the evaluation stack: fix bugs on the fly.

16. Lisp Editor
A structure editor for interactive modification of FRANZ LISP code.

17. Packages
Modular organization technique8 for Lisp.

18. The Foreign Function Interface
Linking LISP to subroutine8 written in other language8.

19. Objects, Message-Passing, and Flavors
Obiect-oriented programming.

Appendix A - Function Index
Appendix B - List oC Special Symbols
Appendix C - The Garbage Collector
Appendix D - LxreC
Appendix E - Reconfiguring Lisp

CHAPTER 1

FRANZ LISP

1.1. Introduction
This document is a reference manual for the FRANZ LISP system. It is not a LISP
primer or introduction to the language. It assumes that you are familiar with at least one
dialect of LISP, preferably a member of the MacLISP I Common LISP family.
A recommended text for learning LISP, with specific reference to FRANZ LISP is
LISPcraft by Robert Wilensky, published by W. W. Norton (1984).
This chapter describes the data types of FRANZ LISP and the conventions used in the
description of the FRANZ LISP. functions. In an attempt to be concise, we use a shorthand
given in §1.3. It is very important that these conventions be read for a full understanding
of subsequent sections. You should refer to the table in that section if the data types of
function arguments are in question.

L2. Data Types
FRANZ LISP has a collection of data types for system implementation and programming. This section describes each type briefly, and, if a type is divisible, the insides are
examined. There is a LISP function type that returns the type name of a LISP object.
This is the official FRANZ LISP name for that type and this name and this name only is
used in the manual to avoid confusing you. The types are listed in terms of importance
rather than alphabetically.

1.2.0. LISPval This is the name used to describe any LISP object. The function type
never returns 'LISPval'.

1.2.1. symbol This object corresponds to a variable in most other programming
languages. It may have a value or may be 'unbound'. A symbol may be lambda bound
meaning that its value (conceptually, at least) pushed on a stack, and the symbol is
given a new value for the duration of a certain context. When the LISP processor
leaves that context, the symbol's value is popped off the stack.
A symbol may also have a function binding. This function binding is static; it cannot
be lambda bound. Whenever the symbol is used in the· functional position of a LISP
expression the function binding of the symbol is examined. See Chapter 4 for more
details on evaluation.
A symbol may also have a property list, another static data structure. The property list
is a list of an even number of elements, considered to be grouped as pairs. The first element of the pair is the indicator; the second, the value of that indicator.

FRANZ LISP

1-1

FRANZ LISP

1-2

Each symbol has a print name (pnamej, which is how this symbol is identified from
input and referred to on (printed) output.
The function intern is the usual way of creating a symbol, but the functions concat,
maknam, and their derivatives also create symbols. Usually, symbols are a member of a
package, but not always (see chapter 19 for a description of packages).
Subpart name

Get value

Set value

Type

value

eval

LISPval

property
list

plist
get

function
binding
print name
home package

getd

set
setq
setplist
putprop
defprop
putd
def

list or nil

array, binary, list
or nil
string
package

get 'pname
symbol-package

1.2.2. list A list cell has two parts, called the car and cdr. List cells are created by the
function cons.
Subpart name

Get value

Set value

Type

car
cdr

car
cdr

rplaca
rplacd

LISPval
LISPval

1.2.3. binary This type acts as a function header for machine coded functions. It has
two parts: a pointer to the start of the function and a symbol whose print name
describes the argument discipline. The discipline (if lambda, macro, or nlambda) determines whether the arguments to this function are evaluated by the caller before this
function is called. If the discipline is a string (specifically "subroutine", "function",
"integer-function", "real-function", "c-function", "doub/e-c-function", "void-c-function",
or "vcctor-c-function" ) then this function is a foreign subroutine or function. (See §8.5
for more details on this.) Although the type of the cntry field of a binary type object is
usually string or other, the object pointed to is actually a sequence of machine
instructions.
Objects of type binary are created bymfunction, cfasl, and getaddrcs8.
Subpart name

Get value

Set value

Type

entry
discipline

getentry
getdisc

putdisc

string or fixnum
symbol or fixnum

FRANZ LISP

1-3

1.2.4. fixnum A fixnum is an integer constant in the range _2 29 to 229_1. Small fixnums
(-1024 to 1023) are stored in a special table so they needn't be allocated each time one
is needed.

1.2.5. Honum A Honum is a double-precision real number.

1.2.6. bignum A bignum is an integer of potentially unbounded size. When integer
arithmetic exceeds the limits of fixnums mentioned above, the calculation is automatically done with bignums. If calculation with bignums gives a result that can be
represented as a fixnum, then the fixnum representation is usedt . This contraction is
known as integer normalization. Many LISP functions assume that integers are normalized. Bignums are composed of a sequence of list cells and a cell known as an sdot.
You should consider a bignum structure indivisible and use functions such as haipart
and bignum-leftshift to extract parts of it.

1.2.7. string A string is a null terminated sequence of characters. Most functions of
symbols that operate on the symbol's print name also work on strings. The default
reader syntax is set so that a sequence of characters surrounded by double quotes is a
string.

1.2.8. port A port is a structure that the system I/O routines can reference to transfer
data between the LISP system and external media. Unlike other LISP objects there are
a very limited number of ports (20 on most machines, more on others). Ports are allocated by infile and outfile and deallocated by close and resetio. The print function
prints a port as a percent sign followed by the name of the file it is connected to (if the
port was opened by infile or outfile). During initialization, FRANZ LISP binds the symbol piport to a port attached to the standard input stream. This port prints as
#. There are ports connected to the standard output and error streams,
which print as # and #. This is discussed in more
detail at the beginning of Chapter 5.

1.2.9. vector Vectors are indexed sequences of data. They can be used to implement a
notion of user-defined types via their associated property list. They make hunks (see
below) logically unnecessary, except for compatability reasons. There is a second kind
of vector, called an immediate-vector, that stores binary data. The name that the
function type returns for immediate-vectors is vectori. For example, immediatevectors can be used to implement strings and block-Honum arrays. Vectors are discussed in chapter 9. The functions new-vector and vector can be used to create vectors.

tThe current algorithms for integer arithmetic operations return (in certain cases) a result as a bignum although
this could just barely be represented as a fixnum.

FRANZ LISP

1-4

Subpart name

Get value

Set value

Type

datum[z1
property

vref
vprop

vset
vsetprop
vputprop

LISPval
LISPval

SIze

vsize

-

fixnum

1.2.10. array Arrays are rather complicated types and are fully described in Chapter 9.
An array consists of a block of contiguous data, a function to access that data, and auxiliary fields for use by the accessing function. Since an array's accessing function is
created by the user, you can create the array to have any form you choose (e.g. ndimensional, triangular, or hash table).

Arrays are created by the function marray.
Subpart name

Get value

Set value

Type

access function

getaccess

putaccess

auxiliary
data

_getaux
arrayref

length
delta

getlength
getdelta

binary, list
or symbol
LISPval
block of contiguous
LISPval
fixnum
fixnum

~utaux

replace
set
putlength
putdelta

1.2.11. value A value cell contains a pointer to a LISPval. This type is used mainly by
arrays of general LISP objects. Value cells are created with the ptr function. A value
cell containing a pointer to the symbol 'foo' is printed as '(ptr to)foo'.

1.2.12. hunk A hunk is a vector of from 1 to 128 LISPvals. Once a hunk is created (by
hunk or makhunk) it cannot grow or shrink. The access time for an element of a hunk
is slower than that for a list cell element but faster than for an array element. Hunks
are really only allocated in sizes that are powers of two, but can appear to you to be
any size in the 1 to 128 range. You must realize that {not (atom LISPval)) returns true
if LISPval is a hunk. Most LISP systems do not have a direct test for a list cell, and,
instead, use the above test and assume that a true result means LISPval is a list cell.
In FRANZ LISP, you can use dtpr (dotted pair) to check for a list cell. Although hunks
are not list cells, you can still access the first two hunk elements with cdr and car, and
you can access any hunk element with cxrt. You can set the value of the first two elements of a hunk with rplacd and rplaca and you can set the value of any element of the
hunk with rplacx. A hunk is printed by printing its contents surrounded by { and }.
However, a hunk cannot be read in this way in the standard LISP system. It is easy to
write a reader macro to do this if desired.

tIn a hunk, the function cdr references the first element and car the second.

FRANZ LISP

1-5

1.2.13. package Chapter 17 describes the FRANZ LISP package system. The ideas,
adopted from Common LISP, are helpful for the development of large systems in a
modular fashion.

1.2.14. closure The fclosure functional object is introduced in chapter 2, but described
in greater detail in chapter 8.

1.2.15. other Occasionally, you can obtain a pointer to storage not allocated by the
LISP system. One example of this is the entry field of those FRANZ LISP functions written in C. Such objects are classified as of type other. Foreign functions, which call
malloc to allocate their own space, may also inadvertently create such objects. The
garbage collector ignores such objects.

1.3. Documentation The conventions used in the following chapters are designed to give a
great deal of information in a brief space. The first line of a function description contains
the function name in bold face and then lists the arguments, if there are any. The arguments all have names that begin with a letter or letters and an underscore. The initial
letter or letters give the allowable type or types for that argument according to this table.

Letter
g
s
t
I
n
i
x
b
f
u
y
v
V
H
a
e
p
h
k
cl

AlIQwable type(s}
any type
symbol (although nil may not be allowed)
string
list (although nil may be allowed)
number (fixnum Honum bignum)
integer (fixnum, bignum)
fixnum
bignum
Honum
function type (either binary or lambda body)
binary
vector
vectori
hash table
array
value
port (or nil)
hunk
package
closure

In the first line of a function description we provide a template showing you how to call
the function from the top level, including appropriate quote marks. (In FRANZ LISP, the
form 'foo is the same as (quote foo).) For example, cons could be described via (cons

FRANZ LISP

1-6

'g_first 'g_rest), allowing us to say the result is the list cell x where (car x) = g_first, and
(cdr x) = g_rest. Referring to the previous table, we see that the 'g' prefix means 'general'
or 'any type'. The suffIXes first and rest are chosen to be mnemonically useful. Those arguments preceded by a quote mark are evaluated before the function is applied. This allows
us to refer to the result of the cons without saying "the result of evaluating its first argument ... " etc.
Occasionally a function will utilize some special order of evaluation (or non-evaluation) but
if the arguments are generally evaluated, we will still use this notation.
When an argument is not quoted in the function description line, it is usually because
no evaluation is done on that argument. Rarely, however, the argument is evaluated but
at a time specifically mentioned in the function description.
Optional arguments are surrounded by square brackets. An ellipsis (... ) means zero or
more occurrences of an argument of the directly preceding type.

1.4. Some History

The original version of FRANZ LISP was created as a research tool for symbolic and
algebraic manipulation, artificial intelligence, and programming languages at the University
of California at Berkeley. AJ5 FRANZ LISP grew, it adopted numerous features of Mac LISP
and LISP Machine LISP (Zetalisp). Substantial compatibility with other LISP dialects
(Interlisp, UCILISP) is achieved by means of support packages and compiler switches.
Beginning in 1984, Franz Inc.'s Common LISP compatibility features were introduced making this version of FRANZ LISP a unique combination of a proven LISP system with the
essential support for development and delivery of Common LISP programs.
The kernel of FRANZ LISP is written almost entirely in the programming language C,
with much of the support written in (compiled) LISP. For run-time efficiency, small portions of the kernel are written in assembly language.
FRANZ LISP's distinctive features include its capability of running very large LISP
programs in a timesharing environment, its excellent facilities for arrays and user-defined
structures, its user-controlled reader with character and word macro capabilities, and its
ability to interact directly with compiled LISP, C, Fortran, and Pascal code in most implementations.

CHAPTER 2

Data Structure Access

The functions described in this chapter allow you to create and manipulate the various
types of lisp data structures. Refer to §1.2 for a brief overview of the data structures available in
FRANZ LISP.

2.1. Lists

The following functions exist for the creation and manipulation of lists. Lists are
composed of a linked list of objects. Various authors call these either 'list cells', 'cons cells'
or 'dtpr cells'. Lists are normally terminated with the special symbol nil. nil is both a
symbol and a representation for the empty list O.

2.1.1. list creation

(cons 'g_argl 'lLarg2)
RETURNS: A new list cell whose car is g_argl and whose cdr is g_arg2.

(xcons 'lLargl 'g_arg2)
EQUNALENT TO: (cons 'u-arg2 'u-argl)
(ncons 'g_arg)
EQUNALENT TO: (cons 'g_arg nil)

(list ['g_argl ... ])
(list ... ['!Largl ... ])
RETURNS: A list whose elements are the lLargi.
NOTE: List* differs from list in that the last argument is cons'd on to the list.
EXAMPLE:

(list 'x 'y '(z w)) is {x y (z w))
(list* 'x 'y '(z w)) is (x y z w)

(append 'l_argl 'l_arg2 [ ... ])
RETURNS: A list containing the elements of l_argl followed by l_arg2.
NOTE: To generate the result, the top level list cells of l_argl are duplicated and the cdr of

the last list cell is set to point to l_arg2. Thus this is an expensive operation if
l_argl is large. See the descriptions of nconc and tconc for cheaper ways of doing the
append if the list Largl can be altered.

Data Structure Access

2-1

Data Structure Access

2-2

(append! 'l_argl 'Larg2)
RETURNS: A list like l_argl with g_arg2 as the last element.
NOTE: This is equivalent to (append 'Cargl (list 'g_arg2)).

; A common mistake is using append to add one element to the end of a list

-> (append '(a bed) 'e}

(abed.e)
; The user intended to say:

-> (append '(a bed) '(e})
(a bed e)
better i, append1
-> (append1 '(a bed) 'e}
(a bed e)

j

(quote! [g_qformtJ ... [! 'g_eforma] ... [I! 'I_forma] ... )
RETURNS: The list resulting from the splicing and insertion process described below.
NOTE: quote! is the complement of the list function. list forms a list by evaluating each
form in the argument list; evaluation is suppressed if the form is quoteed. In quote!,
each form is implicitly quoteed. To be evaluated, a form must be preceded by one of
the evaluate operations! or I!. ! g_eform evaluates g30rm and the value is inserted in
the place of the call; !! I_form evaluates I_form and the value is spliced into the place
of the call.
'Splicing in' means that the parentheses surrounding the list are removed as the
example below shows. Use of the evaluate operators can occur at any level in a form
argument.
Another way to get the effect of the quote! function is to use the backquote character
macro (see § 8.3.3).

(quote! con, ! (cons 1 2) 9} = (cons (1 . 2) 9}
(quote! 1 !! (li,t 2 94) 5} = (1 294 5)
(quote! tr/ll '(this lone)} = (tr/l (this! one)}

Data Structure Access

2-3

(bignum-to-list 'b_arg)
RETURNS: A list of the fixnums which are used to represent the bignum.
NOTE:

The inverse of this function is list-to-bignum.

(list-to-bignum'l_ints)
WHERE:
l_ints is a list of fixnums.
RETURNS:
NOTE:

A bignum constructed of the given fixnums.

The inverse of this function is bignum-to-list.

2.1.2. list predicates

(dtpr 'g_arg)
RETURNS:
NOTE:

t if g_arg is a list cell.

(dtpr '()) is nil. The name dtpr is a contraction for "dotted pair".

(listp 'g_arg)
RETURNS:

(tailp

t if g_arg is a list object or nil.

'Cx '1.s)

RETURNS:

I_x, if a list cell eq to I_x is found by cdring down l.s zero or more times, nil otherwISe.

=> (Betq z '(a bed) 1/ (cddr z))
(c d)

=> (and (dtpr

z) (liBtp z))

; x and y are dtprs and lists

t

; 0 is the same as nil and is not a dtpr

=> (dtpr '())
nil

=> (Iistp '())

; however it is a list

t

=> (tailp II z)
(c d)

(length 'l_arg)
RETURNS:

The number of elements in the top level of list l_arg.

Data Structure Access

2-4

2.1.3. list accessing
(car 'l_arg)
(cdr 'Carg)
RETURNS: The appropriate part of cons cell. (car (cons x y)) is always x, (cdr (cons x y)) is
always y. In FRANZ LISP, the cdr portion is located first in memory. This is
hardly noticeable, and we mention it primarily as a curiosity.
(c ••r 'lh_arg)
WHERE:

The .. represents any positive number of a's and d's.

RETURNS: The result of accessing the list structure in the way determined by the function
name. The a's and d's are read from right to left, a d directing the access down
the cdr part of the list cell and an a down the car part.
NOTE: lh_arg may also be nil, and it is guaranteed that the car and cdr of nil is nil. If
lh_arg is a hunk, then (car 'Ih_arg) is the same as (exr 1 'Ih_arg) and (cdr 'Ih_arg) is
the same as (exr 0 'Ih_arg).
It is generally hard to read and understand the context of functions with large strings
of a's and d's, but these functions are supported by rapid accessing and opencompiling (see Chapter 12).
(nth 'x_index 'I_list)
RETURNS: The nth element of Uist, assuming zero-based index. Thus (nth 0 I_list) is the
same as (car I_list). nth is both a function and a compiler macro so that more
efficient code might be generated than for nthe/em (described below).
NOTE: If x_arg1 is non-positive or greater than the length of the list, nil is returned.
(nthcdr 'x_index 'Uist)
RETURNS: The result of cdring down the list Uist x_index times.
NOTE: If x_index is less than 0, then (cons nil 'Llist) is returned.
(nthelem 'x_arg1 'l_arg2)
RETURNS: The x_arg1'st element of the list l_arg2.
NOTE: This somewhat non-standard name of this function comes from the PDP-ll Lisp system.

(last 'Larg)
RETURNS: The last list cell in the list l_arg.
EXAMPLE: last does NOT return the last element of a list!
{last '(a b)) = (b)

Data Structure Access

2-5

(ldiff 'l_x '1...Y)
RETURNS: A list of all elements in Cx but not in l"'y , i.e., the list difference of 1-" and l"'y.
NOTE: l"'y must be a tail of I_x, i.e., eq to the result of applying some number of cdr's to

I_x. Note that the value of IdiU is always a new list structure unless l"'y is nil, in
which case {ldiU Cx nil} is I_x itself. If 1...Y is not a tail of I_x, IdiU generates an
error.
EXAMPLE: {ldiU 'Cx {member 'gJoo 'Cx}} gives all elements in I_x up to the first g_foo.

2.1.4. list manipulation
(rplaca 'Ih_argl 'g_arg2)
RETURNS: The modified Ih_argl.
SIDE EFFECT: The car of lh_argl is set to g_arg2. H lh_argl is a hunk then the second element of the hunk is set to s-arg2.
(rplacd 'lh_argl 'g_arg2)
RETURNS: The modified Ih_argl.
SIDE EFFECT: The cdr of Ih_arg2 is set to g_arg2. H Ih_argl is a hunk then the first element of the hunk is set to g_arg2.
(attach 's-x '1_1)
RETURNS: 1 1 whose car is now g_x, whose cadr is the original {car Cl}, and whose cddr is
the original {cdr U}.
NOTE: What happens is that g_x is added to the beginning of list 1_1 yet maintaining the
same list cell at the beginning of the list.
(delete 's-val 'Uist ['x_count])
RETURNS: The result of splicing s-val from the top level of I_list no more than x30unt
times.
NOTE: x_count defaults to a very large number, thus if x_count is not given, all occurrences
of g_val are removed from the top level of I_list. s-val is compared with successive
car's of I_list using the function equal.
SIDE EFFECT:

I_list is modified using rplacd, no new list cells are used.

(delq 'g_val 'Clist ['x_count])
(dremove 's-val 'I_list ['x_count])
RETURNS: The result of splicing s-val from the top level of I_list no more than x_count
times.
NOTE: delq {and dremove} are the same as delete except that eq is used for comparison
instead of equal.

Data Structure Access

2-6

; note that you should use the value returned by delete or delq
; and not assume that s-val will always show the deletions.
; For example

->

(Betq teBt '(a b cad e)}

(a b cad e)

-> (delete 'a teBt)
(b cd e)

->

; the value returned is what we would expect

teBt

(a b c d e)

; but test still has the first a in the list!

(remq 'ILX '1_1 ['X30unt])
(remove 'g_x '1_1)
RETURNS: A copy of 1_1 with all top level elements equal to g_x removed. remq uses eq
instead of equal for comparisons.
NOTE: remove does not modify its arguments like delete and delq do.
(insert 'g_object 'I_list 'u30mparefn 'ILnodups)
RETURNS: A list consisting of I_list with g_object destructively inserted in a place determined by the ordering function u30mparefn.
NOTE: (compare/n 'g_x 'U-y) should return something non-nil, if g_x can precede gJ in
sorted order; nil, if g J must precede ILX. H u_comparefn is nil, alphabetical order is
used. H g_nodups is non-nil, an element is not inserted, if an equal element is already
in the list. insert does a binary search to determine where to insert the new element.
(merge 'I_datal 'l_data2 'u_comparefn)
RETURNS: The merged list of the two input sorted lists I_datal and I_datal using binary
comparison function u_comparefn.
NOTE: (compare/n 'g_x 'g_y) should return something non-nil, if g_x can precede gJ in
sorted order; nil, if g J must precede ~x. If u30mparefn is nil, alphabetical order is
used. u30mparefn should be thought of as "less than or equal to". merge changes
both of its data arguments.
(subst '~x ' g J '1_5)
(dsubst '~x 'g-y '1_5)
RETURNS: The result of substituting g_x for all equal occurrences of g-y at all levels in l_s.
NOTE: H g-y is a symbol, eq is used for comparisons. The function subst does not modify
1_5 but the function dsubst (destructive substitution) does.

Data Structure Access

2-7

(lsubst 'l_x 'g""y 'l_s)
RETURNS:

A copy of I_s with I_x spliced in for every occurrence of g""y at all levels. Splicing
in means that the parentheses surrounding the list I_x are removed as the example
below shows.

-> (subsl '(a b c) 'x '(x y z (x y z) (x y z)))
((a b c) y z ((a b c) y z) ((a b c) y z))

-> (lBUbsl '(a b c) 'x '(x y z (x y z) (x y z)))
(a b c y z (a b c y z) (a bey z))

(subpair 'I_old 'I_new 'l_expr)
WHERE:

There are the same number of elements in I_old as 1 new.

RETURNS:

The list Cexpr with all occurrences of an object in I_old replaced by the
corresponding one in I_new. When a substitution is made, a copy of the value to
substitute in is not made.

EXAMPLE:

(subpair '(a c)' (x y) '(a bed)}

=

(x b y d)

(nconc 'l_argl 'l_arg2 ['I_arg3 ... J)
RETURNS:
NOTE:

A list consisting of the elements of l_argl followed by the elements of l_arg2 followed by l_arg3 and so on.
'

The cdr of the last list cell of l_argi is changed to point to l_argi+1.

; nconc is faster than append because it doesn't allocate new list cells.
(selq lisl '(a be))
(a b c)
-> (selq lis2 '(d e I))
(d e f)
-> (append tisl lis2)
(a b c d e f)
-> lisl
(a b c)
; note that lis! has not been changed by append
-> (nconc lisl lis2)
(a bed e f) ; nconc returns the same value as append
-> lisl
(a b c d e f) ; but in doing so alters lis!

->

Data Structure Access

2-8

(reverse 'l_arg)
(nreverse 'l_arg)
RETURNS: The list l_arg with the elements at the top level in reverse order.
NOTE: The function nrever8e does the reversal in place; that is, the list structure is modified.

(nreconc 'l_arg 'g_arg)
EQUIVALENT TO: (nconc (nrever8e 'Carg) 'g_arg)

2.2. Predicates
The following functions test for properties of data objects. When the result of the
test is either 'false' or 'true', then nil is returned for 'false' and something other than nil
(often t) is returned for 'true'.
(arrayp 'g_arg)
RETURNS: t if g_arg is of type array.

(atom 'Larg)
RETURNS: t if g_arg is not a list or hunk object.
NOTE: (atom '()) returns t.

(bcdp 'Larg)
RETURNS: t if g_arg is a data object of type binary.
NOTE: This function name is a throwback to the

code predicate.
(bigp 'Larg)
RETURNS: t if g_arg is a bignum.

(dtpr 'Larg)
RETURNS: t if Larg is a list cell.
NOTE: (dtpr

'm is nil.

(hunkp 'g_arg)
RETURNS: t if g_arg is a hunk.

(listp 'g_arg)
RETURNS: t if g_arg is a list object or nil.

PDP-U Lisp system. It stands for binary

Data Structure Access

(stringp 'g_arg)
RETURNS: t if g_arg is a string.

(symbolp 'g_arg)
RETURNS: t if g_arg is a symbol.

(litatom 'g_arg)
RETURNS: t if g_arg is a string or symbol, not a number.

(valuep 'g_arg)
RETURNS: t if g_arg is a value cell

( vectorp 'v_vector)
RETURNS: t if the argument is a vector.

( vectorip 'v_vector)
RETURNS: t if the argument is an immediate-vector.

(keywordp's_sym)
RETURNS: t if the argument is a symbol and is in the keyword package.

(packagep 'k-package)
RETURNS: t if the argument is a package.

(hash-table-p 'H_arg)
RETURNS: t if H_arg is a hash table, nil otherwise.
NOTE: A hash table is implemented using vectors, and the function typep returns vector

when given a hash table.
(type 'g_arg)
(typep 'g_arg)
RETURNS: A symbol whose pname describes the type of g_arg.

(signp s_test 'g_val)
RETURNS: t if g_val is a number and the given test s_test on g_val returns true.
NOTE: The fact that 8ignp simply returns nil if g_val is not a number, is probably the most
important reason that 8ignp is used. The permitted values for s_test and what they

mean are given in this table.
s_test

tested

Ie
e
n
ge

0
0
~val = 0
g_val =/: 0
g_val ~ 0
g. val> 0

g

g_val
g_val

<

~

Data Structure Access

2-10

(eq 'g_argl 'g_arg2)
RETURNS: t if g_argl and g_arg2 are the exact same lisp object.
NOTE: Eq simply tests if g_argl and g_arg2 are located in exactly the same place in
memory. Lisp objects that print the same are not necessarily eq. The only objects
guaranteed to be eq are interned symbols with the same print name. Unless a symbol
is created in a special way (such as with uconcat or maknam) it is interned.
(neq '(LX 'g""'y)
(nequal '(LX 'g....,Y)
RETURNS: (for neq,) t if g_x is not eq to g""'y, otherwise nil. (for nequal,) t if {LX is not equal
to g....,Y, otherwise nil.
(equal 'g_argl '(Larg2)
(eqstr '(Largl 'g_arg2)
RETURNS: t if g_argl and g_arg2 have the same structure as described below.
NOTE: {Larg and g_arg2 are equal if
(1) They are eq.
(2) They are both fixnums with the same value
(3) They are both fionums with the same value
(4) They are both bignums with the same value
(5) They are both strings and are identical.
(6) They are both lists and their cars and cdrs are equal.

; 6q is much faster than equal, especially in compiled code.
; However, you cannot use eq to test for equality of numbers outside
; of the range -1024 to 1023. equal always works.
-> (ell,10881089)
t

->

(eq 1084 1084)

nil

->

(6qua11084 1084)

t

(not 'g_arg)
(null 'g_arg)
RETURNS: t

if g_arg is nil.

Data Structure Access

2-11

(member 'g_argl 'l_arg2)
(memq '~argl '1_arg2)
RETURNS: That part of the l_arg2 beginning with the first occurrence of g_argl. If g_argl is
not in the top level of l_arg2, nil is returned.
NOTE: member tests for equality with equal; memq tests for equality with eq.

2.3. Symbols and Strings

In many of the following functions, the distinction between symbols and strings is
somewhat blurred. For FRANZ LISP, a string is a null terminated sequence of characters,
stored as compactly as possible. Strings are used as constants in FRANZ LISP. They eval to
themselves. A symbol has additional structure: a value, property list, function binding,
package-cell, as well as its external representation (or print-name). If a symbol is given to
one of the string manipulation functions below, its print name is used as the string.
Another popular way to represent strings in Lisp is as a list of fixnums which
represent characters. The suffix 'n' to a string manipulation function indicates that it
returns a string in this form.

2.3.1. symbol and string creation

(concat ['stn_argl ... ])
(uconcat ['stn_argl '" ])
(strcat ['stn_argl ... ])
RETURNS: A symbol whose print name (or in the case of strcat, a string) is the result of concatenating the print names, string characters, or numerical representations of the
stn_argi.
NOTE: If no arguments are given, a symbol with a null pname is returned. concat interns
(see intern) the symbol in the current package; the function uconcat does the same
thing but does not intern the symbol.
EXAMPLE: {concat 'abc (add 9 4) "de! )

= abc7def

(concatl 'l_arg)
EQUNALENT TO: (apply 'concat 'Larg)
(implode 'l_arg)
(implodes'l_arg)
(maknam. 'l_arg)
WHERE: l_arg is a list of symbols, strings and/or small fixnums.
RETURNS: The symbol whose print name (or in the case of implodes, the string) that is the
result of concatenating the first characters of the print names of the symbols and
strings in the list. Any fixnums are converted to the equivalent ASen character.
In order to concatenate entire strings or print names, use the function concat.
NOTE: implode interns the symbol it creates, maknam does not.

Data Structure Access

2-12

(copysymbol 's_arg 'g-pred)
RETURNS: An uninterned symbol with the same print name as s_arg. If g-pred is non nil,
then the value, function binding, and property list of the new symbol are made eq
to those of s_arg.
(ascii 'x_charnum)
WHERE: x3harnum is between 0 and 255.
RETURNS: A symbol whose print name is the single character whose fixnum representation is
x_charnum.
(intern 's_arg ['k-package])
RETURNS: s_arg
s_arg is installed in the package k-package or (by default) the current package.
NOTE: When a symbol is interned, a mapping between the external print-name and the symbol itself is established. Most symbols are interned so that when the user types in
say, /00, this is the same symbol as previously used. It is possible to change an existing /00 to be uninternedj in that case when a token /00, is read in, a new symbol,
unrelated to the old one except by its coincidentally matching print-name, is created.
The two symbols will ordinarily have different values, etc. One can refer to the old
/00 only by having an internal pointer to it. As far as the reader is concerned, there's
no /00 like the old /00.

SIDE EFFECT:

(remob 's_symbol)
RETURNS: s_symbol
SIDE EFFECT: s_symbol is removed from the current package.
"remob" comes from "remove from the object list".

Historically, the name

(rematom 's_arg)
RETURNS: t if s_arg is indeed an atom.
s_arg is put on the free atom list, effectively reclaiming an atom cell.
NOTE: This function does not check to see if s_arg is accessible. While rematom enables you
to reclaim a small amount of storage, and can be used effectively with gensym'd
atoms, you must be extremely cautious. If you use it on an interned atom which is
referenced by some s-expression, you may be find that one or more different atoms
are synonymous. This can lead to errors which are very difficult to detect. This function should be used only when storage optimization is important and you are creating
many atoms with short lifetimes.
SIDE EFFECT:

Data Structure Access

2-13

The following functions are recommended for use in the orderly management of generated symbols:
(newsym's_name)
(gensym 's_name)
RETURNS: a new uninterned symbol whose name will be s_name with an integer con-

catenated to the right.
SIDE EFFECT:

The integer used (by default initially 0) will be incremented at each use (and
can be initialized to some other value by initsym, described below.

NOTE: Gensym, the original system function, uses only the first letter of s_name, and

manufactures a symbol with that prefix and a six-digit suffix which is the number of
times gensym has been called.

(oldsym 's_name)
RETURNS: the last symbol returned from newsym in the series generated from s_name. If
s_name has not been used, the return value is just s_name.
(allsym 'sCarg)
RETURNS: a list of symbols generated by newsym.
NOTE: If sl_arg is a symbol, all newsymed symbols with that prefix will be in the list

returned. If sCarg is a pair: (name number), then only symbols beginning with the
name and generated with suffix equal to number or higher will be listed.
(initsym 'Uistl ... )
WHERE:
each Uisti is of the form (symbol fixnum).
RETURNS: a list of generated symbols serving as the initialization of symbol generators.
SIDE EFFECT:
EXAMPLE: -

Future calls to newsym may be affected by this initialization.

> (initsym '(foo 10) '(bar 3))
(foolO bar3) - > (newsym 'bar) bar4

(remsym 'sClistl ... )
WHERE:
each sl_listi is a symbol or a list.
SIDE EFFECT:

If sl_listi is a symbol, all the generated symbols with that prefix are uninterned. If sl_listi is a pair (name number), uninterning is done on symbols
beginning with the name and with suffix equal to the given number or higher.

(symstat 's_namel ... )
RETURNS: a list of pairs: (name number) for each s_namel, where s_namei is presumably a
prefix for generated symbols, the number in the pair is the last number used in a
gensym with that prefix. If the name has not been used at all the second element
of the pair will be nil.

Data Structure Access

2-14

2.3.2. string and symbol predicates

(boundp 's_name)
RETURNS: nil if s_name is unbound; that is, it has never been given a value. If x name has
the value g_val, then (nil. g_val) is returned. See also makunbound.
(alphalessp 'st_argl 'st_arg2)
RETURNS: t if the 'name' of st_argl is alphabetically less than. the name of st_arg2. If st_arg
is a symbol, then its 'name' is its print name. If st_arg is a string, then its 'name'
is the string itself.
(str= 't_stringl 't_string2)
RETURNS: t if t_stringl is equal to t_string2.
NOTE:

An error is signalled if the arguments are not strings.

2.3.3. symbol and string accessing

(symeval's_arg)
(symbol-value's_arg)
RETURNS: The value of symbol s_arg. Symbol-value is the Common Lisp name for this function.
NOTE: It is illegal to ask for the value of an unbound symbol. . This function has the same
effect as eval, but compiles into much more efficient code.
(get-pname 's_arg)
(symbol-name's_arg)
RETURNS: The string that is the print name of s_arg.
NOTE: Symbol-name is the Common Lisp name for this function.
(getd 's_arg)
(symbol-function's_arg)
RETURNS: the function definition of s_arg. If there is no function definition, getd returns nil;
8ymbol-function, the Common Lisp function signals an error in this case.
NOTE:

The function definition may turn out to be an array header. You might wish to use
jboundp to see if a function definition exists in a Common Lisp world, rather than
getd.

(symbol-package's_name)
RETURNS: the contents of the package cell for the symbol s_name. This will be nil if there is
no package associated with s_name.

Data Structure Access

2-15

(fboundp's_arg)
RETURNS: t if s_arg is bound to a function.
(getchar 's_arg 'x_index)
(nthchar 's_arg 'x_index)
(getcharn 's_arg 'x_index)
RETURNS: The x_indexth character of the print name of s_arg or nil if x_index is less than 1
or greater than the length of s_arg's print name.
NOTE: getchar and nthchar return a symbol with a single character print name; getcharn

returns the fixnum representation of the character.
(substring 'st_string 'x_index ['x_length])
(substringn 'st_string 'x_index ['x_length])

x_indexth character in the string.
NOTE: IT x_length is not given, all of the characters for x_index to the end of the string are
returned. IT x_index is negative, the string begins at the x_indexth character from
the end. If x_index is out of bounds, nil is returned.
NOTE: substring returns a list of symbols; substringn returns a list of fixnums. If substringn
is given a 0 x_length argument, then a single fixnum, which is the x_indexth character, is returned.

RETURNS: A string of length at most x_length starting at

(char-index 't_string 'stx_char)
(char-rindex 't_string 'stx_char)
RETURNS: the index of stx_char in t_string, from the beginning of the string, in the case of
char-index, and the end of the string in the case of char-rindex. If stx_char is a
fixnum it will be treated as the ascii code for the character. If stx_char is a symbol or string, the first character of the print name or the string is used.
(substrp 't_stringl 'string2)
RETURNS: t if t_stringl is contained in t_string2, nil otherwise.

(string 'st_symbol-or-string)
RETURNS: a string, given a string or symbol. In case of a symbol arg it returns the symbol's

print name.

2.3.4. symbol and string manipulation
(set 's_argl 'g_arg2)
RETURNS: g_arg2.
SIDE EFFECT:

The value of s_argl is set to g_arg2.

Data Structure Access

2-16

(setq s_atml 'g_vall [s_atm2 '~val2 ...... J)
The arguments are pairs of atom names and expressions.
RETURNS: The last g_vali.
SIDE EFFECT: Each s_atmi is set to have the value g_vali.
WHERE:

NOTE: set

evaluates all of its arguments; setq does not evaluate the s_atmi.

(desetq sl...J>atternl 'g_expl [......J)
RETURNS: g_expn
SIDE EFFECT:

This acts just like setq if all the sl...J>atterni are symbols. If sl...J>atterni is a
list, then it is a template which should have the same structure as g_expi .
The symbols in sl...J>attern are assigned to the corresponding parts of g_exp.
(See also setf)

EXAMPLE: (desetq (a b (c . d)) '(1 2 (9 -I 5)))
sets a to 1, b to 2, c to 3, and d to (4 5).
(setplist 's_atm 'l-plist)
l...J>list.
SIDE EFFECT: The property list of s_atm is set to 1...J>list.

RETURNS:

(makunbound's_arg)
RETURNS: s_arg
SIDE EFFECT: The value of s_arg is made 'unbound'. If the interpreter attempts to evaluate s_arg before it is again given a value, an unbound variable error occurs.
(explode '~arg)
(explodee 'g_arg)
(exploden 'g_arg)
(eseape-exploden '~arg)
(qualify-explode 'g_arg)
(qualify-explodee 'g_arg)
(qualify-exploden '~arg)
(qualify-eseape-exploden '~arg)
RETURNS: A list of the characters used to print out s_arg or ~arg.
NOTE: There are a set of functions called "aexplode" which mirror the above functions, except that
they only take symbols as arguments.
NOTE: If the function name ends in a cen", then the function returns a fixnum representation
of the character instead of the character itself. Also, the functions beginning with
"qualify" return a list of characters or fixnums which include package qualifiers.
NOTE: The functions explode, escape-exploden, qualify-explode and qualify-escape-exploden
return a list of characters or fixnums that print would use to print the argument,
which include all necessary escape characters. The functions explodec, exploden,
qualify-explodec and qualify-exploden return a list of characters or fixnums that patom
would use to print the argument (that is, no escape characters).

Data Structure Access

=>

(setq x 'Iquote this

Iquote this

=>

\I ok?1

2-17

\I okfl)

(explode x)

(q u 0 t e 1\\1 II t his 1\\1111\\11\111\\111 0 U)
; note that 1\\1 just means the single character: backslash.
; and 1\11 just means the single character: vertical bar
; and I I means the single character: space

=>
(q u

=>

(explodec x)
0

tell t his 111\1111 ok?)

(exploden x)

(113 117 111 116 101 32 116 104 105 115 32 124 32 111 107 63)

2.4. Vectors

See Chapter 9 for a discussion of vectors.

2.4.1. vector creation
(new-vector 'x_size ['g_fill ['g-prop]])
RETURNS: A vector of length x_size. Each data entry is initialized to g_fill, or to nil, if the

argument g_fill is not present. The vector's property is set to g-prop, or to nil,
by default.
(new-vectori-byte 'x_size ['g_fill ['g-prop]])
(new-vectori-word 'x_size ['g_fill ['g-prop]])
(new-vectori-Iong 'x~size ['g_fill ['g-prop]])
(new-vectori-Hoat 'x_size ['g_fill ['g-prop]])
(new-vectori-double 'x_size ['g_fill ['g-prop]])
RETURNS: A vectori with x_size elements in it. The actual memory requirement is two long

words + x_size*(n bytes), where n is 1 for new-vector-byte, 2 for new-vector-word, 4 for new-vectori-long or new-vectori-float, or 8 for new-vectori-double.
Each data entry is initialized to g_fill, or to zero, if the argument g_fill is not
present. The vector's property is set to g-prop, or nil, by default.

NOTE: new-vectori-float and new-vectori-double are intended to be used in passing float and

double arrays to C routines.

Data Structure Access

2-18

Vectors may be created by specifying multiple initial values:
(vector ['g_vaIO 's-vall ... J)
RETURNS: A vector with as many data elements as there are arguments. It is quite possible
to have a vector with no data elements. The vector's property is a null list.
(vector i-byte ['x_valO 'x_val2 ... J)
(vectori-word ['x_valO 'x_val2 ... J)
(vector i-long ['x_valO 'x_val2 ... J)
(vector i-float ['CvalO 'Cval2 ... J)
(vectori-double ['CvalO 'Cval2 ... J)
RETURNS: A vectori with as many data elements as there are arguments. The arguments
are required to be fixnums, except in the case of float and double, where they
must be flonums. Only the low order byte or word is used in the case of vectoribyte and vectori-word. The vector's property is null.

2.4.2. vector reference
(vref'v_vect 'x_index)
(vrefl-byte 'V_vect 'x_bindex)
(vrefl-word 'V_vect 'x_windex)
(vrefl-Iong 'V_vect 'x_Iindex)
(vrefl-float 'V_vect 'x_lindex)
(vrefi-double 'V_vect 'x_lindex)
RETURNS:

The desired data element from a vector. The indices must be fixnums. Indexing
is zero-based. The vrefi functions sign extend the data.

(vprop'Vv_vect)
RETURNS: The Lisp property associated with a vector.
(vget 'Vv_vect 'g_ind)
RETURNS: The value stored under s-ind if the Lisp property associated with 'Vv_vect is a
disembodied property list.
(vsize'Vv_vect)
(v size-byte 'V_vect)
(vsize-word 'V_vect)
(vsize-float 'V_vect)
(vsize-double 'V_vect)
RETURNS: The number of data elements in the vector. For immediate-vectors, the functions
vsize-byte and vsize-word return the number of data elements, if you think of the
binary data as being comprosed of bytes or words.

Data Structure Access

2-19

2.4.3. vector modification
(v set 'v_vect 'x_index 'g_val)
(vseti-byte 'V_vect 'x_bindex 'x_val)
(vseti-word 'V_vect 'x_wind ex 'x_val)
(vseti-Iong 'V_vect 'x_Iindex 'x_val)
(vseti-float 'V_vect 'x_Iindex 'Cval)
(vseti-double 'V_vect 'x_Iindex 'Cval)
RETURNS: The datum.
SIDE EFFECT:

The indexed element of the vector is set to the value. AB noted above, for
vseti-word and vseti-byte, the index is construed as the number of the data
element within the vector. It is not a byte address. Also, for those two functions, the low order byte or word of x_val is what is stored.

(vsetprop 'Vv_vect 'g_value)
RETURNS: g_value. This should be either a symbol or a disembodied property list whose car

is a symbol identifying the type of the vector.
SIDE EFFECT:

The property list of Vv_vect is set to g_value.

(vputprop 'Vv_vect 'g_value 'g_ind)
RETURNS: g_value.
SIDE EFFECT:

If the vector property of Vv_vect is a disembodied property list, then
vputprop adds the value g_value under the indicator g_ind. Otherwise, the
old vector property is made the first element of the list.

2.5. Hash Tables
A hash table is an object that can efficiently map one object to another. Each hash
table is a collection of entries, each of which associates a unique key with a value. There
are functions to add, delete, and find entries based on a particular key. Finding a value in
a hash table is relatively fast compared to looking up values in, for example, an assoc list
or property list.
The hash table is not a true data type, but rather a type which is constructed from
objects of the type vector. Because of this, the vector predicate returns a non-nil value
when handed a hash table. It should be noted that using v8et to set a element of the hash
table will yield unpredictable results.
Adding a key to a hash table modifies the hash table, and is therefore a destructive
operation.
There are two different kinds of hash tables: those that use the function equal for the
comparing of keys, and those that use eq, the default. When a hash table is created, the
type of comparator is set. If eq is chosen as the comparator, and a lookup of a key is being
performed, then the given key is compared to the keys in the table using eq.
Hashing provides an efficient basis for the construction of the package8 facility and
for various sorts of data retrieval techniques.

Data Structure Access

2-20

This hash table package is completely compatible with the one in Common Lisp.

2.6.1. hash table functions
(make-hash-table :size :test :rehash-size :rehash-threshold)
RETURNS: A hash table object of some number of buckets, given by the :size argument. H

the function to compare hash table keys is be something other than eq, then the
:test argument should be used to set this (the choices are eq, equal, or nil).
NOTE: The :rehash-size and :rehash-threshold parameters are ignored at this time, and no
automatic rehashing is done.
NOTE: For an explanation of keyword arguments, see section 8.2.
(gethash 'g_key 'H_htab [ '(Ldefval ])
RETURNS: two values, first, the value associated with the key g_key in hash table HJltab, or
nil if the key was not in the table, and then a Boolean value to indicate whether
or not there was a match. If (Ldefval is given and there is no entry in the hash
table, then (Ldefval is returned. As is the standard with a multiple-value return,
if only one value is expected, the first is used.
NOTE: set! may be used to set the value associated with a key.
(addhash '(Lkey 'H_htab 'g_val)
RETURNS: gJcey, after installing it with its value g_val to the hash table.
(remhash 'g_key 'H_htab)
RETURNS: t if there was an entry for (Lkey in the hash table lChtab, nil otherwise. In the
case of a match, the entry and associated object are removed from the hash table.
(maphash 'u_fun 'H_htab)
RETURNS: nil.
NOTE: The function uJun is applied to every element in the hash table lChtab. The func-

tion should expect two arguments: the key and value of an element. The mapped
function should not add or delete objects from the table because the results would be
unpredictable. It is, however, acceptable to use remhash or setf of gethash on the
entry currently being mapped over.
(clrhash 'Otab)
RETURNS: the hash table cleared of all entries.
(hash-table-count 'HJltab)
RETURNS: the number of entries in H_htab. Given a hash table with no entries, this function returns zero.

Data Structure Access

; make a vanilla hash table using "eq" to compare items ...
=> (setq black-box (makehash-table :size 20))
#
=> (hash-table-p black-box)
t
=> (hash-table-count black-box)

o
=> (setf (gethash 'any key black-box) '(this list is the value))
anykey
=> (gethash 'anykey black-box)
(this list is the value)
=> (hash-table-count black-box)
1
=> (addhash 'composer black-box 'franz)
composer
=> (gethash 'composer black-box)
franz
=> (maphash '(lambda (key val) (msg "key=" key" ,value=" value N))
black-box)
key=composer,value=franz
key=anykey,value=(this list is the value)
nil

=> (c1rhash black-box)
hash-table[26]
=> (hash-table-count black-box)

o
=> (maphash '(lambda (key val) (msg "key=" key" ,value=" value N))
black-box)
nil

; here is an example using "equal" as the comparator
=> (setq ht (make-hash-table :size 10 :test #'equal))
#
=> (setf (gethash '(this is a key) ht) '(and this is the value))
(this is a key)
=> (gethash '(this is a key) ht)
(and this is the value)
; the reader makes a new list each time you type it ...
=> (setq x '(this is a key))
(this is a key)
=> (setq y '(this is a key))
(this is a key)
; these two lists are really different lists
; they are "equal" but not "eq"
=> (equal x y)
t

=> (eq x y)
nil
; since we are using "equal" to compare keys, we are OK ...
=> (gethash x ht)
(and this is the value)
=> (gethash y ht)
(and this is the value)

2-21

Data Structure Access

2-22

2.6. Arrays

See Chapter 9 for a complete description of arrays. Some of these functions are part
of a Maclisp array compatibility package representing only one simple way of using the
array structure of FRANZ LISP.

2.6~1.

array creation

(marray 'lLdata 's_access 'g_aux 'x_length 'x_delta)

RETURNS: An array type with the fields set up Crom the above arguments whose meanings
are indicated in chapter 9 (see also § 1.2.10).
(*array 's_name 's_type 'x_dim1 ... 'x_dimn)
(array sJlame s_type x_dim1 ... x_dimn)·

WHERE: s_type may be one of t, nil, fixnum, flonum, fixnum-block, or flonum-block.
RETURNS: An array of type s_type with n dimensions of extents given by the x_dimi.
SIDE EFFECT: IT s_name is non nil, the function definition of s_name is set to the array
structure returned.
NOTE: These functions create a Maclisp compatible array. In FRANZ LISP arrays of type t,
nil, fixnum, and flonum are equivalent and the elements of these arrays can be any
type of lisp object. Fixnum-block and flonum-block arrays are restricted to fixnums
and flonums respectively and are used mainly to communicate with foreign Cunctions
(see §8.5).
NOTE: *array evaluates its arguments, array does not.

2.6.2. array predicate

2.6.3. array accessors
(getaccess 'a_array)
(getaux 'a_array)
(getdelta 'a_array)
(getdata 'a_array)
(getlength 'a_array)
RETURNS: The field of the array object a_array given by the function name.

Data Structure Access

2-23

(arrayref 'a_name 'x_ind)
RETURNS:
NOTE:

The x_indth element of the array object a_name. x_ind of zero accesses the first
element.

arrayref uses the data, length, and delta fields of a_name to determine which object
to return.

(arraycall s_type 'as_array 'x_indl ... )
RETURNS:

The element selected by the indices from the array a_array of type s_type.

NOTE: If

as_array is a symbol, then the function binding of this symbol should contain an
array object.
s_type is ignored by arraycall but is included for compatibility with Maclisp.

(arraydims's_name)
RETURNS:

A list of the type and bounds of the array s_name.

(listarray 'sa_array ['x_elements])
RETURNS:

A list of all of the elements in array sa_array. If x_elements is given, then only
the first x_elements are returned.

; This creates a 3 by 4 array of general lisp objects.
=> (array ernie t 94)
array [12]
; The array header is stored in the function definition slot of the
; symbol ernie.

=> (arrayp (getd 'ernie))
t

=> (arraydims (getd 'ernie))
(t 3 4)
; Store in ernie[2][2] the list (test list).
=> (store (ernie 2 2) '(test list))
(test list)
; Check to see if it is there.
=> (ernie 2 2)
(test list)
; Now use the low level function arrayre! to find the same element.
; Arrays are 0 based and row-major (the last SUbscript varies the fastest);
; thus, element [2][2] is the 10th element, starting at O.

=> (arrayre! (getd 'ernie) 10)
(ptr to)(test list)

; The result is a value cell (thus the (ptr to)).

Data Structure Access

2-24

2.0.4. array manipulation
(putaccess 'a_array 'su_func)
(putaux 'a_array 'g_aux)
(putdata 'a_array 'g_arg)
(putdelta 'a_array 'x_delta)
(putlength 'a_array 'xJength)
RETURNS: The second argument to the function.
SIDE EFFECT: The field of the array object given by the function name is replaced by the
second argument to the function.
(store 'l_arexp 's-val)
WHERE: l_arexp is an expression that references an array element.
RETURNS: g_val
SIDE EFFECT: The array location that contains the element that l_arexp references is
changed to contain g.,.val.
(fillarray 's_array 'l_itms)
RETURNS: s_array
SIDE EFFECT: The array s_array is filled with elements from ljtms. If there are not enough
elements in Citms to fill the entire array, then the last element of l_itms is
used to fill the remaining parts of the array.

2.7. Hunks
Hunks are vector-like objects whose size can range from 1 to 128 elements. Internally, hunks are allocated in sizes that are powers of 2. In order to create hunks of a given
size, a hunk with at least that many elements is allocated, and a distinguished symbol
EMPTY is placed in those elements not requested. Most hunk functions respect those distinguished symbols, but there are two (*makhunk and *rplacz) that overwrite the distinguished symbol.

2.7.1. hunk creation
(hunk 's-val1 ['g_val2 ... 's-valn])
RETURNS: A hunk of length n whose elements are initialized to the g_vali.
NOTE: The maximum size of a hunk is 128.
EXAMPLE: (hunk 4. 'Bharp 'keYB) = {4 sharp keys}

Data Structure Access

2-25

(makhunk 'xl_arg)

RETURNS: A hunk of length xCarg initialized to all nils if xl_arg is a fixnum. If xl_arg is a
list, then a hunk of size (length 'zearg) is returned, initialized to the elements in
xl_argo
NOTE: (makhunk '(a b e)) is equivalent to (hunk 'a 'b 'e).
EXAMPLE: (makhunk 4) = {nil nil nil nil}
(*makhunk 'x_arg)

RETURNS: A hunk of size 2x_arg initialized to EMPTY.
NOTE: This is only to be used by such functions as hunk and makhunk, which create and initialize hunks for users.

2.7.2. hunk accessor
(cxr 'x_ind 'h_hunk)

RETURNS: Element x_ind (starting at 0) of hunk h_hunk.
(hunk-to-list 'h_hunk)

RETURNS: A list consisting of the elements of h_hunk.

2.7.3. hunk manipulators
(rplacx 'x_ind 'h_hunk 'g3al)
(*rplacx 'x_ind 'h_hunk 'g_val)

RETURNS:h_hunk
SIDE EFFECT: Element x_ind (starting at 0) of h_hunk is set to g_val.
NOTE: rplaez does not modify one of the distinguished (EMPTY) elements whereas *rplaez
does.
(hunksize 'h_arg)

RETURNS: The size of the hunk h_arg.
EXAMPLE: (hunksize (hunk 1 29)) = 3

2.8. Bcds

A bcd object contains a pointer to compiled code and to the type of function object
the compiled code represents.

Data Structure Access

2-26

(getdisc 'y _bcd)
(getentry 'y_bcd)
RETURNS: The field of the bcd object given by the function name.

(putdisc 'y_func 's_discipline)
RETURNS: s_discipline
SIDE EFFECT:

Sets the discipline field of y_func to s_discipline.

2.9. Structures
There are three common structures constructed out of list cells: the assoc list, the
property list, and the tconc list. The functions below manipulate these structures.

2.9.1. assoc list
An 'assoc list' (or alist) is a common lisp data structure. It has the form
((keyl . valuel) (key2 . value2) (key3 . value3) ... (keyn . valuen))
(assoc 'g_argl 'l_arg2)
(assq 'g_argl 'l_arg2)
(rassq 'g_argl 'l_arg2)
RETURNS: The first top level element of l_arg2 whose ear is equal (with assoe) or eq (with

assq) to !Largl.
NOTE: Usually l_arg2 has an a-list structure and g_argl acts as key.

Rassq is similar to
assq, with the 'r' indicating the reversal that it looks at cdr's instead of car's in
l_arg2.

(sassoc 'g_argl 'l_arg2 'sI3unc)
RETURNS: The result of {eond ({assoe 'g_arg 'Carg2) (apply 'slJune nil)))
NOTE: sassoc is written as a macro.

(sassq 'g_argl 'l_arg2 'sCfunc)
RETURNS: the result of {eond ({assq 'g_arg 'Larg2) (apply 'slJune nil)))
NOTE: sassq is written as a macro.

Data Structure Access

2-27

; aB80e or a88q is given a key and an assoc list and returns
; the key and value item if it exists. They differ only in how they test
; for equality of the keys.

=> {8etq ali8t '{(alpha. a) ( (eomplez key) . b) (junk. z)}}
((alpha. a) ((complex key) . b) (junk. x))
; You should use a88q when the key is an atom;
=> (a88q 'alpha ali8t)
(alpha. a)
; but it may not work when the key is a list.
=> (a8Bq '(eomplez key) aliBt}
nil
; However, a8Boe always works.
=> (a88oe '(eomplez key) ali8t)
((complex key) . b)

(sublis 'l_alst 'l_exp)

l_alst is an a-list.
RETURNS: The list l_exp with every occurren~e of keyi replaced by vali.
NOTE: A new list structure is returned to prevent modification of l_exp. When a substitution is made, a copy of the value to substitute in, is not made.
WHERE:

2.9.2. property list

A property list consists of an alternating sequence of keys and values. Normally a
property list is stored on a symbol. A list is a 'disembodied' property list if it contains
an odd number of elements, the first of which is ignored.
(plist 's_name)
(symbol-plist 's_name)

The property list of s_name.
NOTE: Symbol-pla'st is the Common Lisp name for this function.

RETURNS:

(setplist 's_atm 'l-plist)

l-plist.
SIDE EFFECT: the property list of s_atm is set to l-plist.

RETURNS:

Data Structure Access

2-28

(get 'Is_name 'g_ind)
RETURNS: The value under indicator g_ind in ls_name's property list if ISJlame is a symbol.
there is no indicator g_ind in ls_name's property list, nil is returned. If Is_name is
a list of an odd number of elements, then it is a disembodied property list. get
searches a disembodied property list by starting at its cdr and comparing every other
element with !Lind, using eq.

NOTE: If

(getl 'Is_name 'I_indicators)
The property list Is_name beginning at the first indicator that is a member of the
list Cindicators, or nil, if none of the indicators in I_indicators are on ls_name's
property list.
NOTE: If Is_name is a list, then it is assumed to be a disembodied property list.

RETURNS:

(putprop 'Is_name 'g_val 'g_ind)
(defprop ISJlame !Lval gjnd)
RETURNS: g_val.
SIDE EFFECT: Adds to the property list of Is_name the value g_val under the indicator
gjnd.
NOTE:

putprop evaluates its arguments; de/prop does not. Is_name may be a disembodied
property list. See get.

(remprop 'Is_name 'g_ind)
The portion of ISJlame's property list beginning with the property under the
indicator gjnd. If there is no !Lind indicator in ISJlame's plist, nil is returned.
SIDE EFFECT: The value under indicator g_ind and g_ind itself is removed from the property list of Is_name.
NOTE: Is_name may be a disembodied property list. See get.

RETURNS:

=>

(pu'prop ':dl.l'e

'1.1

'o/phl.l)

a

=>

(pu'prop '~ll.l'e 'b 'betl.l)

b

=>

(pliB' '~/I.I'e)

(alpha a beta b)

=>

(get

'~/l.Ite

'1.Ilphl.l)

a
; You can use a disembodied property list this way:

=>
kls

(get '(nilll.l'eml.ln rjl Bklower klB loderl.lro jkl) 'Bklower)

Data Structure Access

2-29

2.9.3. tconc structure
A tconc structure is a special type of list, designed to make it easy to add objects
to the end. It consists of a list cell whose ear points to a list of the elements added
with teone or leone and whose edr points to the last list cell of the list pointed to by
the ear.
(tconc 'l-ptr 'g_x)
WHERE:

l-ptr is a tconc structure.

RETURNS:

l-ptr with g...x added to the end.

(lconc 'l-ptr 'I_x)
WHERE:

l-ptr is a tconc structure.

RETURNS:

l-ptr with the list l...x spliced in at the end.

; A leone structure can be initialized in two ways.
; Nil can be given to leone, in which case leone generates
; a leone structure.

=>(8elg /00

(leone nUl))

((1) 1)
; Since teone destructively adds to
; the list, you can now add to roo without using Betg again.
=>(teone /00 e)

((1 2) 2)

=>100
((1 2) 2)
; Another way to create a null teone structure
; is to use (neons nil).
=>(setg /00 (neonB nil))
(nil)
=> (teone /00 1)

((1) 1)
; Now see what leotle can do:
=> (leone /00 nil) .
((1) 1)
;There is no change.
=> (leone /00 '(e!J 4))
((1 2 3 4) 4)

2.9.4. fclosures
An fclosure is a functional object that admits some data manipulations. They are
discussed in §8.4. Internally, they are constructed from vectors.

Data Structure Access

2-30

(fclosure 'l_vars 'g_funobj)
WHERE: l_vars is a list of variables; g_funobj is any object that can be funcalled (including, fclosures).
RETURNS: A vector that is the fclosure.

(fclosure-alist 'v_fclosure)
RETURNS: An association list representing the variables in the fclosure. This is a snapshot of

the current state of the fclosure. If the bindings in the fclosure are changed, any
previously calculated results of !closure-alist do not change.

(fclosure-function 'v_fclosure)
RETURNS: The functional object part of the fclosure.
(fclosurep 'v_fclosure)
RETURNS: t if the argument is an fclosure.

(fclosure-list 'Cvarsl 'g_fcnobjl [...... J)
RETURNS: a list of fclosures where variables with the same name are shared between fclo-

sures.
NOTE: !closure-list creates a set of fclosures which share variables. If you create fclosures

with the !closure function, they will not share closed-over variables. The following
example shows the difference between !closure-list and a pair of !closure calls.

Data Structure Access

; intialize x and then make two closures over it
=> (setq x 10)
10
=> (setq cIa (fclosure '(x) '(lambda (y) (setq x y))))
#
; This fclosure will have the same initial value as the one above but
; it will not share the value of x
=> (setq c1b (fclosure '(x) '(lambda 0 (print x))))
#
; To demonstrate that the closures don't share the value of x
; we call the first closure function:
=> (funcall cla 20)
(funcall cla 20)
20
; and then see that the value of the second has not been affected:
=> (funcall cIb)
10nil
; now we create two closures with fclosure-list
; since both closures are over x, the value of x will be shared
=> (setq clc (fclosure-list '(x) '(lambda (y) (setq x y))
'(x) '(lambda 0 (print x))))
(# # (fun call (car dc) 15)
15
; ... and then call the second one to print the value of x
=> (run call (cadr cIe))
15nil

=>

(symeval-in-fclosure 'v_fclosure 's_symbol)
RETURNS:

The current binding of a particular symbol in an fclosure.

(set-in-fclosure 'v_fclosure 's_symbol 'g_newvalue)
RETURNS: g_newvalue.
SIDE EFFECT:

The variable s_symbol is bound in the fclosure to g_newvalue.

2.10. Random functions
The following functions do not fall into any of the classifications above.

2-31

Data Structure Access

2-32

(bcdad 's_funcname)
RETURNS: A fixnum that is the address in memory where the function s_funcname begins. If
sJuncname is not a machine coded function (binary), then bcdad returns nil.
(copy'g_arg)
RETURNS:

A structure equal to g_arg but with new list cells.

(copyint* 'x_arg)
RETURNS:

A fixnum with the same value as x_arg but in a freshly allocated cell.

(cpyl 'xvt_arg)
RETURNS: A new cell of the same type as xvt_arg with the same value as xvt_arg.
(getaddress

'S_en~ryl 's_~~)lrl 'st_disciplinel [.........J)

RETURNS:
NOTE:

The binary object that s_binderl's function field is set to.

This looks in the running lisp's symbol table for a symbol with the same name as
s_entryi. It then creates a binary object whose entry field points to s_entryi and
whose discipline is st_disciplinei. This binary object is stored in the function field of
s_binderi. If st_disciplinei is nil, then "subroutine" is used by default. This is especially useful for cfa81 users.

(macroexpand's-form)
RETURNS: gJorm after all macros in it are expanded.
NOTE: This function only macroexpands expressions that could be evaluated, and it does not
know about the special nlambdas such as cond and do; thus, it misses many macro
expansions.
(ptr 'g_arg)
RETURNS:

A value cell initialized to point to Larg.

(quote g_arg)
g_arg.
NOTE: The reader allows you to abbreviate (quote foo) as 'foo.

RETURNS:

(kwote 'g_arg)
RETURNS:

{lid (quote quote) g_arg).

(replace 'Largl 'g_arg2)
WHERE: g_argl and s-arg2 must be the same type of lispval and not symbols or hunks.
RETURNS: g_arg2.
SIDE EFFECT: The effect of replace dependents on the type of the g_argi, although you may
notice a similarity in the effects. To understand what replac e does to fixnum
and flonum arguments, you must first understand that such numbers are
'boxed' in FRANZ LISP. This means that if the symbol x has a value 32412,
then, in memory, the value element of x's symbol structure contains the
address of another word of memory (called a box) with 32412 in it.
Thus, there are two ways of changing the value of x. The first way is to
change the value element of x's symbol structure to point to a word of
memory with a different value. The second way is to change the value in the

Data Structure Access

2-33

box that x points to. The former method is used almost all of the time; the
latter is used very rarely and may cause great confusion. The function
replace allows you to do the latter, i.e., to actually change the value in the
box.
You should watch out for these situations. If you do (8etq y x), then both x
and y point to the same box. If you now (replace x 12945), then y also has
the value 12345. And, in fact, there may be many other pointers to that box.
Another problem with replacing fixnums is that some boxes are read-only.
The fixnums between -1024 and 1023 are stored in a read-only area and
attempts to replace them result in an "Illegal memory reference" error. See
the description of copyint* for a way around this problem.
For the other valid types, the effect of replace is easy to understand. The
fields of g_vall's structure are made eq to the corresponding fields of g_vaI2's
structure. For example, if x and y have lists as values then the effect of
(replace x y) is the same as {rplaca x (car y)) and {rplacd x (cdr y)).
(scons 'x_arg 'bs_rest)
bs_rest is a bignum or nil.
RETURNS: A bignum whose first bigit (digit in the bignum base) is x_arg and whose higher
order bigits are bs_rest.
WHERE:

(setf ~refexpr 'g_value)
NOTE: 8et! is a generalization of setq. Information may be stored by binding variables,
replacing entries of arrays, and vectors, or by being put on property lists, among others. Setf allows you to store data into some location by mentioning the operation
used to refer to the location. Thus, the first argument may be partially evaluated,
but only to the extent needed to calculate a reference. 8et! returns g_value. (Compare to de8etq )

(setf x 3)
= (setq x 3)
(setf (car x) 3) = (rplaca x 3)
(setf (get faa 'bar) 3) = (putprop faa 3 'bar)
(setf (v ref vector index) value) = (vset vector index value)

(sort 'Cdata 'u_comparefn)
RETURNS: A list of the elements of I_data ordered by the comparison function u30mparefn.
SIDE EFFECT:

The list I_data is modified rather than allocated in new storage.

should return something non-nil, if g_x can precede g.s in
sorted order; nil, if g.s must precede g_x. If u_comparefn is nil, alphabetical order is
used.

NOTE: (compare!n 'g_x 'g_y)

Data Structure Access

2-34

(sortcar 'I_list 'u_comparefn)
RETURNS: A list of the elements of I_list with the car's ordered by the sort function
u_comparefn.
SIDE EFFECT:

The list I_list is modified rather than copied.

NOTE: Like sort, if u_comparefn is nil, alphabetical order is used.

CHAPTER 3
Arithmetic and Logical Functions

This chapter describes FRANZ LISP's functions for manipulation of numeric quantities.
Often the same function is known by several names for the sake of compatibility with several lisp
dialects. For example, add is also plus and sum. However, you should avoid using functions with
names such as + and * in this version of FRANZ LISP unless their arguments are fixnums. The +
function in Common Lisp has been defined to allow mixed mode arguments (an incompatibility
with pre-existing lisps such as FRANZ LISP) and corresponds to the FRANZ LISP function plus. The
mapping of + to plus (etc.) may be easily achieved via the package system for Common Lisp compatibility. Note that FRANZ LISP compiler can take advantage of implicit declarations.
An attempt to divide or to generate a floating point result outside of the range of floating
point numbers causes a floating exception signal from the operating system. You can catch and
process this interrupt if desired. See the description of the signal function.

3.1. Simple Arithmetic Functions
(add ['n_argl ... J)
(plus ['n_argl ... J)
(sum ['n_argl ...J)
(+ ['x_argl ... J)
RETURNS: The sum of the arguments. If no arguments are given, 0 is returned.
NOTE: If the size of the partial sum exceeds the limit of a fixnum, the partial sum is converted to a bignum. If any of the arguments are flonums, the partial sum is converted to a flonum when that argument is processed and the result is thus a flonum.
Currently, if, in the process of doing the addition, a bignum must be converted into a
flonum, an error message results.
(addl 'n_arg)

(1+ 'x_arg)
RETURNS: Its argument plus 1.

(diff ['n_argl ... ])
(difference ['n_argl ... ])
(- ['x_argl ... ])
RETURNS: The result of subtracting from n_argl all subsequent arguments. If no arguments
are given, 0 is returned.
NOTE: See the description of add for details on data type conversions and restrictions.

Arithmetic and Logical Functions

3-1

Arithmetic and Logical Functions

3-2

(sub1 'n_arg)
(1- 'x_arg)
RETURNS:

Its argument minus 1.

(minus 'n_arg)
RETURNS:

Zero minus n_arg.

(product ['n_argl ... ])
(times ['n_argl ... ])
(* ['x_argl ... ])
The product of all of its arguments. It returns I if there are no arguments.
NOTE: See the description of the function add for details and restrictions to the automatic
data type coercion.

RETURNS:

(quotient ['n_argl ... J)

(f ['x_argl ... J)
The result of dividing the first argument by succeeding ones.
there are no arguments, I is returned. See the description of the function add for
the details and restrictions of data type coercion. A divide by zero causes a floating
exception interrupt. See the description of the aignal function.

RETURNS:
NOTE: If

(*quo 'i..x 'i.s)
RETURNS: The integer part of i_x / i.s.
(Divide 'i_dividend 'i_divisor)
RETURNS: A list whose car is the quotient and whose cadr is the remainder of the division of
i_dividend by i_divisor.
NOTE: This is restricted to integer division.
(Emuldiv 'x_facti 'x_fact2 'x_addn 'x_divisor)
RETURNS: A
list
of
the
quotient
and
remainder
of
«x_facti * x_fact2) + (sign extended) x_addn) / x_divisor.
NOTE: This is useful for creating a bignum arithmetic package in Lisp.

this

operation:

(*invmod 'xJlumber 'x_modulus)
RETURNS: This function returns the inverse of x_number in the finite field of the integers
modulo the odd prime x_modulus. The result is expressed as a positive or negative
fixnum of magnitude less than x_modulus/2.
NOTE: This is useful in algebraic manipUlation and number theory calculations.

3.2. predicates
(numberp 'g_arg)
(numbp 'g_arg)
RETURNS: t iff

~arg

is a number: fixnum, flonum, or bignum.

Arithmetic and Logical Functions

3-3

(fixp '~arg)
RETURNS:

t iff ~arg is a fixnum or bignum.

(floatp 'g_arg)
RETURNS:

t iff ~arg is a flonum.

(evenp 'x_arg)
RETURNS:

t iff x_arg is even.

(oddp 'x_arg)
RETURNS:

t iff x_arg is odd.

(zerop 'g_arg)
RETURNS:

t iff ~arg is a number equal to

o.

(onep 'g_arg)
RETURNS:

t iff g_arg is a number equal to 1.

(plusp 'n_arg)
RETURNS:

t iff n_arg is greater than zero.

(minusp 'g_arg)
RETURNS:

t iff ~arg is a negative number.

(greaterp ['n_argl ... J)
(> 'fx_argl 'fx_arg2)
(>& 'x_argl 'x_arg2)
t iff the arguments are in a strictly decreasing order.
NOTE: In the functions greaterp and >, the function ds"fference is used to compare adjacent
values. If any of the argum~nts are non-numbers, the error message comes from the
difference function. The arguments to > must be fixnums or both flonums. The
arguments to > f! must both be fixnums.

RETURNS:

(lessp ['n_argl ... J)
'fx_argl 'fx_arg2)
'x_argl 'x_arg2)

«

«&

t iff the arguments are in a strictly increasing order.
In functions Ie ssp and < the function difference is used to compare adjacent values.
If any of the arguments are non numbers, the error message comes from the
difference function. The arguments to < may be either fixnums or flonums but must
be the same type. The arguments to < f! must be fixnums.

RETURNS:
NOTE:

Arithmetic and Logical Functions

3-4

(= 'fx_argl 'fx_arg2)
(=& 'x_argl 'x_arg2)
RETURNS:

t iff the arguments have the same value. The arguments to = must be the either
both fixnums or both flonums. The arguments to =& must be fixnums.

(primep 'x_arg)
RETURNS: t iff x_arg is a prime integer in the range of fixnums.
NOTE:

This is intended to be fast and convenient for, for example, hash-table construction.

3.3. Trignometric Functions
Some of these functions are taken from the host math library, and therefore have the
same accuracy and other performance characteristics.
(cos 'fx_angle)
RETURNS:

The (flonum) cosine of fx_angle (which is assumed to be in radians).

(sin 'fx_angle)
RETURNS:

The sine of fx_angle (which is assumed to be in radians).

(aeos 'fx_arg)
RETURNS:

The (flonum) arc cosine of fx_arg in the range 0 to

11".

(asin 'fx_arg)
RETURNS:

The (flonum) arc sine of fx_arg in the range -11"/2 to 11"/2.

(atan 'fx_argl 'fx_arg2)
RETURNS: The (flonum) arc tangent of fx_argl/fx_arg2 in the range

-11"

to

11".

3.4. Bignum/Fixnum Manipulation
(haipart bx_number x_bits)
RETURNS: A fixnum (or bignum) that contains the x_bits high bits of (abs bx_number) if
x_bits is positive; otherwise, it returns the (abs x_bits) low bits of
(abs bx_number).
(haulong 'bx_number)
(integer-length 'bx_number)
RETURNS: The number of significant bits in bx_number.
NOTE: The result is equal to the least integer greater than or equal to the base two logarithm of one plus the absolute value of bx_number. Common Lisp's integer-length
differs from haulong in that if the argument is negative, the result is equal to the
least integer greater than or equal to the base two logarithm of the absolute value of
bx_number.

Arithmetic and Logical Functions

3-5

(bignum-Ieftshift bx_arg x_amount)
RETURNS: bx_arg shifted left by x_amount. If x_amount is negative, bx_arg is shifted right
by the magnitude of x_amount.
NOTE: If bx_arg is shifted right, it will be rounded to the nearest even number.

(sticky-bignum-Ieftshift 'bx_arg 'x_amount)
RETURNS: bx_arg shifted left by x_amount. If x_amount is negative, bx_arg will be shifted
right by the magnitude of x_amount and rounded.
NOTE: Sticky rounding is done this way: after shifting, the low order bit is changed to I

if

any I's were shifted off to the right.

3.5. Bit Manipulation
In this section numerous functions based on the boole function are defined for Common Lisp compatibility. Many are merely macro-expanded into calls to boole, and in the
current implementation are restricted to fixnum-Iength integers.

(boo Ie 'x_key 'x_vI 'x_v2 ... )
RETURNS: The result of the bitwise boolean operation as described in the following table.
NOTE: If there are more than 3 arguments, then evaluation proceeds left to right with each

partial result becoming the new value of x_vI. That is,
(boole 'key 'vi 'v2 'v9) = (boole 'key (boole 'key 'vi 'v2) 'v9).
In the following table, * represents bitwise and + represents bitwise, or E9 represents
bitwise xor and -, represents bitwise negation and is the highest precedence operator.
(boole 'key 'x 'y)
key
result

0
0

common
names

key
result
common
names

1

2

3

4

5

x*y

-,x*y

y

x*-,y

x

and

8
-, (x + y)

9
-,(x@y)

nor

equiv

bitc\ear

10
-,x

11
-,x+y

implies

6
x@y

7
x+y

xor

or

15
-1

12

13

14

-,y

x + -, Y

-,x+-'y
nand

Arithmetic and Logical Functions

3-6

(Ish 'x_val 'x_amt)
(ash 'x_val 'x_amt)
RETURNS: x_val shifted left by x_amt if x_amt is positive. If x_amt is negative, then Ish
returns x_val shifted right by the magnitude if x_amt.
NOTE: This always returns a fixnum even for those numbers whose magnitude is so large

that they would normally be represented as a bignum; i.e., shifter bits are lost. Functionally "arithmetic shift" ash, is the same as Ish. For more general bit shifters, see
bignum-Ieftshift and sticky-bignum-Ieftshift.
(rot 'x_val 'x_amt)
RETURNS: x_val rotated left by x_amt if x_amt is positive. If x_amt is negative, then x_val
is rotated right by the magnitude of x_amt.
(Iogand ['n_argl ... J)
RETURNS: the (numeric) result of the bitwise logical and of the n_argi's.
NOTE: If there are no arguments, -1 is returned.
(Iogior ['n_argl ... J)
RETURNS: the (numeric) result of the bitwise logical inclusive or of the n_argi's.
NOTE: If there are no arguments, zero is returned.
(Iogxor ['n_argl ...J)
RETURNS: the (numeric) result of the bitwise logical exclusive or of the n_argi's.
NOTE: If there are no arguments, zero is returned.
(Iogeqv ['n_argl ... J)
RETURNS: the (numeric) result of the bitwise logical equivalence of the n_argi's.
NOTE: If there are no arguments, -1 is returned. Equivalence is the same as exclu8ive nor.
(Iognot 'n_arg)
RETURNS: the (numeric) result of the bitwise logical not of n_arg. (The logical complement

of n_arg).
Additional Common Lisp logical operators which require exactly two fixnum arguments are as follow:
(logandcl 'n_argl 'n_arg2)
RETURNS: (logand (Iognot n_argl) n_arg2)

(logandc2 'n_argl 'n_arg2)
RETURNS: (logand n_argl (lognot n_arg2))

Arithmetic and Logical Functions

3-7

(logbitp 'x_index 'n_number)
RETURNS: t if the bit in n_number with index indexis
(logcount 'n_number)
RETURNS: the number of one bits in n_number if n_number is positive; the number of zero

bits if n_number is negative.
(Iogiorcl 'n_argl 'n_arg2)
RETURNS: (logior (lognot n_argl) n_arg2)

(logiorc2 'n_argl 'n_arg2)
RETURNS: (logior n_argl (lognot n_arg2))

(lognand 'n_argl 'n_arg2)
RETURNS: (lognot (logand n_argl n_arg2))

(lognor 'n_argl 'n_arg2)
RETURNS: (lognot (Iogor n_argl n_arg2))

(logtest 'n_argl 'n_arg2)
RETURNS: (not (zerop (Iogand n_argl n_arg2)))
NOTE: Logtest is true if anyone's are in corresponding locations in the two arguments.

3.6. Other Functions
As noted above, some of the following functions are inherited from the host math
library.

(abs 'n_arg)
(absval 'n_arg)
RETURNS: The absolute value of n_arg.

(exp 'fx_arg)
RETURNS: e raised to the fx_arg power (Bonum).

(expt 'n_base 'n_power)
RETURNS: n_base raised to the n.J>ower power.
NOTE: If either of the arguments are Bonums, the calculation is done using log and expo

Arithmetic and Logical Functions

3-8

(fact 'x_arg)
RETURNS: x_arg factorial -- fixnum or bignum.

(fix 'n_arg)
RETURNS: A fixnum as close as we can get to n_arg.
NOTE:

fix rounds down. Currently, if n_arg is a Honum larger than the size of a fixnum, this
fails.

(float 'n_arg)
RETURNS: A Honum as close as we can get to n_arg.
NOTE: If n_arg is a bignum larger than the maximum size of a Honum, then a Hoating excep-

tion occurs.
(log 'fx_arg)
RETURNS: The natural logarithm of fx_arg.

(max 'n_argl ... )
RETURNS: The maximum value in the list of arguments.
(min 'n_argl ... )
RETURNS: The minimum value in the list of arguments.
(mod 'i_dividend 'i_divisor)
(remainder 'i_dividend 'i_divisor)
RETURNS: The remainder when i_dividend is divided by i_divisor.
NOTE: The sign of the result has the same sign as i_dividend.

(*mod 'x_dividend 'x_divisor)
RETURNS: The balanced representation of x_dividend modulo x_divisor.
NOTE: The range of the balanced representation is abs(x_divisor}/2 to (abs(x_divisor}/2) -

x_divisor

+ 1.

(random ['x_limit])
RETURNS: A fixnum between 0 and x_limit - 1 if x_limit is given. If xJimit is not given,
any fixnum, positive or negative, might be returned.
(sqrt 'fx_arg)
RETURNS: The square root of fx_arg.

CHAPTER 4
Special Functions

4.1. Introduction

This chapter describes the special functions, or forms of FRANZ LISP. While Lisp is
generally thought of as very simple, in fact serious programming in Lisp uses a large helping of these special forms. What makes them special is that they generally do not conform
to the usual function evaluation methodology.

4.2. Functions
(and [g_argl ... J)

RETURNS: The value of the last argument if all arguments evaluate to a non-nil value; otherwise, and returns nil. It returns t if there are no arguments.
NOTE: The arguments are evaluated left to right and evaluation ceases with the first nil
encountered.
(apply 'u_func ['g_argl ... J 'l_args)

RETURNS: The result of applying function u_func to the arguments contained in the list
Cargs.
NOTE: If ujunc is a lambda, then the length of Larg8 should equal the number of formal
parameters for the u_func. If u_func is a nlambda or macro, then l_args is bound to
the single formal parameter.
For application of a lambda (or lexpr), apply will take the optional g_arg's and just
push them on the stack (like funcall). The LAST argument, Larg8 should be a list
which will be spread on the stack. This version of apply (Opus 42.03 and later) is
upward compatible with Common Lisp. If the argument is a nlambda or macro, it
still must be given only one argument.

Special Functions

4-1

Special Functions

4-2

; add1 is a lambda of ! argument
(apply 'add1 '(9))

=>
4

; You can define plus1 as a macro that is equivalent to
add1.
=> (deJ plus1 (maero (arg) (list 'add1 (cadr arg))))
plus!
=> (plus19)
4
; Now if you apply a macro, you obtain the form it changes to.
(apply 'plus1 '(plus1 9))
(add! 3)

=>

; If you Juneall a macro ,however, the result
of the macro is eualed
; before it is returned.
=> (Juneall 'plus1 '(plusl 9))
4
; For this particular macro, the ear of the arg is not checked
; so that this too works.
=> (apply 'plus1 '(foo 9))
(add! 3)

(apropos 'st_arg)
RETURNS: nil
NOTE: All packages are searched for symbols whose print name contains the substring

st_arg. Matching symbols are printed, along with information about their function
definition and current value.
(apropos-list'st_arg)
RETURNS: a list of symbols which is the result of seaching all packages for symbols which
have a print name containing the substring st_arg.
(arg ['x_numb])
RETURNS: If x_numb is specified, then the x_numb'th argument to the enclosing lexpr. If
x_numb is not specified, then this returns the number of arguments to the enclosing lexpr.
NOTE: It is an error to the interpreter if x_numb is given and out of range.

Special Functions

4-3

(break [g_message ['g,..pred]])
WHERE: If g_message is not given, it is assumed to be the null string, and if g,..pred is not
given, it is assumed to be t.
RETURNS:

The value of (*brcak 'g-prcd 'g_mc88agc)

(*break 'g,..pred 'g_message)
RETURNS: nil immediately if g,..pred is nil; otherwise, the value of the next (return 'value)
expression typed in at top level.
SIDE EFFECT:

If the predicate, g,..pred, evaluates to non-null, the Lisp system stops and
prints out 'Break ' followed by g_message. It then enters a break loop that
allows you to interactively debug a program. To continue execution from a
break, you can use the return function. To return to top level or another
break level, you can use ~pop or rcsct.

(caseq 'g_key-form 13lausel ... )
(case 'g_key-form l_clausel ... )
WHERE:
NOTE:

Cclausei is a list of the form (g_comparator ['lLformi ... J). The comparators may
be symbols, small fixnums, a list of small fixnums or symbols.

The way caseq works is that it evaluates g_key-form, yielding a value called the
selector. Each clause is examined until the selector is found consistent with the comparator. For a symbol, or a fixnum, this means the two must be cq. For a list, this
means that the selector must be cq to some element of the list.
The comparator consisting of the symbol t has special semantics: it matches anything
and, consequently, should be the last c.omparator.
In any case, having chosen a clause,
returns the value of the last form

RETURNS:

C4SCq

evaluates each form within that clause and

The value of the last form as indicated above. If no comparators are matched,
cascq returns nil.

Here are two ways of defining the same function:

== > (defun fate (personna)
{caseq personna
{cow '(jumped over the moon))
(cat '(played nero))
({dish Bpoon) '(ran away with each other))
{t '(lived happily ever after))))
fate
=>{defun fate (personna)
{cond
({eq personna 'cow) '(jumped over the moon))
((eq personna 'cat) '(played nero))
{(memq personna '(dish spoon)) '(ran away with each other))
{t '(lived happily ever after))))
fate

Special Functions

4-4

(cateh g_exp [Is_tag])
WHERE:

If Is_tag is not given, it is assumed to be nil.

RETURNS: The result of (*catch 'Is_tag g_exp)
NOTE: Catch is defined as a macro.

("'cateh 'Is_tag g_exp)
WHERE:

Is_tag is either a symbol or a list of symbols.

RETURNS: The result of evaluating g_exp or, if the 'throw' pseudo-function is invoked with

the argument Is_tag within the execution of g3XP, the value given by throw. (see
throw, *throw) The *catch and throw or *throw construction is used for a nonlocal return of a value, and is typically used in an error return or some kind of
break in the normal modularization of a program.
SIDE EFFECT:

This proceeds as follows: *catch first sets up a 'catch frame' on the Lisp runtime stack. Then it begins to evaluate g_exp. If g_exp evaluates normally,
its value is returned. If, however, a value is thrown during the evaluation of
g_exp, then this *catch returns with that value if one of these cases is true:

(1)

The tag thrown to is Is_tag.

(2)

Is_tag is a list and the tag thrown to is a member of this list.

(3)

Is_tag is nil.

NOTE: Errors are implemented as a special kind of throw. A catch with no tag does not

catch an error, but a catch whose tag is the error type catches that type of error. See
Chapter 10 for more information.
(comment [Larg ... ])
RETURNS: The symbol comment.
NOTE: This does nothing but return a constant value. You should be caution to avoid using

this in a place where the value might be used.
(cond [13lausel ... J)
(w hen pred formi ... )
(unless pred formi ... )
(if pred formi [form2])
RETURNS: The last value evaluated in the first satisfied clause. If no clauses are satisfied,
then nil is returned.
NOTE: Cond is the basic conditional 'statement' in Lisp. The clauses are processed from left
to right. The first element of a clause is evaluated. If it evaluates to a non-null

value, then that clause is satisfied and all following elements of that clause are
evaluated. The last value computed is returned as the value of the condo If there is
just one element in the clause, then its value is returned. If the first element of a
clause evaluates to nil, then the other elements of that clause are not evaluated and
the system moves to the next clause. The forms when, unless, and if are expanded
into cond '8 as follows:
(when p a b ... ) = (cond (p a b ... ))
(unless p a b ... ) = (cond ((not p) a b ... ))
(if p a b) = {cond (p a) (t b))

Special Functions

4-5

(cvttointlisp)
SIDE EFFECT: The reader is modified to conform with the Interlisp syntax. The character
% is made the escape character and special meanings for comma, backquote,
and backslash are removed. Also the reader is told to convert upper case to
lower case.
( cvttofranzlisp)
SIDE EFFECT: FRANZ LISP's default syntax is reinstated. You should run this function after
having run any of the other cvtto- functions. Backslash is made the escape
character, super-brackets work again, and the reader distinguishes between
upper and lower case.
( cvttomaclisp )
SIDE EFFECT: The reader is modified to conform with Maclisp syntax. The character / is
made the escape character, and the special meanings for backslash, left and
right bracket are removed. The reader is made case-insensitive.
( cvttoucilisp )
SIDE EFFECT: The reader is modified to conform with DCI Lisp syntax. The character / is
made the escape character; tilde is made the comment character; exclamation
point takes on the unquote function normally held by comma, and backslash,
comma, and semicolon become normal characters. Here too, the reader is
made case-insensitive.
(debug s_msg)
SIDE EFFECT: Enter the Fixit package described in Chapter 15. This package allows you to
examine the evaluation stack in detail. To leave the Fixit package type 'ok'.
(debugging 'g_arg)
SIDE EFFECT: If g_arg is non-null, FRANZ LISP unlinks the transfer tables, does a (*rset t)
to turn on evaluation monitoring and sets the all-error catcher (ER%all) to
be debug-err-handler. If g_arg is nil, all of the earlier changes are undone.
(declare [g_arg ... J)
RETURNS: nil
NOTE: This is a no-op to the evaluator. It has special meaning to the compiler (see Chapter
12).
(def s_name (s_type l_argl g_expl ... ))
WHERE:

s_type is one of lambda, nlambda, macro or lexpr.

RETURNS: s_name
SIDE EFFECT: This defines the function s_name to the Lisp system. If s_type is nlambda or
macro then the argument list l_argl must contain exactly one non-nil symbol.

Special Functions

4-6

(defmacro s_name l_arg g_expl ... )
(defcmacro s_name Carg g_expl ... )

RETURNS: s.Jlame
SIDE EFFECT: This defines the macro s_name. de/macro makes it easy to write macros since
it makes the syntax just like de/un. Further information on de/macro is in
§8.3.2. de/cmacro defines compiler-only macros, or cmacros. A cmacro is
stored on the property list of a symbol under the indicator cmacro. Thus a
function can have a normal definition and a cmacro definition. For an example of the use of cmacros, you can examine the definitions of nthcdr and nth
in /lisp/lib/common2.l
(defsubst s_name l_llist g_form [ ... ])
RETURNS: s_name.

NOTE: defsubst is like defun (below), except that a compiler macro is defined (see defcmacro
above) which expands to the definition of s_name as a lambda. It's use is to allow an
easy method of defining functions which are to be macro expanded out at compile
time. Note, also, that the & lambda list parameters, which are valid to defun, are
not to defsubst.
(defun s_name [s_mtype]ls_argl ~expl ... )
WHERE: s_mtype is one of fexpr, expr, args or macro.

RETURNS: s.Jlame
SIDE EFFECT: This defines the function s_name.
NOTE: Some of these options exist for Maclisp compatibility. Defun rearranging the informa,tion you provide and then invokes the 'def' procedure. For example, the MacLisp
'fexpr' is automatically converted to a FRANz LISP nlambda. A MacLisp s_mtype of
expr is simply the same thing as FRANZ LISP's lambda. The s_type of macro exists in
the same form. If ls_argl is a non-nil symbol, then the type is assumed to be lexpr
and ls_argl is the symbol that is bound to the number of args when the function is
entered.
For compatibility with the Lisp Machine Lisp, there are four types of optional parameters that can occur in ls_argl: i!Joptional, i!Jrest, i!Jauz and i!Jkey. For an explanation
of use of these forms, see section 8.2.
An additional form accepted by defun is provided to set up property lists. To place
the value ~value on the property list of symbol s_name under indicator sjnd, use
the form
(defun (s.Jlame sjnd) ~value)

Special Functions

4-7

; de/ and de/un here are used to define identical
functions.
; You can decide for yourself which is easier to use.
=> (de/ appendl (lambda (liB extra) (append lie (liet extra))))
appendl

=> (de/un appendl (lie extra) (append liB (list extra)))
appendl
; Using the & forms ...
=> (de/un test (a b &optional c &aux (retval 0) &reet z)
(i/ c them (msg "Optional arg present" N

"c is" eN))
(meg "rest is" z N
"retval is " ret val N))
test

=> (teBt 1 284)
Optional arg present
cis 3
rest is (4)
retval is 0

(defvar s_variable ['g_init])
RETURNS: s_variable.
NOTE: This form is put at the top level in files, like de/un.
SIDE EFFECT:

This declares s_variable to be special. If g_init is present and s_variable is
unbound when the file is read in, s_variable is set to the value of g_init. An
advantage of '(defvar foo)' over '(declare (special foo))' is that if a file containing defvars is loaded (or fasl'ed) in during compilation, the variables mentioned in the defvar's are declared special. The only way to have that effect
with '(declare (special foo))' is to include the file.

(do l_vrbs I_test g_expl ... )
RETURNS: The last form in the cdr of Ctest evaluated, or a value explicitly given by a

return evaluated within the do body.
NOTE: This is the basic iteration form for FRANZ LISP. l_vrbs is a list of zero or more var-

init-repeat forms. A var-init-repeat form looks like:
(s_name [g_init [!LrepeatlJ)
There are three cases depending on what is present in the form. If just s_name is
present, this means that when the do is entered, s_name is lambda-bound to nil and
is never modified by the system (though the program is certainly free to modify its
value). If the form is (s_name 'g_init) then the only difference is that s_name is
lambda-bound to the value of g_init instead of niL If !Lrepeat is also present then
s_name is lambda-bound to g_init when the loop is entered and after each pass
through the do body s_name is bound to the value of g_repeat.
I_test is either nil or has the form of a cond clause. If it is nil then the do body is
evaluated only once and the do returns nil. Otherwise, before the do body is
evaluated the car of I_test is evaluated, and, if the result is non-null, this signals an
end to the looping. Then the rest of the forms in I_test are evaluated and the value
of the last one is returned as the value of the do. If the cdr of I_test is nil, then nil is
returned. Thus, this is not exactly like a cond clause.

Special Functions

4-8

tLexp1 and those forms that follow constitute the do body. A do body is like a prog
body and, thus, may have labels. You can use the functions go and return.
The sequence of evaluations is this:
(1)

The init forms are evaluated left to right and stored in temporary locations.

(2)

Simultaneously, all do variables are lambda bound to the value of their init forms or
to nil.
If I_test is non-null, then the car is evaluated, and, if it is non-null, the rest of the
forms in I_test are evaluated, and the last value is returned as the value of the do.

(3)
(4)
(5)
(6)
(7)

The forms in the do body are evaluated left to right.
If I_test is nil the do function returns with the value nil.
The repeat forms are evaluated and saved in temporary locations.
The variables with repeat forms are simultaneously bound to the values of those
forms.

(8)

Go to step 3.
NOTE: There is an alternate form of do that can be used when there is only one do variable.
It is described next.
NOTE: For Common Lisp compatability, the var-init-repeat form may be an atom, which is

equivalent to specifing a g_init of nil.

NOTE: This is another, less general, form of do. It is evaluated by:

(1)

(2)
(3)
(4)
(5)
(6)

Evaluating tLinit.
Lambda binding s_name to value of tLinit.
g_test is evaluated, and, if it is not nil, the do function returns with nil.
The do body is evaluated beginning at g_expl.
The repeat form is evaluated and stored in s_name.
Go to step 3.

RETURNS: Nil.

(do,," l_vrbs I_test tLexp1 ... )
RETURNS: the value of the last form in the cdr of I_test, or a value explicitly given by a
return evaluated within the do body. '
NOTE: This is the Common Lisp do* form. It is very similar to do except that: (1) The var-

init-repeat forms are evaluated sequentially rather than simultaneously. (2) There is
no analogue of the old-style mac lisp do. In particular, Cvrbs must be a list of varinit-repeat forms.

Special Functions

4-D

(dolist (s_var I_form g_resultform) g_form)
RETURNS: if present, g_resultform, nil otherwise. Dolist provides a mechanism to iterate
over the elements of the list I_form, successively binding the elements to s_var,
while executing the body of the loop g_form.
(dotimes (s_var i_countform g_resultform) g_form)
RETURNS: if present, ILresultform, nil otherwise. Dotimes provides a mechanism to iterate
over a sequence of integers. First, i_countform is evaluated to produce an integer,
and then evaluates g30rm once for each integer from zero (inclusive) to
i_countform (exclusive), in order, binding s_var to this integer.

; This is a simple function that numbers the elements of a list.
; It uses a do function with two local variables.

=> (de/un printem (lis)
(do ((zz liB (cdr zz))
(i 1 (1+ i)))
((null zz) (patom »all done") (terpr))
(print i)
(patom»:" )
(print (car zz))
(terpr)))
printem

=> (printem '(a bed))
1: a
2: b
3: c
4: d
all done
nil
=> (setq x 100)
100
=> (dolist (x '(a bed e f g) 'result) (msg x"
abc d e f g result

"»

=>x
100

=>

(dotimes (x 10) (mag x","»
0,1,2,3,4,5,6,7,8,9,nil

=>x
100

=>

(environment [l_whenll_whatl Cwhen21_what2 ... J)
(environment-maclisp [1_whenll_whatll_when2 l_what2 ... J)
(environment-Imlisp [1_whenll_whatll_when21_what2 ... J)
WHERE: The when's are a subset of (eval compile load), and the symbols have the same
meaning as they do in 'eval-when'.
The what's may be:
(files filel file2 ... fileN)
which insure that the named files are loaded. To see if filet" is loaded, these functions look for a 'version' property under filei's property list. In order to make this
work to prevent multiple loading, you should put
(putprop 'myfile t 'version),
at the end of myfile.l.

Special Functions

4-10

Another acceptable Corm Cor a what is
(syntax type)
Where type is either maclisp, intlisp, ucilisp, or Cranzlisp.
SIDE EFFECT: environment-maclisp sets the environment to what'liszt +m' generates.
environment-Imlisp sets up the Lisp machine environment. This is like
mac lisp but it has additional macros.

For these specialized environments, only the files clauses are useCui.
(environment-mac lisp (compile eval) (files Coo bar))
RETURNS: The last list oC files requested.

(err ['s_value [nillJ)
RETURNS: Nothing (it never returns).
SIDE EFFECT: This causes an error, and, iC this. error is caught by an errset then that errset
returns s_value instead oC nil. If the second arg is given, then it must be nil
(Cor MAclisp compatibility).
(error ['s_messagel ['s_message2]])
RETURNS: Nothing (it never returns).
SIDE EFFECT: s_messagel and s_message2 are patomed iC they are given and then err is
called (with no arguments), which causes an error.
(cli:error 's3ormat-string ['argsJ)
WHERE: s3ormat-string is a command string to the Cormat-program, and the arg(s) are
passed to Cormat.
RETURNS: Nothing. This Cunction signals a Catal error~
NOTE: The prefix "cli" must be used normally because it is part oC the Common LISP package, and conflicts with the FRANZ LISP Cunction oC the same name.
(cerror 's_continue-Cormat-string 's_error-format-string ['arg ...J)
RETURNS: nil, if the program is continued after the error.
SIDE EFFECT: This Cunction (which is intended Cor use with continuable errors) signals an
error and enters a break loop. The program may be continued after resolution
of the error by typing ?ret to the break loop. The two strings given are
intended as control strings to the Cormat Cunction to construct a continuation
message and an error message. This is entirely compatible with the Common
LISP cerror Cunction. Explanations oC use can be Cound in Common LISP the
Language.

Special Functions

4-11

(errset g_expr [s_Bag])
RETURNS: A list of one element that is the value resulting from evaluating g_expr. If an
error occurs during the evaluation of g_expr, then the locus of control returns to
the errset, which then returns nil (unless the error was caused by a call to err
with a non-null argument).
SIDE EFFECT:

S_Bag is evaluated before g_expr is evaluated. If s_Bag is not given, then it is
assumed to be t. If an error occurs during the evaluation of g_expr, and
s_Bag was evaluated to a non-null value, then the error message associated
with the error is printed before control returns to the errset.

(eval 'g_val ['x_bind-pointer])
RETURNS: The result of evaluating g_val.
NOTE: The evaluator evaluates g_val in the following way:

If g_val is a symbol, then the evaluator returns its value. If g_val had never been
assigned a value, then this causes an 'Unbound Variable' error. If x_bind-pointer is
given, then the variable is evaluated with respect to that pointer. See eva/frame for
details on bind-pointers.
If g_val is of type value, then its value is returned. If g_val is of any other type than
list, g_val is returned.
If g_val is a list object, then g_val is either a function call or array reference. Let
g_car be the first element of g_val. g_car is continually evaluated until it results in a
symbol with a non-null function binding or a non-symbol. Call the result: g_func.

G_func must be one of three types: list, binary, or array. If it is a list, then the first
element of the list, which is called g_functype, must be either lambda, nlambda,
macro, or lexpr. If g_func is a binary, then its discipline, which is called g_functype,
is either lambda, nlambda, macro, or a string. If g3unc is an array, then this form is
evaluated specially. See Chapter 9 on arrays. If g_func is a list or binary, then
ILfunctype determines how the arguments to this function, the cdr of g_val, are processed. If g_functype is a string, then this is a foreign function call. See §8.5 for
more details.
If g_functype is lambda or lexpr, the arguments are evaluated (by calling eval recursively) and stacked. If g_functype is nlambda, then the argument list is stacked. If
g_functype is macro, then the entire form, g_val, is stacked.

Next, the formal variables are lambda bound. The formal variables are the cadr of
g_func. If g_functype is nlambda, lexpr, or macro, there should only be one formal
variable. The values on the stack are lambda bound to the formal variables except
in the case of a lexpr, where the number of actual arguments is bound to the formal
variable.
After the binding is done, the function is invoked, either by jumping to the entry
point in the case of a binary or by evaluating the list of forms beginning at cddr
g_func. The result of this function invocation is returned as the value of the call to
eval.

Special Functions

4-12

(evalframe 'x-pdlpointer)
RETURNS:

NOTE:

An evalframe descriptor for the evaluation frame just before x-pdlpointer. If
x-pdlpointer is nil, it returns the evaluation frame of the frame just before the
current call to evalframe.

An evalframe descriptor describes a call to eval, apply, or funcal/. The form of the
descriptor is

(type pdl-pointer expression bind-pointer np-index lbot-index),
where type is 'eval' if this describes a call to evalor 'apply' if this is a call to apply or
funcall. pdl-pointer is a number that describes this context. It can be passed to evalframe to obtain the next descriptor and can be passed to freturn to cause a return
from this context. bind-pointer is the size of variable binding stack when this
evaluation began. The bind-pointer can be given as a second argument to eval in
order to evaluate variables in the same context as this evaluation. If type is 'eval',
then expression has the form (function-name argl ...). If type is 'apply', then expression has the form {function-name (argl ...)). np-index and lbot-index are pointers
into the argument stack (also known as the names tack array) at the time of call.
lbot-index points to the first argument; np-index points one beyond the last argument.
In order for there to be enough information for evalframe to return, you must call
(*rset t).
EXAMPLE: {progn (evalframe nil))
returns {eval 21.1.7478600 {progn (evalframe nil)) 1 8 1)

(evalhook 'S'-form 'su_evalfunc ['su_funcallfunc1)
The result of evaluating g_form after lambda binding 'evalhook' to su_evalfunc,
and, if it is given, lambda binding 'funcallhook' to su_funcallhook.
NOTE: .As explained in §15.4, the function eval may pass the job of evaluating a form to a
user 'hook' function when various switches are set. The hook function normally
prints the form to be evaluated on the terminal and then evaluates it by calling
evalhook. Evalhook does the lambda binding mentioned earlier and then calls eval to
evaluate the form after setting an internal switch to tell eval not to call the user's
hook function just this one time. This allows the evaluation process to advance one
step and yet insure that further calls to eval cause traps to the hook function (if
su_evalfunc is non-null).
In order for evalhook to work, (*rset t) and (sstatus evalhook t) must have been done
previously.

RETURNS:

(exec s_argl ... )
RETURNS: the result of forking and executing the command named by concatenating the
s_argi together with spaces in between.
(exece 's_fname ['l_args ['l_envir]])
RETURNS: The error code from the system if it was unable to execute the command s_fname
with arguments l_args and with the environment set up as specified in l_envir. If
this function is successful, it is not returned, instead the Lisp system is overlaided
by the new command.

Special Functions

4-13

(freturn 'x""'pdl-pointer 'g_retval)
RETURNS: g_retval from the context given by x_pdl-pointer.
NOTE: A pdl-pointer denotes a certain expression currently being evaluated. The pdl-pointer

for a given expression can be obtained from evalJrame.

(funcall 'u_func ['Largl ... J)
RETURNS: the value of applying function u_func to the arguments g_argi and then evaluat-

ing that result if u_func is a macro.
NOTE: If u_func is a macro or nlambda, then there should be only one g_arg. JuneaU is the

function that the evaluator uses to evaluate lists. If Joo is a lambda, lexpr, or array,
then (JuneaU ,/00 'a 'b 'c) is equivalent to (Joo 'a 'b 'c). If Joo is an nlambda, then
(JuneaU ,/00 '(a b c)) is equivalent to (Joo a b c). Finally, if Joo is a macro, then
(JuneaU ,/00 '(Joo a b c)) is equivalent to (Joo a be).

(funcallhook 'IJorm 'su_funcallfunc ['su_evalfunc])
RETURNS: the result of the following sequence of actions.

First, it lambda-binds 'funcallhook' to su_funcallfunc and, if it is given, lambda binds 'evalhook' to
sU3valhook. Then it proceeds to JuneaU the (car IJorm) on the already evaluated
arguments in the (cdr lJorm)

NOTE: This function is designed to continue the evaluation process with as little work as

possible after a funcallhook trap has occurred. It is for this reason that the form of
I_form is unorthodox: its car is the name of the function to call and its cdr are a list
of arguments to stack (without evaluating again) before calling the given function.
After stacking the arguments but before calling JuneaU, an internal switch is set to
prevent JuneaU from passing the job of funcalling to su_funcallfunc. If JuneaU is
called recursively in funcalling I_form and if su_funcallfunc is non-null, then the
arguments to JuneaU are actually given to su_funcallfunc (a lexpr) to be funcalled.
In order for eva/hook to work, (*rset t) and (sstatus eva/hook t) must have been done
previously. A more detailed description of evalhook and Juncallhook is given in
Ohapter 14.

(function u_func)
RETURNS: The function binding of u_func if it is a symbol with a function binding; other-

wise, u_func is returned.

(getenv 'st_name)
RETURNS: the value of looking up st_name in current environment. Not all operating sys-

tems have an environment.

(go g_labexp)
WHERE:

g_labexp is either a symbol or an expression.

SIDE EFFECT:

If g_labexp is an expression, that expression is evaluated and should result in
a symbol. The locus of control moves to just following the symbol g_labexp
in the current prog or do body.

NOTE: This is only valid in the context of a prog or do body. The interpreter and compiler

allow non-local go's, although the compiler does not allow a go to leave a function
body. The compiler does not allow g_labexp to be an expression.

Special Functions

4-14

(help sx_arg)
RETURNS: nil.
NOTE: a portion of the online FRANZ LISP manual is printed. If sx_arg is an function, then

manual description of that function is printed. If sx_arg is a number or "b" or "c",
then print that chapter or appendix. If sx_arg is "tc", then a table of contents is
printed.
(if
(if
(if
(if

'~a
'~a

'g_b)
'g_b 'g3 ... )
'g_a then 'g_b [... ] [elseif 'g3 then '~d ... ] [else 'g3 [... ])
'~a then 'g_b [... ] [else if 'g_c thenret] [else 'g_d [... ])

il are intended to be easily readable conditional statements -- to
be used in place of condo There are two varieties of if: with and without keywords.
The keyword-less variety is inherited from common Maclisp usage. A keyword-less,
two argument il is equivalent to a one-clause cond, i.e., (cond (a b)). Any other
keyword-less il must have at least three arguments. The first two arguments are the
first clause of the equivalent cond, and all r!!maining arguments are shoved into a
second clause beginning with t. Thus, the second form of il is equivalent to
(cond (a b) (t c ... )).

NOTE: The various forms of

The keyword variety has the following grouping of arguments: a predicate, a thenclause, and an optional else-clause. The predicate is evaluated, and if the result is
non-nil, the then-clause is performed, in the sense described later. Otherwise, that is,
the result of the predicate evaluation was precisely nil, the else-clause is performed.
Then-clauses are either consist entirely of the single keyword thenret, or start with
the keyword then, and followed by at least one general expression. (These general
expressions must not be one of the keywords.) To actuate a thenret means to cease
further evaluation of the il and to return the value of the predicate just calculated.
The performance of the longer clause means to evaluate each general expression in
turn and then return the last value calculated.
The else-clause may begin with the keyword else and be followed by at least one general expression. The rendition of this clause is just like that of a then-clause. An
else-clause may begin alternatively with the keyword elseif and be followed (recursively) by a predicate, then-clause, and optional else-clause. Evaluation of this
clause, is just evaluation of an ii-form, with the same predicate, then- and elseclauses.
(I-throw-err 'I_token)
WHERE:

Ctoken is the cdr of the value returned from a *catch with the tag ER%unwindprotect.

RETURNS: Nothing (never returns in the current context).
SIDE EFFECT:

The error or throw denoted by I_token is continued.

NOTE: This function is used to implement unwind.protect which allows the processing of a

transfer of control though a certain context to be interrupted, a user function to be
executed, and then the transfer of control to continue. The form of Ctoken is either
(t tag value) for a throw or
(nil type meS8age va/ret contuab uniqueid [arg ... j) for an error.
This function is not to be used for implementing throws or errors and is only documented here for completeness.

Special Functions

4-15

(let l_args g_expl ... g_exprn)
RETURNS: The result of evaluating g_exprn within the bindings given by Cargs.
NOTE: l_args is either nil (in which case let is just like progn) or it is a list of binding

objects. A binding object is a list (symbol expression). When a let is entered, all of
the expressions are evaluated and then simultaneously lambda-bound to the
corresponding symbols. In effect, a let expression is just like a lambda expression
except that the symbols and their initial values are next to each other, making the
expression easier to understand. There are some added features to the let expression:
A binding object can just be a symbol, in which case the expression corresponding to
that symbol is 'nil'. If a binding object is a list and the first element of that list is
another list, then that list is assumed to be a binding template and let does a desetq
on it.
(let. l_args g_expl ... g_expn)
RETURNS: The result of evaluating g_exprn within the bindings given by l_args.
NOTE: This is identical to let except the expressions in the binding list Cargs are evaluated

and bound sequentially instead of in parallel.
(lexpr-funcall 'g_function ['g_argl ... J 'l_argn)
NOTE: This is a cross between funcall and apply. The last argument must be a list (possibly
empty). The elements of list arg are stacked and then the function is funcalled.
EXAMPLE: (lexpr-funcall 'list 'a '(b c d)) is the same as

(funcall 'list 'a 'b 'c 'd)
(listify 'x_count)
RETURNS: A list of x_count of the arguments to the current function (which must be a
lexpr).
NOTE: Normally arguments 1 through x_count are returned. If x_count is negative then a
list of last abs{x_count) arguments are returned.
(map 'u_func 'l_argl ... )
RETURNS: l_argl
NOTE: The function u_func is applied to successive sublists of the l_argi. All sublists should

have the same length.
(mapc 'u_func 'l_argl ... )
RETURNS: l_argl.
NOTE: The function u_func is applied to successive elements of the argument lists. All of

the lists should have the same length.

Special Functions

4-16

(mapcan 'u_func 'l_argl ... )
RETURNS: nconc applied to the results of the functional evaluations.
NOTE: The function u_func is applied to successive elements of the argument lists. All sub-

lists should have the same length.
(map car 'u_func 'l_argl ... )
RETURNS: A list of the values returned from the functional application.
NOTE: The function uJunc is applied to successive elements of the argument lists. All sub-

lists should have the same length.
(mapcon 'u_func 'l_argl ... )

to the results of the functional evaluation.
NOTE: The function u_func is applied to successive sublists of the argument lists. All sublists should have the same length.

RETURNS: nconc applied

(maplist 'u_func 'l_argl ... )
RETURNS: A list of the results of the functional evaluations.
NOTE: The function u_func is applied to successive sublists of the arguments lists. All sub-

lists should have the same length.
You may find the following summary table useful in remembering the differences between
the six mapping functions:
Value returned is
Argument to functional is

l_argl

list of results

nconc of results

elements of list

mapc

mapcar

mapcan

sublists

map

maplist

mapcon

(mfunction t_entry 's_disc)
RETURNS: A Lisp object of type binary composed of t_entry and s_disc.
NOTE: t_entry is a pointer to the machine code for a function, and s_disc is the discipline

(e.g., lambda).
(oblist)
RETURNS: a list of every interned symbol in the current lisp environment.
NOTE: The name of this function is historical, and means "object list". It used to be the

case that all symbols lived on the same entity called the oblist or obarray (for object
array).

Special Functions

4-17

(or [g_argl ... J)
RETURNS: The value of the first non-null argument or nil if all arguments evaluate to nil.
NOTE: Evaluation proceeds left to right and stops as soon as one of the arguments evaluates

to a non-null value.
(pop 'I_stack ['g_into])
RETURNS: The top element on the stack I_stack. If g_into is given, a

set! of g_into is done

with the top element as the value. See push below.
(prog l_vrbls g_expl ... )
RETURNS: The value explicitly given in a return form or else nil if no return is done by the

time the last g_expi is evaluated.
NOTE: The local variables are lambda-bound to nil, then the g_expi are evaluated from left

to right. This is a prog body (obviously) and this means that any symbols seen are
not evaluated, but are treated as labels. This also means that return's and go's are
allowed.
(progl 'Lexpl ['g_exp2 ... J)
RETURNS: g3xpl

(prog2 'g_expl 'g_exp2 ['g_exp3 ... J)
RETURNS: g_exp2
NOTE: The forms are evaluated from left to right and the value of g3xp2 is returned.

(progn 'g_expl ['g_exp2 ... J)
RETURNS: The last g_expi.

(progv 'Llocv 'Unitv lLexpl ... )

l_locv is a list of symbols and l_initv is a list of expressions.
RETURNS: The value of the last g_expi evaluated.
WHERE:

NOTE: The expressions in l_initv are evaluated from left to right and then lambda-bound to

the symbols in Llocv. If there are too few expressions in l_initv, then the missing
values are assumed to be nil. If there are too many expressions in l_initv, then the
extra ones are ignored (although they are evaluated). Then the g_expi are evaluated
left to right. The body of a progv is like the body of a progn, it is not a prog body.
(C.f. let)
(pur copy 'g_exp)
RETURNS: A copy of g_exp with new pure cells allocated wherever possible.
NOTE: Pure space is never swept up by the garbage collector, so this should only be done on

expressions that are not likely to become garbage in the future. In certain cases, data
objects in pure space become read-only after a dumplisp, and then an attempt to
modify the object results in an illegal memory reference.

Special Functions

4-18

(purep 'g_exp)
RETURNS: t iff the object g3XP is in pure space.

(push 'g_element 'I_stack)
(pushnew '(Lelement 'I_stack)
RETURNS: I_stack.
NOTE: l.-stack is a fifo stack, and push cons'es (Lelement into l.-stack. pushnew only pushes
the element if it is not already there. See pop above.

(putd 's_name 'uJunc)
RETURNS: u_func
SIDE EFFECT:

This sets the function binding of symbol s_name to u_func.

(return ['g_valJ)
RETURNS: g_val (or nil if g_val is not present) from the enclosing prog or do body.
NOTE: This form is only valid in the context of a prog or do body.

(selectq 'g_key-form [l_clausel ...J)
NOTE: This function is just like caseq (see earlier), except that the symbol otherwise has

the same semantics as the symbol t, when used as a comparator.
(setarg 'x_argnum '(Lval)
x_argnum is greater than zero and less than or equal to the number of arguments
to the lexpr.
RETURNS: g_val
WHERE:

The lexpr's x_argnum'th argument is set to g-val.
NOTE: This can only be used within the body of a lexpr.
SIDE EFFECT:

(throw 'g_val [s_tag])
WHERE:

If s_tag is not given, it is assumed to be nil.

RETURNS: The value of (*throw 's_tag 'Lval).

(*throw 's_tag 'g_val)
RETURNS: g_val from the first enclosing catch with the tag s_tag or with no tag at all. Thus

the value is accompanied by a change in control.
NOTE: This is used in conjunction with *catch to cause a clean jump to an enclosing context.
(unwind-protect g-protected[g_cleanupl ...J)
RETURNS: The result of evaluating g-protected.
NOTE: Normally g-protected is evaluated and its value remembered, then the g_cleanupi are
evaluated, and, finally, the saved value of g-protected is returned. If something
should happen when evaluating g-protected which causes control to pass through
LProtected, and, thus, through the cfl-ll to the unwind-protect, then the g_cleanupi is
still evaluated. This is useful if g-protected does something sensitive which must be
cleaned up whether or not g-protected completes itself. Programs which 'temporarily' mess up a structure and then straighten the structure can use this scheme to
protect the straightening-up process from being cut off by a keyboard interrupt.

4-19

Special Functions

4.3. Multiple Value Returns
Sometimes a function logically needs to return more than one value, but in most
cases only one of them is used and it is therefore considered uneconomical to "cons-up" a
structure for the unusual case. A function performing a division might returning the quotient and then as a second part, number might return the remainder. A neat way to do
this is by using multiple value returns. Only those functions which expect multiple values
can receive them, and thus the default is to return a single value. The mechanism for
using multiple values is explained below.
There are special functions which must be used to produce and receive multiple
value. If a called function produces multiple values and the calling function does not
request them, then all but the first value are discarded. If no values are produced, then the
caller receives nil for a value. The maximum number of multiple values which can be
returned by a functions is bound to the global variable multiple-values-limit.
The multiple value facility is completely compatible with Common Lisp.
Here are the functions to produce and receive multiple values:
(values ['g_arg1 ... 'g_argn])
RETURNS: g_arg1, or nil if given no arguments. The g_argi are returned as multiple values.
With the exception of the first, they can be accessed only by using one of the special forms below to receive them.
(values-list 'l_arg)
RETURNS: the car of l_arg; but if received appropriately will exhibit the elements in the list

Carg as multiple values. This form is equivalent to (apply 'values 'l_arg).
EXAMPLE: (values-list '(1 2 3)) is equivalent to (values 1 2 3)

(multiple-value-call 'u_fun 'g_form1 [ '~form2 ... ])
RETURNS: the result of calling u_fun with the results of all g_formi as arguments.

(multiple-value-list 'g_form)

oC the multiple values returned by g_form. This Corm
(multiple-value-call #'list 'g_form).

RETURNS: a list

IS

equivalent to

(multiple-value-progl 'g_form1 [ 'g_form2 ... ])
RETURNS: the values produced by g_Corml, aCter evaluating all gJormi.

(multiple-value-setq 'l_varlist 'g_Corm)
RETURNS: the first value returned by g_Corm after setting each variable in l_varlist to the

corresponding value returned by ~Corm (the first variable gets the first value, and
so on).
NOTE: If there are more variables than returned values, then the remaining variables are
given the value nil.

Special Functions

4-20

(multiple-value-bind 'l_varlist 's-values-form 's-form! [ 'g_form2 ... ])
RETURNS: the result of evaluating g_formi. The variables in l_varlist are bound to the
values returned by s-values-form, and then all the g_formi are evaluated.

CHAPTER 5
Input/Output

5.1. Introduction
The following functions are used to read from and write to external devices (e.g. files)
and programs through pipes. All I/O goes through the Lisp data type called the port. A
port may be open for either reading or writing but usually not both simultaneously (see
jileopen). There are only a limited number of ports (20) and they are not reclaimed unless
they are clo8ed. All ports are reclaimed by a resetio call, but this drastic action is not
necessary if the program closes ports that it uses.
If a port argument is not supplied to a function that requires one, or if a bad port
argument (such as nil) is given, then FRANZ LISP uses the default port according to this
scheme: if input is being done, then the default port is the value of the symbol piport and,
if output is being done, then the default port is the value of the symbol poport. Further-more, if the value of piport or poport is not a valid port, then the standard input or standard output is used, respectively.

The standard input and standard output are usually the keyboard and terminal
display unless your job is running in the background and its input or output is connected
to a pip~. All output that goes to the standard output also goes to the port ptport, if it is
a valid port. Output destined for the standard output does not reach the standard output
if the symbol AW is non-nil, although it still goes to ptport if ptport is a valid port.
FRANZ LISP has borrowed a convenient shorthand notation from the Unix operating
system '0' shell concerning naming files. If a file name begins with - (tilde), and the symbol tilde-expansion is bound to something other than nil, then FRANZ LISP expands the
file name. It takes the string of characters between the leading tilde, and the first slash as
a user-name. Then, that initial segment of the filename is replaced by the home directory
of the user. The null username is taken to be the current user.
On Unix systems, having gone to the effort of searching the password file, FRANZ LISP
remembers the user directory, in case it gets asked to do so again. Tilde-expansion is per-formed in most places in which file names are expect, and in particular, the following functions: clasl, chdir, lasl, ffa81, jileopen, injile, load, outjile, probe/, sys:access, sys:unlink.
The programmer should be careful to note which of the functions reference file names
and which refer to ports.

Input/Output

5-1

Input/Output

5-2

5.2. Functions
(eras} 'st_file 'st_entry 'st_funcname ['st_disc ['st_Iibrary]])
RETURNS:

T

SIDE EFFECT:

This is used to load in a foreign function (see §8.4). The object file st_file is
loaded into the Lisp system. St3ntry should be an entry point in the file
just loaded. The function binding of the symbol s_funcname is set to point
to st_entry so that, when the Lisp function sjuncname is called, st_entry is
run. st_disc is the discipline to be given to sjuncname. st_disc defaults to
"subroutine" if it is not given or if it is given as nil. H st_library is non-null,
then after st_file is loaded, the libraries given in st_library are searched to
resolve external references. The form of st_Iibrary should be something like
"+llibname". The C library (" +lclib " ) is always searched so that when
loading in a C file, you probably will not need to specify a library.

NOTE: This function may be used to load the output of the assembler, C compiler, Fortran

compiler, and Pascal compiler but NOT the Lisp compiler. Use last for that. If a file
has more than one entry point, then use getaddress to locate and setup other foreign
functions.
It is an error to load in a file that has a global entry point of the same name as a global entry point in the running Lisp. As soon as you load in a file with clast, its global
entry points become part of the Lisp's entry points. Thus, you cannot clast in the
same file twice unless you use remove address to change certain global entry points to
local entry points.
(close 'p-port)
RETURNS: t
SIDE EFFECT:

The specified port is drained and closed, releasing the port.

NOTE: The standard defaults are not used in this case since you probably never want to

close the standard output or standard input.
(cprintf'st_format 'xfst_val ['p-portJ)
RETURNS: xfst_val
SIDE EFFECT:

The operating system formatted output function printf is called with arguments st_format and xfst_val. If xfst_val is a symbol, then its print name is
passed to printf. The format string may contain characters that are printed
literally, and it may contain special formatting commands preceded by a percent sign. The complete set of formatting characters is described in the
operating system manual. Some useful ones are %d for printing a fixnum in
decimal, %f or %e for printing a flonum, and %s for printing a character
string (or print name of a symbol).

EXAMPLE: (cprintl" Pi equals

%/' 3.14159) prints 'Pi equals

3.14159'

(drain ['p-portJ)
RETURNS: nil
SIDE EFFECT:

H this is an output port, then the characters in the output buffer are all sent
to the device. H this is an input port, then all pending characters are flushed.
The default port for this function is the default output port.

Input/Output

5-3

(fasl 'st_name ['st_mapf ['g_warn]])
WHERE: st_mapf and g_warn default to nil.
t if the function succeeded, nil otherwise.
SIDE EFFECT: This function is designed to load in an object file generated by the Lisp compiler Liszt. File names for object files usually end in '.0', so /a81 append '.0'
to st_name, if it is not already present. If st_mapf is non-nil, then it is the
name of the map file to create. Fa81 writes in the map file the names and
addresses of the functions it loads and defines. Normally, the map file is
created (i.e. truncated if it exists), but if (88tat'l/,8 appendmap t) is done, then
the map file is appended. If ~warn is non-nil and if a function is loaded
from the file that is already defined, then a warning message is printed.

RETURNS:

NOTE:

/a81 only looks in the current directory for the file to load. The function load looks
through a user-supplied search path and calls /a81 if it finds a file with the same root
name and a '.0' extension. In most cases, you should use the function load rather
than calling /a81 directly.

(fileopen 's_filename 's_mode])
RETURNS: a port for reading or writing based on the file s_filename. The s_mode is one of r,
W, or a, (for read, write, append), or r+, w+, or a+ each of which permits both
reading and writing on a port provided that /8eek is done between changes in
"direction". In the case of writing, the file will be created if it does not already
exist. The directory search-path for file name resolution is not used.
(filepos 'p-port ['x-POsJ)
RETURNS: The current position in the file if x-pos is not given or else x-pos if x-pos is
given.
SIDE EFFECT:

If x-pos is given, the next byte to be read or written to the port is at position
x-pos.

(filestat 'st_filename)
RETURNS: A vector containing various numbers that the operating system assigns to files. If
the file does not exist, an error is invoked. Use probe/ to determine if the file
exists.
NOTE: The individual entries can be accessed by mnemonic functions of the form filestatfield, where field may be any of: dev, ino, mode, mtime, nlink, size, type, or uid.
See the operating system programmers manual for a more detailed description of
these quantities.
(Hate '~form ['x_max])
RETURNS: The number of characters required to print g_form using patom. If x_max is
given and, if fiate determines that it returns a value greater than x_max, then it
gives up and returns the current value it has computed. This is useful if you just
want to see if an expression is larger than a certain size.

Input/Output

6-4

(flatsize '~form ['x_max])
RETURNS: The number of characters required to print g_form using print. The meaning of
x_max is the same as for flatc.
NOTE: Currently this just explode's g_form and checks its length.

(fseek 'p-port 'x_offset 'x_flag)
RETURNS: The position in the file after the function is performed.
SIDE EFFECT:

this function positions the read/write pointer before a certain byte in the file.
If x_flag is 0 then the pointer is set to x_offset bytes from the beginning of
the file. If x_flag is 1 then the pointer is set to x_offset bytes from the
current location in the file. If x_flag is 2 then the pointer is set to x_offset
bytes from the end of the file.

(help sx_arg)
RETURNS: nil.
NOTE: a portion of the online FRANZ LISP manual is printed. If sx_arg is an function, then

manual description of that function is printed. If sx_arg is a number or "b" or "c",
then print that chapter or appendix. If sx_arg is "tc", then a table of contents is
printed.
(infile 's_filename)
RETURNS: A port ready to read s_filename.
SIDE EFFECT:

This tries to open s_filename, and, if it cannot or if there are no ports available, it gives an error message.

NOTE: To allow your program to continue on a file-not-found error, you can use something

like:
{cond {{null {setq myport {car {err8et {infile name} nil}}}}
{patom "' couldn't open the file" }}}
which sets myport to the port to read from if the file exists or prints a message if it
could not open it and also sets myport to nil. To simply determine if a file exists, use
probef·
(load 's_filename ['st_map ['g_warn]])
RETURNS: t
NOTE: The function of load has changed since previous releases of FRANZ LISP and the fol-

lowing description should be read carefully.

load now serves the function of both fa81 and the old load. Load searches a
user-defined search path for a Lisp source or object file with the filename
s_filename (with the extension .1 or .0 added as appropriate). The search
~ path that load uses is the value of {8tatus load-8earch-path}. The default is
- .(1.1 /lisp/lib), which means: look in the current directory first and then
/lib/lisp. The file that load looks for depends on the last two characters of
s_filename. If s_filename ends with ".1", then load only looks for a file name
sJlename and assumes that this is a FRANZ LISP source file. If s_filename
ends with ".0", then load only looks for a file named s_filename and assumes
that this is a FRANZ LISP object file to be fa8led in. Otherwise, load first
looks for s_filename.o, then s_filename.l, and, finally, s_filename itself. If it
finds s_filename.o, it assumes that this is an object file; otherwise, it assumes
that it is a source file. An object file is loaded using fasl and a source file is
loaded by reading and evaluating each form in the file. The optional arguments st_map and g_warn are passed to fa81 should fasl be called.

SIDE EFFECT:

Input/ Output

5-5

requires a port to open the file s_filename. It then lambda binds the symbol
piport to this port and reads and evaluates the forms.

NOTE: load

(makereadtable ['s_Hag])
WHERE:

If s_Hag is not present it is assumed to be nil.

RETURNS:

A readtable equal to the original readtable if s_Hag is non-null, or else equal to
the current readtable. See Chapter 7 for a description of readtables and their
uses.

(msg [Coption ... J ['~msg ... ])
NOTE: This function is intended for printing short messages. Any of the arguments or
options presented can be used any number of times in any order. The messages
themselves (~msg) are evaluated, and then they are transmitted to patom. Typically, they are strings, which evaluate to themselves. The options are interpreted
specially:

m8g

Option Summary

(P pJlortname)

Causes subsequent output to go to the port p-portnamej
port should be opened previously.

B

Print a single blank.
Evaluate n_b and print that many blanks.

N

Print a single newline by calling terpr.
Evaluate nJl and transmit
that many newlines to the stream.
drain the current port.

D

(nwritn ['p-port])
RETURNS: The number of characters in the buffer of the given port but not yet written out
to the file or device. The buffer is Hushed automatically when filled or when terpr
is called.
(outfile 's_filename ['st_typeD
RETURNS:

A port or nil

SIDE EFFECT:

This opens a port to write s_filename. If st_type is given and if it is a symbol or string whose name begins witQ' 'a', then the file is opened in append
mode; that is, the current contents
not lost, and the next data is written
at the end of the file. Otherwise, the file opened is truncated by outfile if it
existed beforehand. If there are no free ports, outfile returns nil. If one cannot write on s_filename, an error is signalled.

are

Input/ Output

5-6

(patom 'g_exp ['p-port])
RETURNS: g_exp
SIDE EFFECT: g_exp is printed to the given port or the default port. If g_exp is a symbol or
string, the print name is printed without any escape characters around special characters in the print name. If lLexP is a list, then patom has the same
effect as print.
(pntlen 'xfs_arg)
RETURNS: The number of characters needed to print xfs_arg.
(portp

'~arg)

RETURNS: T iff g_arg is a port.

(pp [I_option] s_namel ... )
RETURNS: t

SIDE EFFECT: If s_namei has a function binding, it is pretty-printed; otherwise, if s_namei

has a value, then that is pretty-printed. Normally, the output of the prettyprinter goes to the standard output port poport. The options allow you to
redirect it.

PP Option Summar1l
(F •...filename)

Direct future printing to s_filename.

(P p,...portname)

Causes output to go to the port p-portnamej
port should be opened previously.
Evaluate 8-expression and do not print.

(prine 'g_arg ['p-port])
EQUNALENT TO: patom.
(print '~arg ['p...,port])
RETURNS: nil
SIDE EFFECT: Prints g_arg on the port p...,port or the default port. For objects that can't be
read back in, the convention is used that a sharp-sign (#) prefixes the data
printed. For example,
The lisp objects other, bcd, vector, hash-table, package, array, and port now
print as "#< ... >". Reading the value of printing one of the above objects is
an error.

Input/Output

5-7

=> ·package*
#
=> (getd 'car)
#
=> (make-hash-table)
#
=> Standard-Input
#
=> (vector 10)
#
= > (marray nil nil nil 10 nil)
#
= > (getd 'format)
# ; known to be compiled code, which is of type other
=> (fake #xd4800)
#

(sprintt't_control ['argl ... J)
RETURNS: the formatted string corresponding to the returned value of the C library sprintf
function.
NOTE: The (backslash) escapes do NOT work. T_control must be a string.

(wide-print-list 'g_exp [:port 'p_whereJ [:left-margin 'x_wheretostartJ)
RETURNS: Nil
SIDE EFFECT: Prints the expression g_exp to to the port p_where, starting at the column
number x_wheretostart. wide-print-list prints as many entities on one line as
will fit assuring that no lisp object other than a list is broken across a line
boundary. In particular, atoms and numbers remain on one line.

(prober 'st_file)
RETURNS: T iff the file st_file exists.
NOTE: Just because it exists doesn't mean you can read it.

(pp-rorm 'g_form ['p-portJ)
RETURNS:T
SIDE EFFECT: g_form is pretty-printed to the port p-port (or poport if p-port is not given).
This is the function that pp uses. pp-form does not look for function
definitions or values of variables, it just prints out the form it is given.
NOTE: This is useful as a top-level-printer. See top-level in Chapter 6.

Input/Output

5-8

(ratom ['p-port ['g_eof]])
RETURNS: The next atom read from the given or default port. On end of file, g_eof (default

nil) is returned.

(read ['p-port ['g_eof]])
RETURNS: The next Lisp expression read from the given or default port.

On end of file,

Leof (default nil) is returned.
NOTE: An error occurs if the reader is given an ill-formed expression. The most common

error is too many right parentheses. (Note that this is not considered an error in
Maclisp).

(reade ['p-port ['g_eoflJ)
RETURNS: The next character read from the given or default port. On end of file, g30f
(default nil) is returned.
(read line ['p_port])
RETURNS: a string containing all characters in the stream p-port up to, but not including,
the next newline. The null string is returned if the first character is a newline.
(eharent 'p-port)
RETURNS: The number of characters left on the current line in p-port.
5;) ~ ; rtallJ.,(

treaddir ['t_dirname])
RETURNS: A list of strings, one for each file in the named directory.
NOTE: t_dirname is a string representing the name of a directory. It may be ".", meaning

return a list of the current working directory (This is the default if the argument is
omitted.) All files are listed except"." and " .. ". No tilde-expansion is done on the
argument.

(readlist 'Carg)
RETURNS: The Lisp expression read from the list of characters in l_arg.
(removeaddress 's_namel ['s_name2 ... ])
RETURNS: Nil
SIDE EFFECT:

The entries for the s_namei in the Lisp symbol table are removed. This is
useful if you wish to clasl in a file twice, since it is illegal for a symbol in the
file you are loading to already exist in the Lisp symbol table.

(resetio)
RETURNS: Nil
SIDE EFFECT:

All ports except the standard input, output, and error are closed.

Input/Output

5-9

(sload's_file)
The file s_file (in the current directory) is opened for reading, and each form
is read, printed, and evaluated. IT the form is recognizable as a function
definition, only its name is printed; otherwise, the whole form is printed.
NOTE: This function is useful when a file refuses to load because of a syntax error and you
would like to determine where the error is.

SIDE EFFECT:

(tab 'x_col ['p-port])
SIDE EFFECT:

Enough spaces are printed to put the cursor on column x_col. IT the cursor is
beyond x301 to start with, a terpr is done first.

(terpr ['p-portJ)
RETURNS: Nil
SIDE EFFECT:

A terminate line character sequence is sent to the given port or the default
port. This also drains the port.

(terpri ['p-port])
EQUIVALENT TO: terpr.

(tilde-expand 'st_name)
RETURNS: st_name will all - 's expanded with absolute pathnames in their place.
NOTE: this function is not available in all versions of FRANZ LISP.

(truenam.e 'p...,port)
RETURNS: The name of the file to which p...,port refers.
(tyi ['p...,portj)
RETURNS: The fixnum representation of the next character read.

On end of file, -1 is

returned.
(tyipeek ['p...,port])
RETURNS: The fixnum representation of the next character to be read.
NOTE: This does not cause an official 'read' of the character, it just peeks at it and returns
the value which would be returned if it were read. (It 'peeks'.)
(tyo 'x3har ['p...,portj)
RETURNS: x3har.
SIDE EFFECT: The character whose fixnum representation is x30de is printed as a character
on the given output port or the default output port.

Input/Output

5-10

(untyi 'x_char ['p-port])
SIDE EFFECT: x_char is put back in the input buffer so a subsequent tyi or read reads it
first.
NOTE: A maximum of one character may be put back.

(y-or-n-p ['t_message])
RETURNS: t if an answer of "y" is read from the user, nil otherwise. H t_message is given,
then prompt the user with this string before reading.
NOTE: piport and poport are used as the querying ports.

(zap line)
RETURNS: nil
SIDE EFFECT: All characters up to and including the line termination character are read

and discarded from the last port used for input.
NOTE: This is used as the macro function for the semicolon character when it acts as a comment character.

5.3. Format
Format is a output formatter somewhat in the style of the fprintf cO' run-time library
program. The arguments to format include an output port, a control string, and the values
to be printed. The values passed to format are printed according to the directives in the
control string.
In the simplest case, the format control string has no directives and is passed no variables. In this case, format just prints:

(/orm(Jt t "HeUo world")

==> "HeUo world"nil

As we see from the previous example, format prints some expression, and then
return8 a value nil. H, instead of t, (which indicates the standard output), we had used nil
as the value for the port, format would have printed nothing, but returned a symbol, IHello
worldl. Values returned by format are uninterned.

(format 'p-port 's_ctrl ['g_arg ...])
RETURNS: nil if p-port is non-nil otherwise returns a 8ymbol determined by s_ctrl and the
arguments.
WHERE: p-port is one of: t (the user's terminal), an output port opened with o'ILtjile (or
jileopen), or nil (which causes format to return a symbol).
s_ctrl is a control string, enclosed in double quotes ("). It may also contain directive8, prefaced by a tilde
as explained, below.

r ),

The number of arguments should correspond to the number of values expected by
the control string. All arguments are processed according to the number of directives contained in the control string. Extra arguments are discarded. When an

Input/Output

0-11

insufficient number of arguments are given, default values may be inserted.
when p-port is non-nil, prints a string to p-port.

SIDE EFFECT:

In the example, above, the control string was a simple string, containing no directives
and there were no arguments to the string. The remainder of this section will deal with
more complex control strings wpich contain directives which are used to manipulate the output. Directives are invoked using the directive prefix, - , (a tilde). In addition, there are a
number of modifiers, which can be used to further manipulate the output. These modifiers
may be in the form of a special character, such as the atsign ("@"), or the colon (":"), or,
they may simply be a combination of numbers, indicating, perhaps, the number of
significant digits in a numeric expression. Finally, there is a control character, which is
flagged by the tilde signifies the directive to be followed. In some cases, directives may only
apply to the next item to be printed, and as such, will appear alone in the text of the control string. In other cases, directives may involve more complex strings, and may require a
matching "closing" directive (much like the closing right parenthesis of a list). All of these
variations will be described and illustrated in the following text. In general, however, the
form of the control string is (with the optional end-directive in brackets):
,,-    string...

r !,

In certain cases, more than one modifier may be used for a single directive. In such
cases, individual modifiers may be separated by a comma. For example, the directive - d
causes the argument to be printed in decimal format. However, - nd causes the argument to
be printed to n decimal places (using a space as a pad character), while - n,md will cause
the integer to be printed to n decimal places using the character whose decimal representation is m as the pad character. (In the previous discussion, nand m are prefixes, in contradistinction to modifiers such as the atsign and the colon.)

; the - % outputs a carriage return.

=> (format t " Today'8 daily number i8: - d - %" 10f4)
Today's daily number is: 1024
nil
; the number will be printed to four places but the pad character
; will be a space.
=> (format t "Today's daily number is:- 4d - %" 304)
Today's daily number is: 304
nil
; 48 is the decimal representation of a zero (0)
=> (formal I" Today'8 daily number i8: - 4,48d- %" 904)
Today's daily number is: 0304
nil
=>

In some cases, the prefix parameter will indicate a character to be printed, such as the
padding character in the case of - d, above. Since format expects a decimal number, ascii
characters should either be specified by their decimal values (e.g., 48 = "0"), or using a
quote sign (e.g., ,,- 4, 'Od") In addtion, the prefix character can be the letter v or the sharpsign character, =IF. The v prefix directs format to use the value of the current argument as
the prefix to the directive. This syntax is illustrated in description of the - q directive. The
other option, =IF, substitutes the number of remaining arguments for the prefix character.
The use of the sharpsign is illustrated in a number of examples, below.

5-12

Input/ Output

5.3.1. format directives
The following is a description of the format directives have been modeled after
those in MacLISP and ZetaLISP. The symbol arg will be used to indicate the
corresponding argument to the directive.

a
s

prints any argument, arg as it would be printed by prine (without escaping).
- na prints the argument filling it to width n with spaces.
is identical to - a except that the print function is prin1.

as described in the previous example, prints the decimal representation of arg
(without a decimal point). If arg is not a number, it is printed in - a format. - nd
prints arg to n spaces, the padding character is indicated by - mineolw,padehard
where padchar is the decimal representation of the padding character (default is a
space but a useful value is decimal 48 which is an ascii 0).
o similar to - d except that it prints the argument in octal form (radix 8). Note
that arg must be a number. See also - r. - nf
print8 arg to a precision of n digits (minimum 2, because of the decimal point).
The decimal pointed is floated to be consistent with standard scientific notation so
that extremely large numbers and extremely small number are printed in
exponential notation. If arg is not a number it is printed in - a format. Unlike the
previous directives, the prefix is not mine 01, rather, it is total number of digits
printed (n-l decimal places).]
e [arg is printed in exponential notation. The prefix case is identical to - f indica,tive of the number of significant digits. Unlike - f, all values for arg are printed in
exponential notation.]
r a general purpose number formatter. The full form of this directive is
- radiz,mineoiw,padehar,eommachar r where each of these prefix values has
the same meaning as in the - d directive. The radix prefix causes the argument to
be printed in that base, i.e, - lOr is equivalent to - d. Non-numeric arguments
are printed using - a.

- d

If no prefix is given, the numerical argument is printed as text, i.e, if the argu-

ment is "4", then - r prints "four" (cardinal value), - :r prints "fourth" (ordinal
:@r prints IIII (old-style Roman
value), and - @r prints N (Roman numeral).
numeral).]

r

=>

(format t "The - :r one on the right.-

%" 1)

The first one on the right.
nil
; - % prints a carriage return.

=>

(format t "Total value of door number - r: - r doUarsr

%" a teaae)

Total value of door number three: twelve thousand three hundred thirty-two dollars!
nil
; the next example illustrates the use of the - • directive which
; allows the user to evaluate the arguments out of order.

=>

(format t "The octal representation of- dis - :* - Br. -

%"

1B)

The octal representation of 18 is 22.
nil

c

prints arg (which should be a fixnum representing an ascii character), in a more
human-readable form. - c prints the non-printable (control) characters
represented by the fixnum argument in a slashified octal form. - :c prints the
non-printable characters as an upper case character prefixed by a carat (e.g.,

Input/Output

5-13

"'C"); some characters such as decimal 32 (a space) is printed in a text form (e.g.,
"space"). The - @e form prints the character in LISP readable form (slashified).
In all cases, the printable characters are printed in their keyboard form.
[The - e allows the character to be displayed along with any control bits which
may be set. In ZetaLISP, an alternate character set may be used to indicate nonprinting characters such as control characters (using the - e directive) while chaI'acters printed with the - :e directive will have the control bits spelled out. For
example, a character may print out as "Control-Meta-x". Mouse characters will
print out "Mouse-

Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.3
Linearized                      : No
XMP Toolkit                     : Adobe XMP Core 4.2.1-c041 52.342996, 2008/05/07-21:37:19
Create Date                     : 2016:05:24 11:28:44-08:00
Modify Date                     : 2016:05:24 11:53:55-07:00
Metadata Date                   : 2016:05:24 11:53:55-07:00
Producer                        : Adobe Acrobat 9.0 Paper Capture Plug-in
Format                          : application/pdf
Document ID                     : uuid:fea5202f-6f0d-9745-a797-8272b1426750
Instance ID                     : uuid:a2970896-5c4c-5248-a6d9-331c28675606
Page Layout                     : SinglePage
Page Mode                       : UseNone
Page Count                      : 319
EXIF Metadata provided by EXIF.tools

Navigation menu