μ
uLisp
Reference Manual

Version 0.5e
2017 Feb 9
edited by Glenn Takanishi
Modifications of original documention from XLisp-3.3 (2002)
by David Betz


Table of Contents



Introduction

Running μ-Lisp:

Usage: ulisp [-htV] [-c <size>] [-v <size>] [-s <size>] <file> <argument ...>
            V - version
            t - turn on the trace option
            c - number of cell segments [default: 16384] 
            v - number of vector segments [default: 65536]
            s - stack size [default: 16384]

This version is case-sensitive.  The s-expression procedures and symbols
(including the built-in variables) on the command-line are NOT automatically
converted to upper-case.  For example, the function "print" is defined, but
"PRINT" does not exist as a builtin function.  Ulisp uses the Common Lisp
like dynamic binding or closure in functions "def" and "lambda".  This kind
of binding is not used in scheme.

ulisp loads the initialization file from directory
/usr/local/share/ulisp.  Copy the files in directory macros to
/usr/local/share/ulisp. You can change this directory path in main.c

If the environmental parameter LISP_LIBRARY_PATH is defined, ulisp will
set the *load-path* variable to this parameter.  For example, if you
use the Bash shell set, eg., export LISP_LIBRARY_PATH=/usr/local/slib.
Then ulisp will try to load files in your home directory, then search
the LISP_LIBRARY_PATH's for files if it's not in the home directory.



Constants


#t
#!true

The true value.

#f
#!false

The false value.

nil
#!nil

The nil value.  In ulisp, nil, and the empty list,
(), are the same value.  ulisp returns () from statements such as
(if nil #t nil). 



Built-In Variables



*readtable*

Bound to the current read table.

*error-handler*

Bound to a function to handle errors.  The function should take
two arguments, the function where the error occured and the
environment at the time of the error.  It shouldn't return.

*unbound-handler*

Bound to a function to handle unbound symbol errors.  The
function should take two arguments, the symbol that is unbound
and a continuation to call after correcting the error.


*load-path*

This variable is used by the LOAD function, and initialized
by the get environment, "getenv" function.  This variable is set
using the environment variable "LISP-LIBRARY-PATH".  The value
of this variable consists of a list of ":" separated directory
names to search in.  For example, "/usr/local/slib:./".


*standard-input*

Bound to the standard input port.

*standard-output*

Bound to the standard output port.

*error-output*

Bound to the error output port.

*fixnum-format*

A printf style format string for printing fixed point numbers.
FIXNUMs are generally represented by long integers so this should
usually be set to "%ld".

*hexnum-format*

A printf style format string for printing fixed point numbers
in hexadecimal.  FIXNUMs are generally represented by long
integers so this should usually be set to "%lx".

*flonum-format*

A printf style format string for printing floating point numbers.
This is usually set to "%.15g".


#t

Bound to the true value.

#f

Bound to the false value.

nil

Bound to the empty list.




Expressions


variable

An expression consisting of a variable is a variable reference.
The value of the variable reference is the value stored in the
location to which the variable is bound. It is an error to
reference an unbound variable.

(quote datum)
'datum

(quote datum) evaluates to datum. Datum may be any external
representation of an ulisp value. This notation is used to include
literal constants in ulisp code. (quote datum) may be abbreviated
as 'datum. The two notations are equivalent in all respects.

constant

Numeric constants, string constants, character constants
and boolean constants evaluate "to themselves"; they need not
be quoted.

(operator operand...)

A procedure call is written by simply enclosing in parentheses
expressions for the procedure to be called and the arguments to
be passed to it. The operator (predicate) and operand expressions are
evaluated and the resulting procedure is passed the resulting
arguments.


(set variable expression)

Expression is evaluated, the variable is created, and then
the value of the expression is stored in location to which the
variable is bounded.  Set is a macro define as
(define-macro (set a b) `(define ,a ,b)).


(set! variable expression)

Expression is evaluated, and the resulting value is stored in the
location to which variable is bound.  Variable must be bound in
some region or at the top level.  The result of the set! expression
is unspecified.


(lambda formals body)

Formals should be a formal argument list as described below,
and body should be a sequence of one or more expressions.  A lambda
expression evaluates to a procedure. The environment in effect when
the lambda expression is evaluated is remembered as part of the
procedure. When the procedure is later called with some actual
arguments, the environment in which the lambda expression was
evaluated will be extended by binding the variables in the formal
argument list to fresh locations, the corresponding actual argument
values will be stored in those locations, and the expressions in
the body of the lambda expression will be evaluated sequentially
in the extended environment.  The result of the last expression in
the body will be returned as the result of the procedure call.

Formals should have the following form:

(var... [&optional ovar...] [. rvar])

or

(var... [&optional ovar...] [&rest rvar])

where:

var is a required argument
ovar is an optional argument
rvar is a "rest" argument

There are three parts to a formals list. The first lists the
required arguments of the procedure. All calls to the procedure
must supply values for each of the required arguments. The second
part lists the optional arguments of the procedure. An optional
argument may be supplied in a call or omitted. If it is omitted,
a special value is given to the argument that satisfies the
default-object? predicate. This provides a way to test to see
if an optional argument was provided in a call or omitted. The
last part of the formals list gives the "rest" argument. This
argument will be bound to the rest of the list of arguments
supplied to a call after the required and optional arguments
have been removed.

In summary, you can use "Common Lisp" syntax for the formal parameters:

(var...
 [&optional {ovar | (ovar [init [svar]])}...
 [&rest rvar]
 [&key {kvar | ({kvar | (key kvar)} [init [svar]])}...
 [&aux {avar | (avar [init])}])

where:

var is a required argument
ovar is an optional argument
rvar is a "rest" argument
kvar is a keyword argument
avar is an aux variable
svar is a "supplied-p" variable



(named-lambda name formals body)

named-lambda is the same as lambda except that the specified
name is associated with the procedure.



(rec (name args) body)

Name is the name of the resulting procedure.  Args is the
formal parameters.  An example factorial procedure is

> (set f (rec (f n) (if (zero? n) 1
                        (* n (f (- n 1))))))
f
> (f 10)
3628800



(if test consequent [alternate])

An if expression is evaluated as follows: first, test is evaluated.
If it yields a true value, then consequent is evaluated and its
value is returned. Otherwise, alternate is evaluated and its
value is returned. If test yields a false value and no alternate
is specified, then the result of the expression is unspecified.

A false value is nil or the empty list.  Every other value is
a true value.



(cond clause...)

Each clause should be of the form

(test expression...)

where test is any expression. The last clause may be an
"else clause," which has the form

(else expression...)

A cond expression is evaluated by evaluating the test
expressions of successive clauses in order until one of
them evaluates to a true value. When a test evaluates to a
true value, then the remaining expressions in its clause are
evaluated in order, and the result of the last expression in
the clause is returned as the result of the entire cond expression.
If the selected clause contains only the test and no expressions,
then the value of the test is returned as the result. If all tests
evaluate to false values, and there is no else clause, then the
result of the conditional expression is unspecified; if there
is an else clause, then its expressions are evaluated, and the
value of the last one is returned.

(and test...)

The test expressions are evaluated from left to right, and
the value of the first expression that evaluates to a false
value is returned. Any remaining expressions are not evaluated.
If all the expressions evaluate to true values, the value of
the last expression is returned. If there are no expressions
then #t is returned.

(or test...)

The test expressions are evaluated from left to right, and
the value of the first expression that evaluates to a true
value is returned. Any remaining expressions are not evaluated.
If all expressions evaluate to false values, the value of
the last expression is returned. If there are no expressions
then nil (the empty list or false value) is returned.




Multiple Values


(values expr ...)

The results of evaluating this expression are the values of
the expressions given as arguments.  It is legal to pass no
values as in (VALUES) to indicate no values.  See the example
for MULTIPLE-VALUE-BIND.  "(values expr ...)" is a vexpr.

(values-list list)

The results of evaluating this expression are the values in the
specified list.

(multiple-value-bind (var ...) vexpr expr ...)

A vexpr is an expression that produces multiple variables regulating
a consumer expression.  The multiple values produced by vexpr are bound
to the specified variables and the remaining expressions are evaluated
in an environment that includes those variables.
For example,
   > (multiple-value-bind (f g) (values 1 2)  (cons f g)) => (1 . 2)

(multiple-value-call expr vexpr)

The multiple values of vexpr are passed as arguments to the
specified function or expression.  For example,
   > (multiple-value-call cons (values 1 2)) => (1 . 2)
   > (multiple-value-call + (values-list (list 1 2 3))) => 6

(call-with-values vexpr expr)

The multiple values of procedure vexpr are passes as arguments to
the function expr.  For example,
   > (call-with-values (lambda () (values 1 2)) cons) => (1 . 2)


(let-values) and (let*-values) are described under "Binding Forms".






Non-Local Exits


(catch tag expr ...)

Evaluate the specified expressions in an environment where
the specified tag is visible as a target for "throw".  If no
throw occurs, return the value(s) of the last expression.
If a throw occurs that matches the tag, return the value(s)
specified in the THROW form.

(throw tag expr ...)

Throw to a tag established by the "catch" form.  In the process of
unwinding the stack, evaluate any cleanup forms associated with
unwind-protect forms  established between the target catch and
the THROW form.

(throw-error arg)

Throw an error.  This is basically equivilent to
(throw error arg) except that care is taken to make sure
that recursive errors are not produced if there is no
corresponding CATCH for the ERROR tag.

(unwind-protect pexpr expr ...)

Evaluate pexpr (the protected expression) and then the other
expressions and return the value(s) of pexpr.  If an error or
a THROW occurs during the evaluation of the protected form,
the other expressions (known as cleanup forms) are evaluated
during the unwind process.





Binding Forms


(let [name] bindings body)

Bindings should have the form

((variable init) ...)

where each init is an expression, and body should be a sequence
of one or more expressions. The inits are evaluated in the current
envirnoment, the variables are bound to fresh locations holding
the results, the body is evaluated in the extended environment,
and the value of the last expression of body is returned. Each
binding of a variable has body as its region.

If a name is supplied, a procedure that takes the bound variables
as its arguments and has the body of the LET as its body is bound
to that name.

(let* bindings body)

Same as LET except that the bindings are done sequentially from
left to right and the bindings to the left are visible while
evaluating the initialization expressions for each variable.

(letrec bindings body)

Bindings should have the form

((variable init) ...)

and body should be a sequence of one or more expressions.
The variables are bound to fresh locations holding undefined 
values; the inits are evaluated in the resulting environment;
each variable is assigned to the result of the corresponding
init; the body is evaluated in the resulting environment;
and the value of the last expression in body is returned.
Each binding of a variable has the entire letrec expression
as its region, making it possible to define mutually
recursive procedures. One restriction of letrec is very
important: it must be possible to evaluate each init without
referring to the value of any variable. If this restriction
is violated, then the effect is undefined, and an error may
be signalled during evaluation of the inits. The restriction
is necessary because ulisp passes arguments by value rather
than by name. In the most common uses of letrec, all the inits
are lambda expressions and the restriction is satisfied
automatically.


(let-values bindings body)

Analogous to let with multiple values in variable bindings.  For
example,

> (let-values ([(a b) (values 1 2)]
               [(c d) (values 3 4)])
     (list a b c d))                      => (1 2 3 4)

> (let ([a 1] [b 2] [c 3] [d 4])
    (let-values ([(a b) (values c d)]
                 [(c d) (values a b)])
      (list a b c d)))                    => (3 4 1 2)


(let*-values bindings body)

Analogous to let* with multiple values in variable bindings.  For
example,

>  (let ([a 1] [b 2] [c 3] [d 4])
    (let*-values ([(a b) (values c d)]
                  [(c d) (values a b)])
      (list a b c d)))                    => (3 4 3 4)



(fluid-let bindings body)

This macro emulates dynamic binding.  The variables are saved before
they are bounded in the new fluid-let environment.  The variables
with new bindings are set back, unwinded, to the old values when the
fluid-let environment is closed.  For example,

(set x 0)
(define (printx) (print x))
(fluid-let ([x 1])
   (printx))                => 1
(let ([x 1])
   (printx))                => 0





Begin Code Block


(begin expression...)

The expressions are evaluated sequentially from left to right,
and the value of the last expression is returned. This expression
type is used to sequence side effects such as input and output.




Delayed Evaluation


(cons-stream expr1 expr2)

Create a cons stream whose first element is expr1 (which is evaluated
immediately) and whose remaining elements is expr2 (whose evaluation is
delayed until "cdr" is called). 

(car expr)

Returns the first element of a stream.

(cdr-stream expr)

Returns the remaining elements of a stream by calling FORCE on the promise
created by cons-stream.

(delay expression)

Evaluating this expression creates a "promise" to evaluate
expression at a later time.

(force promise)

Applying "force" to a promise generated by DELAY requests that
the promise produce the value of the expression passed to DELAY.
The first time a promise is FORCEed, the DELAY expression is
evaluated and the value stored. On subsequent calls to FORCE
with the same promise, the saved value is returned.





Iteration


(while test expression ...)

While is an iteration construct. Each iteration begins by evaluating
test; if the result is false, then the loop terminates and the value
of test is returned as the value of the while expression. If test
evaluates to a true value, then the expressions are evaluated in
order for effect and the next iteration begins.



Definitions


(def name formals body)

Define a new procedure (or as in common lisp defines a new function) with
the name "name", and formals as specified in LAMBDA. 

(def-macro name formals body) 


(define variable expression)

Define a variable and give it an initial value.

(define (variable . formals) body)

Define a procedure.  Formals should be specified in the same way
as with LAMBDA.

(define-macro (name . formals) body)

Defines a macro with the specified name.



List Functions


(cons expr1 expr2)

Create a new cons pair whose car is expr1 and whose cdr is expr2.

(acons key data alist)

Is equivilent to (cons (cons key data) alist) and is used to
add a pair to an association list.

(car pair)

Extract the car of a cons pair.

(cdr pair)

Extract the cdr of a cons pair.

(C..R pairs)
{caar, cadr, cdar, cddr}
{caaar, caadr, caddr, cdddr}
{cadddr, cddddr}

These functions are short for combinations of CAR and CDR.
Each 'x' is stands for either 'A' or 'D'. An 'A' stands for
the CAR function and a 'D' stands for the CDR function. For
instance, (cadr x) is the same as (car (cdr x)).

Extract the specified elements of a list.

(list expr...)

Create a list whose elements are the arguments to the function.
This function can take an arbitrary number of arguments. Passing
no arguments results in the empty list.

(list* expr...)

Create a list whose elements are the arguments to the function
except that the last argument is used as the tail of the list.
This means that the call (list* 1 2 3) produce the result (1 2 . 3).

(append list...)

Append lists to form a single list. This function takes an
arbitrary number of arguments. Passing no arguments results
in the empty list.

(reverse list)

Create a list whose elements are the same as the argument
except in reverse order.

(last list)

Return the last element in the list.

(last-pair list)

Return the last pair in a list.

(length list)

Compute the length of a list.

(pairlis keys data &optional alist)

Creates pairs from corresponding elements of keys and data
and pushes these onto alist.

For instance:

	(pairlis '(x y) '(1 2) '((z . 3)))  =>  ((x . 1) (y . 2) (z . 3))

(copy-list list)

Makes a top level copy of the list.

(copy-tree list)

Make a deep copy of a list.

(copy-alist alist)

Copy an association list by copying each top level pair in the list.

(end? list)

Returns nil for a pair, #t for the empty list and signals an
error for all other types.

(member expr list)
(memv expr list)
(memq expr list)

Find an element in a list. Each of these functions searches
the list looking for an element that matches expr. If a matching
element is found, the remainder of the list starting with that
element is returned. If no matching element is found, the empty
list is returned. The functions differ in the test used to
determine if an element matches expr. The MEMBER function
uses EQUAL?, the MEMV function uses EQV? and the MEMQ
function uses EQ?.

(assoc expr alist)
(assv expr alist)
(assq expr alist)

Find an entry in an association list. An association list
is a list of pairs. The car of each pair is the key and
the cdr is the value. These functions search an association
list for a pair whose key matches expr. If a matching pair
is found, it is returned. Otherwise, the empty list is
returned. The functions differ in the test used to determine
if a key matches expr. The ASSOC function uses EQUAL?,
the ASSV function uses EQV? and the ASSQ function uses EQ?.

(list-ref list n)

Return the nth element of a list (zero based).

(list-tail list n)

Return the sublist obtained by removing the first n elements of list.



Destructive List Functions


(set-car! pair expr)

Set the car of a pair to expr. The value returned by this procedure
is unspecified.

(set-cdr! pair expr)

Set the cdr of a pair to expr. The value returned by this procedure
is unspecified.

(append!  list...)

Append lists destructively.




Sequence Functions


At the moment these sequence functions work only with lists.

(mapc)

(mapcan)

(maplist)

(mapl)

(mapcon)

(some)

(every)

(notany)

(notevery)

(find)

(find-if)

(find-if-not)

(member)

(member-if)

(member-if-not)

(assoc)

(assoc-if)

(assoc-if-not)

(rassoc)

(rassoc-if)

(rassoc-if-not)

(remove)

(remove-if)

(remove-if-not)

(delete)

(delete-if)

(delete-if-not)

(count)

(count-if)

(count-if-not)

(position)

(position-if)

(position-if-not)




Symbol Functions


(bound? sym [ env])

Returns #t if a global value is bound to the symbol and nil otherwise.

(symbol-name sym)

Get the print name of a symbol.

(symbol-value sym [env])

Get the global value of a symbol.

(set-symbol-value! sym expr [env])

Set the global value of a symbol. The value returned by this procedure
is unspecified.

(symbol-plist sym)

Get the property list associated with a symbol.

(set-symbol-plist! sym plist)

Set the property list associate with a symbol. The value returned by
this procedure is unspecified.

(symbol-module sym)

Returns the module containing the symbol.

(gensym &optional sym | str | num)

Generate a new, uninterned symbol. The print name of the symbol
will consist of a prefix with a number appended. The initial
prefix is "G" and the initial number is 1. If a symbol is
specified as an argument, the prefix is set to the print
name of that symbol. If a string is specified, the prefix
is set to that string. If a number is specified, the numeric
suffix is set to that number. After the symbol is generated,
the number is incremented so subsequent calls to GENSYM will
generate numbers in sequence.

(get sym prop)

Get the value of a property of a symbol. The prop argument is
a symbol that is the property name. If a property with that name
exists on the symbols property list, the value of the property
is returned. Otherwise, the empty list is returned.

(put sym prop expr)

Set the value of a property of a symbol. The prop argument is
a symbol that is the property name. The property/value
combination is added to the property list of the symbol.

(remprop sym prop)

Remove the specified property from the property list of the symbol.



Module Functions


These routines are Common Lisp like package functions for Scheme
modules.  They may currently be too unstable to be used in practice.
Use with caution.

(make-module name &key uses)

(find-module name)

(list-modules)

(module-name name)

(module-nicknames name)

(in-module name)

(use-module name [module])

(unuse-module name [module])

(module-use-list name)

(module-used-by-list name)

(export sym [module])

(unexport sym [module])

(import sym [module])

(intern module-name [module])

(unintern sym [module])

(make-symbol name)

(find-symbol sym [module])


Module example.

> ulisp
; ulisp-0.4
> (make-module "FOO")
#
> (in-module "FOO")
#
> (set x 1)          ; cannot perform (set FOO::x 1) as you should ...
x
> (set! FOO::x 10)   ; performing (set FOO::x 10) aborts ulisp ....
10
> FOO::x
10
> x
10
> (in-module "lisp")
> x
error: unbound variable - x
...
>

Currently, these "module" routines may be too rigid to use in practice.
However, you can move between modules okay if you only set variables
without using the fully scoped name, eg., without a variable like foo::x,
and use (set x 1) as in the example above.  You can set a variable across
modules using the set! function, eg., (set! foo::x 2).



Examples:


> (set x (gensym))
x
> x
#:G4
> (symbol-value x)
*unbound*
> (set-symbol-value! x 2)
2
> (bound? x)
#t
> (symbol-value x)
2
> x
#:G4
> (set-symbol-value! x (lambda (n) (+ n 1)))
#<Procedure #x0x7fd5bd96f490>
> (eval x)
#<Procedure #x0x7fd5bd96f490>
> ((symbol-value x) 5)
6
> ((eval x) 8)
9
>



Vector Functions


(vector expr...)

Create a vector whose elements are the arguments to the function.
This function can take an arbitrary number of arguments. Passing
no arguments results in a zero length vector.

(make-vector len)

Make a vector of the specified length.

(vector-length vect)

Get the length of a vector.

(vector-ref vect n)

Return the nth element of a vector (zero based).

(vector-set! vect n expr)

Set the nth element of a vector (zero based).



Array Functions


(make-array d1 d2...)

Make an array (vector of vectors) with the specified dimensions.
At least one dimension must be specified.

(array-ref array s1 s2...)

Get an array element. The sn arguments are integer subscripts
(zero based).

(array-set! array s1 s2... expr)

Set an array element. The sn arguments are integer subscripts
(zero based).



Table Functions


(make-table &optional size)

Make a table with the specified size.  The size defaults to
something useful hopefully.  These table functions are similar
to the hash-table functions, ie., table-set! is similar to
hash-table-set!.

(table-ref table key)

Find the value in the table associated with the specified key.

(table-set! table key value)

Set the value in the table associated with the specified key.
The key in the table is a hashed value.

(table-remove! table key)

Remove the entry with the specified key from the table.
Return the old value associated with the key or nil if
the key is not found.

(empty-table! table)

Remove all entries from a table.

(map-table-entries table fun)

Apply the specified function to each entry in the table
and return the list of values.  The function should take
two arguments.  The first is the key and the second is
the value associated with that key.


Conversion Functions


(symbol->string sym)

Convert a symbol to a string. Returns the print name of
the symbol as a string.

(string->symbol str)

Convert a string to a symbol. Returns a symbol with the
string as its print name. This can either be a new symbol
or an existing one with the same print name.

(vector->list vect)

Convert a vector to a list. Returns a list of the elements
of the vector.

(list->vector list)

Convert a list to a vector. Returns a vector of the elements
of the list.

(string->list str)

Convert a string to a list. Returns a list of the characters
in the string.

(list->string list)

Convert a list of character to a string. Returns a string whose
characters are the elements of the list.

(char->integer char)

Convert a character to an integer. Returns the ASCII code of
the character as an integer.

(integer->char n)

Convert an integer ASCII code to a character. Returns the
character whose ASCII code is the integer.

(string->number str &optional base)

Convert a string to a number.  Returns the value of the
numeric interpretation of the string.  The base argument
must be 2, 8, 10 or 16 and defaults to 10.

(number->string n &optional base)

Convert a number to a string.  Returns the string corresponding
to the number.    The base argument must be 2, 8, 10 or 16 and
defaults to 10.




Type Predicates


(null? expr)

Returns #t if the expression is the empty list and nil otherwise.

(atom? expr)

Returns nil if the expression is a cons and #t otherwise.

(list? expr)

Returns #t if the expression is either a cons or the empty list
and nil otherwise.

(number? expr)

Returns #t if the expression is a number and nil otherwise.

(boolean? expr)

Returns #t if the expression is either #t and nil otherwise.

(cons? expr)
(pair? expr)

Returns #t if the expression is a cons pair and nil otherwise.

(symbol? expr)

Returns #t if the expression is a symbol and nil otherwise.

(real? expr)

Returns #t if the expression is a real number and nil otherwise.

(integer? expr)

Returns #t if the expression is an integer and nil otherwise.

(char? expr)

Returns #t if the expression is a character and nil otherwise.

(string? expr)

Returns # if the expression is a string and nil otherwise.

(vector? expr)

Returns #t if the expression is a vector and nil otherwise.

(table? expr)

Returns #t if the expression is a table and nil otherwise.

(procedure? expr)

Returns #t if the expression is a procedure (closure) and nil otherwise.

(port? expr)

Returns #t if the expression is a port and nil otherwise.

(input-port? expr)

Returns #t if the expression is an input port and nil otherwise.

(output-port? expr)

Returns #t if the expression is an output port and nil otherwise.

(eof-object? expr)

Returns #t if the expression is the object returned by READ upon
detecting an end of file condition and nil otherwise.

(default-object? expr)

Returns #t if the expression is the object passed as the default
value of an optional parameter to a procedure when that parameter
is omitted from a call and nil otherwise.

(environment? expr)

Returns #t if the expression is an environment and nil otherwise.



Equality Predicates


(equal? expr1 expr2)

Recursively compares two objects to determine if their components
are the same and returns #t if they are the same and nil otherwise.

(eqv? expr1 expr2)

Compares two objects to determine if they are the same object.
Returns #t if they are the same and nil otherwise. This function
does not compare the elements of lists or vectors but will
compare strings and  all types of numbers.

(eq? expr1 expr2)

Compares two objects to determine if they are the same object.
Returns #t if they are the same and nil otherwise. This function
performs a low level address compare on two objects and may
return nil for objects that appear on the surface to be the same.
This is because the objects are not stored uniquely in memory.
For instance, numbers may appear to be equal, but EQ? will
return nil when comparing them if they are stored at different
addresses. The advantage of this function is that it is faster
than the others. Symbols are guaranteed to compare correctly,
so EQ? can safely be used to compare them.



Arithmetic Functions


(identity expr)

Returns the value of expr.  This is the identity function.

(zero? n)

Returns #t if the number is zero and nil otherwise.

(positive? n)

Returns #t if the number is positive and nil otherwise.

(negative? n)

Returns #t if the number is negative and nil otherwise.

(odd? n)

Returns #t if the integer is odd and nil otherwise.

(even? n)

Returns #t if the integer is even and nil otherwise.

(exact? n)

Returns #t if the number is exact and nil otherwise.

(inexact? n)

Returns #t if the number is inexact and nil otherwise.

(truncate n)

Truncates a number to an integer and returns the resulting value.

(floor n)

Returns the largest integer not larger than n.

(ceiling n)

Returns the smallest integer not smaller than n.

(round n)

Returns the closest integer to n, rounding to even when n is
halfway between two integers.

(inc n)

Returns the result of adding one to the number.

(dec n)

Returns the result of subtracting one from the number.

(abs n)

Returns the absolute value of the number.

(gcd n1 n2...)

Returns the greatest common divisor of the specified numbers.

(lcm n1 n2...)

Returns the least common multiple of the specified numbers.
 

(set-random-seed)

Sets random seed by calling the system function srand(time()).
Returns #t.  ulisp calls srand in the main program to initialize
the rand(n) function.

(random-integer n)

Returns a random number between zero and n-1 (n must be an integer).


(+ n1 n2...)

Returns the sum of the numbers.

(- n)

Negates the number and returns the resulting value.

(- n1 n2...)

Subtracts each remaining number from n1 and returns the resulting value.

(* n1 n2...)

Multiplies the numbers and returns the resulting value.

(/ n)

Returns 1/n.

(/ n1 n2...)

Divides n1 by each of the remaining numbers and returns the
resulting value.

(quotient n1 n2...)

Divides the integer n1 by each of the remaining numbers
and returns the resulting integer quotient. This function
does integer division.

(remainder n1 n2)

Divides the integer n1 by the integer n2 and returns
the remainder.

(modulo n1 n2)

Returns the integer n1 modulo the integer n2 .

(min n1 n2...)

Returns the number with the minimum value.

(max n1 n2...)

Returns the number with the maximum value.

(sin n)

Returns the sine of the number.

(cos n)

Returns the cosine of the number.

(tan n)

Returns the tangent of the number.

(asin n)

Returns the arc-sine of the number.

(acos n)

Returns the arc-cosine of the number.

(atan x)

Returns the arc-tangent of x.

(atan y x)

Returns the arc-tangent of y/x.

(exp n)

Returns e raised to the n.

(sqrt n)

Returns the square root of n.

(expt n1 n2)

Returns n1 raised to the n2 power.

(log n)

Returns the natural logarithm of n.



Comparison Functions


(< n1 n2...)
(= n1 n2...)
(> n1 n2...)
(<= n1 n2...)
(/= n1 n2...)
(>= n1 n2...)

These functions compare numbers and return #t if the numbers
match the predicate and nil otherwise. For instance, (< x y z)
will return #t if x is less than y and y is less than z.





Logical Functions


(not expr)

Returns #t if the expression is nil and #t otherwise.




Bitwise Logical Functions


(bit-and n1 n2...)

Returns the bitwise AND of the integer arguments.

(bit-ior n1 n2...)

Returns the bitwise inclusive OR of the integer arguments.

(bit-xor n1 n2...)

Returns the bitwise exclusive OR of the integer arguments.

(bit-not n)

Returns the bitwise complement of n.

(ash n shift)

Arithmetically bitwise shift n left by the specified number of places
(or right if shift is negative).  In a right ash, the most-significant-bit
is kept preserving the sign of the integer.

(lsh n shift)

Logically bitwise shift n left by the specified number of places
(or right if shift is negative).  In a right lsh, the most-significant-bit
is zeroed.  For a left shift, the ash and lsh operations are the same.



String Functions


(make-string size)

Makes a string of the specified size initialized to nulls.

(string-length str)

Returns the length of the string.

(string-null? str)

Returns #t if the string has a length of zero and nil otherwise.

(string-append str1...)

Returns the result of appending the string arguments.
If no arguments are supplied, it returns the null string.

(string-ref str n)

Returns the nth character in a string.

(string-set str n c)

Sets the nth character of the string to c.

(substring str &optional start end)

Returns the substring of str starting at start and ending
at end (integers). The range is inclusive of start and
exclusive of end.

(string-trim bag str)

Return a string with characters that are in bag (which is also
a string) removed from both the left and right ends.

(string-left-trim bag str)

Return a string with characters that are in bag (which is also
a string) removed from the left end.

(string-right-trim bag str)

Return a string with characters that are in bag (which is also
a string) removed from right end.

(string-search str1 str2 &key start1 end1 start2 end2 from-end?)

Search for the specified substring of str1 in the specified
substring of str2 and return the starting offset when a match
is found or nil if no match is found.

(string-ci-search str1 str2 &key start1 end1 start2 end2 from-end?)

Like STRING-SEARCH but case insensitive.




String Comparison Functions


(string? str1 str2 &key start1 end1 start2 end2)
(string<=? str1 str2 &key start1 end1 start2 end2)
(string/=? str1 str2 &key start1 end1 start2 end2)
(string>=? str1 str2 &key start1 end1 start2 end2)

These functions compare strings and return #t if the strings match
the predicate and nil otherwise. For instance, (string< x y) will
return #t if x is less than y. Case is significant. #A does not
match #a.

(string-ci? str1 str2 &key start1 end1 start2 end2)
(string-ci<=? str1 str2 &key start1 end1 start2 end2)
(string-ci/=? str1 str2 &key start1 end1 start2 end2)
(string-ci>=? str1 str2 &key start1 end1 start2 end2)

These functions compare strings and return #t if the strings match
the predicate and nil otherwise. For instance, (string-ci< x y)
will return #t if x is less than y. Case is not significant.
#A matches #a.



Character Functions


(char-upper-case? ch)

Is the specified character an upper case letter?

(char-lower-case? ch)

Is the specifed character a lower case letter?

(char-alphabetic? ch)

Is the specified character an upper or lower case letter?

(char-numeric? ch)

Is the specified character a digit?

(char-alphanumeric? ch)

Is the specified character a letter or a digit?

(char-whitespace? ch)

Is the specified character whitespace?

(string ch)

Return a string containing just the specified character.

(char str [n])

Return the nth character of the string (n defaults to zero).

(char-upcase ch)

Return the uppercase equivilent to the specified character if
it is a letter.  Otherwise, just return the character.

(char-downcase ch)

Return the lowercase equivilent to the specified character if
it is a letter.  Otherwise, just return the character.

(digit->char n)

Return the character associated with the specified digit.
The argument must be in the range of zero to nine.




Character Comparison Functions


(char? ch1 ch2)
(char<=? ch1 ch2)
(char/=? ch1 ch2)
(char>=? ch1 ch2)

These functions compare characters and return #t if the characters
match the predicate and nil otherwise. For instance, (char< x y)
will return #t if x is less than y. Case is significant. #A does
not match #a.

(char-ci? ch1 ch2)
(char-ci<=? ch1 ch2)
(char-ci>=? ch1 ch2)

These functions compare characters and return #t if the characters
match the predicate and nil otherwise. For instance, (char-ci< x y)
will return #t if x is less than y. Case is not significant.
#A matchs #a.



The Reader


(read &optional port)

Reads an expression from the specified port. If no port is specified,
the current input port is used. Returns the expression read or
an object that satisfies the eof-object? predicate if it reaches
the end of file on the port.

(read-delimited-list ch &optional port)

Read expressions building a list until the first occurance of the
specified character.  Return the resulting list.

(set-macro-character! ch fun &optional non-terminating? table)

(get-macro-character ch &optional table)

(make-dispatch-macro-character ch &optional non-terminating? table)

(set-dispatch-macro-character dch ch fun &optional table)

(get-dispatch-macro-character dch ch &optional table)



The Printer


(write expr &optional port)

Writes an expression to the specified port. If no port is specified,
the current output port is used. The expression is written such that
the READ function can read it back. This means that strings will
be enclosed in quotes and characters will be printed with # notation.

(write-size expr)

Returns the number of characters in the printed representation
of the specified object when printed by the function WRITE.

(display-size expr)

Returns the number of characters in the printed representation
of the specified object when printed by the function DISPLAY.

(display expr &optional port)

Writes an expression to the specified port. If no port is specified,
the current output port is used. The expression is written without
any quoting characters. No quotes will appear around strings
and characters are written without the # notation.

(print expr ...)

Prints an expression to the console.


Input/Output Functions


(read-line &optional port)

Read a line from the specified port (which defaults to the current
input port).  Returns the line read as a string or nil if it
reaches end of file on the port.

(read-char &optional port)

Reads a character from the specified port. If no port is specified,
the current input port is used. Returns the character read or
an object that satisfies the default-object? predicate if it
reaches the end of file on the port.

(unread-char ch &optional port)

Unread the specified character.  This causes it to be the next
character read from the port.  Only one character can be
"unread" at a time.  This allows for a one character look
ahead for parsers.

(peek-char &optional port)

Peek at the next character without actually reading it.

(char-ready? &optional port)

Returns #t if a character is ready on the specified port, nil if not.

(clear-input &optional port)

Clears any buffered input on the specified port.

(read-byte &optional port)

Reads a byte from the specified port. If no port is specified, the
current input port is used. Returns the byte read or an object
that satisfies the default- object? predicate if it reaches
the end of file on the port.

(read-short &optional port)
(read-short-high-first &optional port)
(read-short-low-first &optional port)

Read signed 16 bit value from the specified port in whatever
byte order is native to the host machine.  Returns the 16 bit
value or an object that satisfies the eof-object? predicate if
it reaches the end of file on the port.  The -HIGH-FIRST
and -LOW-FIRST forms read the high and low byte first
respectively.
 
(read-long &optional port)
(read-long-high-first &optional port)
(read-long-low-first &optional port)

Read signed 32 bit value from the specified port in whatever
byte order is native to the host machine.  Returns the 32 bit
value or an object that satisfies the eof-object? predicate
if it reaches the end of file on the port. .  The -HIGH-FIRST
and -LOW-FIRST forms read the high and low byte first respectively.

(write-char ch &optional port)

Writes a character to the specified port. If no port is specified,
the current output port is used.

(write-byte ch &optional port)

Writes a byte to the specified port. If no port is specified,
the current output port is used.

(write-short n &optional port)
(write-short-high-first n &optional port)
(write-short-low-first n &optional port)

Write a signed 16 bit integer to the specified port.  If no
port is specified, the current output port is used.
The -HIGH-FIRST and -LOW-FIRST forms write the high
and low byte first respectively.

(write-long n &optional port)
(write-long-high-first n &optional port)
(write-long-low-first n &optional port)

Write a signed 32 bit integer to the specified port.  If
no port is specified, the current output port is used.
The -HIGH-FIRST and -LOW-FIRST forms write the high and
low byte first respectively.


(newline &optional port)

Starts a new line on the specified port. If no port is
specified, the current output port is used.

(fresh-line &optional port)

Starts a fresh line on the specified port.  If the output
position is already at the start of the line, FRESH-LINE does
nothing.  If no port is specified, the current output port is
used.






Format


(format port str &rest args)

If port is nil, FORMAT collects its output into a string
and returns the string.  If port is #t, FORMAT sends its
output to the current output port.  Otherwise, port should
be an output port.

~S print argument as if with WRITE
~A print argument as if with DISPLAY
~X print argument as a hexadecimal number
~% print as if with NEWLINE
~& print as if with FRESH-LINE




Output Control Functions


(print-breadth [n])

Controls the maximum number of elements of a list that will
be printed. If n is an integer, the maximum number is set to n.
If it is nil, the limit is set to infinity. This is the default.
If n is omitted from the call, the current value is returned.

(print-depth [n])

Controls the maximum number of levels of a nested list that will
be printed. If n is an integer, the maximum number is set to n.
If it is nil, the limit is set to infinity. This is the default.
If n is omitted from the call, the current value is returned.



File I/O Functions


All four of the following OPEN functions take an optional argument
to indicate that file I/O is to be done in binary mode. For binary
files, this argument should be the symbol BINARY. For text files,
the argument can be left out or the symbol TEXT can be supplied.
The following OPEN functions are built-in functions that call
C-language library routine "fopen" which requires a mode argument.

(open-input-file str ['BINARY])

Opens the file named by the string and returns an input port.

(open-output-file str ['BINARY])

Creates the file named by the string and returns an output port.

(open-append-file str ['BINARY])

Opens the file named by the string for appending returns an
output port.

(open-update-file str ['BINARY])

Opens the file named by the string for input and output
and returns an input/output port.

(file-modification-time str)

Returns the time the file named by the string was last modified.

(parse-path-string str)

Parses a path string and returns a list containing each path
entry terminated by a path separator.

(get-file-position port)

Returns the current file position as an offset in bytes from
the beginning of the file.

(set-file-position! port offset whence)

Sets the current file position as an offset in bytes from the
beginning of the file (when whence equals 0), the current file
position (when whence equals 1) or the end of the file (when
whence equals 2). Returns the new file position as an offset
from the start of the file.

(close-port port) - Closes any port.

(close-input-port port) - Closes an input port.

(close-output-port port) - Closes an output port.

(call-with-input-file str proc)

Open the file whose name is specifed by str and call proc passing
the resulting input port as an argument. When proc returns, close
the file and return the value returned by proc as the result.

(call-with-output-file str proc)

Create the file whose name is specifed by str and call proc
passing the resulting output port as an argument. When proc
returns, close the file and return the value returned by
proc as the result.

(current-input-port) - Returns the current input port.

(current-output-port) - Returns the current output port.

(current-error-port) - Returns the current error port.





String Stream Functions


(open-input-string str)

Make a stream that can be used to retrieve the characters in
the specified string.  The returned stream can be used as an
input port in any function that takes an input port as an
argument.


(open-output-string)

Make a stream that can be used as an output port in any
function that takes an output port as an argument.  The
stream accumulates characters until the GET-OUTPUT-STRING
function is called to retrieve them.

(get-output-string stream)

Returns the contents of a string output stream as a string
and clears the output stream.




Control Features


(eval expr [env])

Evaluate the expression in the global environment and return
its value.

(apply proc args)

Apply the procedure to the list of arguments and return the
result.

(map proc list...)

Apply the procedure to argument lists formed by taking
corresponding elements from each list. Form a list from
the resulting values and return that list as the result
of the MAP call.

(for-each fun list...)

Apply the procedure to argument lists formed by taking
corresponding elements from each list. The values returned
by the procedure applications are discarded. The value
returned by FOR-EACH is unspecified.

(call-with-current-continuation proc)
(call/cc proc)

Form an "escape procedure" from the current continuation
and pass it as an argument to proc. Calling the escape
procedure with a single argument will cause that argument
to be passed to the continuation that was in effect when
the CALL-WITH-CURRENT-CONTINUATION procedure was called.



Environment Functions


(the-environment)

Returns the current environment.

(procedure-environment proc)

Returns the environment from a procedure closure.

(environment-bindings env)

Returns an association list corresponding to the top most
frame of the specified environment.

(environment-parent env)

Returns the parent environment of the specified environment.

(bound? symbol [env])

Returns #t if the symbol is bound in the environment.

(symbol-value symbol [env])

Returns the value of a variable in an environment.

(set-symbol-value! symbol value [env])

Sets the value of a symbol in an environment.  The result
of the set-symbol-value! expression is unspecified.

(eval expr [env])

Evaluate the expression in the specified environment
and return its value.



Utility Functions


(load str)

Read and evaluate each expression from the specified file.

(load-noisily str)

Read and evaluate each expression from the specified file
and print the results to the current output port.

(load-fasl-file str)

Load a fasl file produced by COMPILE-FILE.

(transcript-on str)

Opens a transcript file with the specified name
and begins logging the interactive session to that file.

(transcript-off)

Closes the current transcript file.

(compile expr &optional env)

Compiles an expression in the specified environment
and returns a thunk that when called causes the expression
to be evaluated.  The environment defaults to the top level
environment if not specified.


(command-line)

Get the command line.


(get-time)

Get the current time in seconds.

(get-environment-variable name)

Get the value of the environment variable with the specified
name.  The name should be a string.  Returns the value of
the environment variable if it exists.  Otherwise, returns nil.

(exit)

Exits from ulisp back to the operating system.


(gc [ni vi])

Invokes the garbage collector and returns information on
memory usage. If ni and vi are specified, they must be integers.
Node and vector space are expanded by those amounts respectively
and no garbage collection is triggered. GC returns an array of
six values: the number of calls to the garbage collector, the
total number of nodes, the current number of free nodes, the
number of node segments, the number of vector segments and
the total number of bytes allocated to the heap.


(room)

Returns the same information as GC without actually invoking the
garbage collector.



Fast Loading


(load-fasl-file name)
(fasl-write-procedure proc &optional port)
(fasl-read-procedure &optional port)



C Records


(define-crecord name (field-definition...))

Field definition:

    (field-name type &optional size)

where type is:

    char, uchar, short, ushort, int, uint, long, ulong, str


(allocate-cmemory type size)
(free-cmemory ptr)
(foreign-pointer? ptr)
(foreign-pointer-type ptr)
(set-foreign-pointer-type! ptr type)
(foreign-pointer-type? ptr type)
(foreign-pointer-eq? ptr1 ptr2)
(get-crecord-field ptr offset type)
(get-crecord-field-address ptr offset type)
(set-crecord-field! ptr offsetl type val)
(get-crecord-string ptr offset length)
(set-crecord-string! ptr offset length str)
(get-crecord-type-size type)
 



Debugging Functions



(error string arg ...)

Reports an error condition as in Common Lisp.  Error prints
an error message and hands over control to the debugger.  The
string can contain multiple reference to the arguments as in
(error "element ~S not in current list ~S" element curr-list)     

For example,

(def factorial (n)
   (cond ([or (not (integer? n)) (< n 0)]
          (error "~S is not a valid argument to FACTORIAL." n))
         ([zero? n] 1)
         (else (* n (factorial (- n 1))))))
> (factorial -2)
error: -2 is not a valid argument to FACTORIAL.
happened in: <Code #!@>
Entering break loop
level 1>



(reset)

Returns to the top level read/eval/print loop.


(decompile proc &optional port)

Decompiles the specified bytecode procedure and displays the bytecode
instructions to the specified port.  If not specified, the port
defaults to the current output port.


(instruction-trace &rest body)

Enables bytecode level instruction tracing during the evaluation
of the expressions in the body.


(trace-on)

Starts bytecode instruction level tracing.


(trace-off)

Stops bytecode instruction level tracing.


(show-stack &optional n)

Shows the call stack leading up to an error when invoked from
a debug prompt.  Each line represents a procedure waiting for
a value.  The line is displayed in the form of a function call
with the procedure first followed by the actual values of the
arguments that were passed to the procedure.  For method invocations,
the method is first followed by the object receiving the message
followed by the arguments.  N is the number of stack levels to
display.  If unspecified, it defaults to 20.


(show-control-stack &optional n)

Shows frames on the continuation stack.  N is the number of stack
levels to display.  If unspecified, it defaults to 20.


(show-value-stack &optional n)

Shows frames on the value stack.  N is the number of stack levels
to display.  If unspecified, it defaults to 20.





System Functions


(%car pair)
(%cdr pair)
(%set-car! pair expr)
(%set-cdr! pair expr)
(%vector-length vect)
(%vector-ref vect n)
(%vector-set! vect n expr)

These functions do the same as their counterparts without the
leading '%' character. The difference is that they don't check
the type of their first argument. This makes it possible to examine
data structures that have the same internal representation as pairs
and vectors. It is *very* dangerous to modify objects using these
functions and there is no guarantee that future releases of ulisp
will represent objects in the same way that the current version does.

(%vector-base vect)

Returns the address of the base of the vector storage.

(%address-of expr)

Returns the address of the specified object in the heap.

(%format-address addr)

Returns the address of an object as a string formated for output
as a hex number.



Functions to Access to C Structures



First, a macro to define a C Record:

(define-crecord name (field-definition...))

Where field-definition is:

(fieldname type &optional size)

Where type is one of:

char, uchar, short, ushort, int, uint, long, ulong, ptr

Instead of a single field, a field-definition can be a list of field
definitions.  In this case, each field in the list occupies the same
space in the crecord and the size of the union field is the maximum
of the sizes of each of the component fields.

DEFINE-CRECORD creates the following macros:

(make-name &optional size) --> cpointer
(name-address rec i) --> cpointer

and for each field:

(name-fieldname rec &optional i) --> fieldvalue
(name-fieldname-address rec) --> cpointer to field
(set-name-fieldname! rec value &optional i)

as well as the following variables:

name-size for the size of the entire record
name-fieldname-offset for the offset to the start of each field

Note: If the optional i parameter is supplied for one of the SET- macros,
it's position is reversed with value so the calling syntax is really:

(set-name-fieldname! rec i value)

For example:

(define-crecord foo
  ((a ptr)
   (b long 10)))

defines the macros:

(make-foo &optional size)
(foo-address rec i)
(foo-a rec &optional i)
(foo-b-address rec &optional i)
(set-foo-a! rec value &optional i)
(foo-b rec &optional i)
(foo-b-address rec &optional i)
(set-foo-b! rec value &optional i)

and the variables:

foo-size
foo-a-offset
foo-b-offset

Supporting functions:

(allocate-cmemory size) --> cpointer

(free-cmemory cpointer)

(get-crecord-field cpointer offset type-id)

(get-crecord-field-address cpointer offset) --> cpointer

(set-crecord-field! cpointer offset type-id value)

(get-crecord-string cpointer offset length) --> string

(set-crecord-string! cpointer offset length string)

(get-crecord-type-size type-id) --> size

(null-pointer? cpointer) --> nil if pointer has been freed

(crecord-type type-symbol) --> type-id



Dynamically Load Library


(load-library library-name)

Load a dynamic library at runtime.  Library-name is the
name of the dynamic library.  For example,

(load-library "liblispext.so.1")