This document has two parts:
As an aid to finding things, here are some alphabetical indexes for entries in the dictionary.
Index for commands that are part of the R5 standard:
Index for commands that are Pixie Scheme III enhancements that begin with "e::":
Index for commands that are Pixie Scheme III enhancements that begin with "c::":
This portion of the document is a command summary of the procedures, special forms, macros, and the like, that are provided as part of Pixie Scheme III. It includes all of the standard Scheme stuff that Pixie Scheme III provides, and also includes many other items that I have provided as enhancements.
The command summary is a supplement to the "R5 report", but definitely not a substitute for it.
The descriptions herein are specific to Pixie Scheme III. Pixie Scheme III generally follows the "R5" Scheme report, but there are many places in that report where some behavior of Scheme is left undefined, or is allowed to be implementation-dependent. In those cases, this document describes what Pixie Scheme III does. For example, the R5 report often does not define the return values of procedures that are called for side effects: Pixie Scheme III generally returns #t from such procedures, and the descriptions herein so indicate.
The command summary is arranged alphabetically, with a few exceptions. First, procedures that are enhancements -- that is, they are not part of R5 Scheme -- are listed at the very end. Their identifiers all begin with either "e::" or "c::". The procedures that begin with "e::" come before the procedures that begin with "c::".
Second, a few closely-related groups of procedures are presented together. They include:
There are other such groups.
Pixie Scheme III does contain procedures and such that are not documented here; I have omitted many things used internally by the compiler, macro-generator, and so on, because they are complicated and more than likely to change in subsequent releases. I do not personally regard them as secrets. If you find something undocumented that you would like to know more about, send me EMail and ask, but don't count on any undocumented feature continuing to exist in future releases of Pixie Scheme III.
General notes about the command summary entries:
And now, on to the command summary itself ...
Type:
Procedure.
Operation:
Arithmetic multiplication.
Arguments:
Zero or more numbers.
Side Effects:
None.
Returned Value:
A number: With two or more arguments, returns their product. With one argument, returns just the argument. With no arguments, returns 1.
For Example:
(* 2 3) ;; ==> 6 (* 1 2 3 4 5) ;; ==> 120 (* 2.5) ;; ==> 2.5 (*) ;; ==> 1
Type:
Procedure.
Operation:
Arithmetic addition.
Arguments:
Zero or more numbers.
Side Effects:
None.
Returned Value:
A number: The sum of its arguments, or 0 if there are no arguments.
For Example:
(+ 2 3) ;; ==> 5 (+ 1 2 3 4 5) ;; ==> 15 (+ 2.5) ;; ==> 2.5 (+) ;; ==> 0
Type:
Procedure.
Operation:
Arithmetic subtraction.
Arguments:
One or more numbers.
Side Effects:
None.
Returned Value:
A number: With two or more arguments, returns the first argument minus the sum of all the rest. With one argument, returns the argument subtracted from zero.
For Example:
(- 2 3) ;; ==> -1 (- 1 2 3 4 5) ;; ==> -13 (- 2.5) ;; ==> -2.5 (-) ;; ==> <error>
Type:
Procedure.
Operation:
Arithmetic division.
Arguments:
One or more numbers.
Side Effects:
None.
Returned Value:
A number: With two or more arguments, returns the first argument divided by the product of all the rest. With one argument, returns its reciprocal. Returns a nan or an inf, as appropriate, for any attempt to divide by zero.
For Example:
(/ 6 3) ;; ==> 2 (/ 3 4 5) ;; ==> 0.15 (/ .5) ;; ==> 2. (/) ;; ==> <error> (/ 0) ;; ==> <error> (/ 2 0) ;; ==> <error> (/ 2 3 4 0 5) ;; ==> <error>
Type:
Procedure.
Operation:
Arithmetic comparison: Less than.
Arguments:
Two or more real numbers.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, each argument is less than the one to its right. Otherwise, returns #f. Ignores the exactness of the arguments.
For Example:
(< 2 3) ;; ==> #t (< 3 2) ;; ==> #f (< 2 2) ;; ==> #f (< 2 3 4) ;; ==> #t (< 4 3 2) ;; ==> #f
Type:
Procedure.
Operation:
Arithmetic comparison: Less than or equal to.
Arguments:
Two or more real numbers.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, each argument is less than or equal to the one to its right. Otherwise, returns #f. Ignores the exactness of the arguments.
For Example:
(<= 2 3) ;; ==> #t (<= 3 2) ;; ==> #f (<= 2 2) ;; ==> #t (<= 2 3 4) ;; ==> #t (<= 4 3 2) ;; ==> #f
Type:
Procedure.
Operation:
Arithmetic comparison: Equality
Arguments:
Two or more numbers.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, all arguments are arithmetically equal. Otherwise, returns #f. Ignores the exactness of the arguments.
For Example:
(= 2 3) ;; ==> #f (= 3 2) ;; ==> #f (= 2 2) ;; ==> #t (= 2 3 4) ;; ==> #f (= 4 3 2) ;; ==> #f (= 4 (+ 2 2) (/ 20 5)) ;; ==> #t
Type:
Procedure.
Operation:
Arithmetic comparison: Greater than.
Arguments:
Two or more real numbers.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, each argument is greater than the one to its right. Otherwise, returns #f. Ignores the exactness of the arguments.
For Example:
(> 2 3) ;; ==> #f (> 3 2) ;; ==> #t (> 2 2) ;; ==> #f (> 2 3 4) ;; ==> #f (> 4 3 2) ;; ==> #t
Type:
Variable.
Operation:
The operation of Pixie Scheme III sets or binds this variable to the third most recent quantity whose value was printed out by the "print" part of the top-level read-eval-print loop. That is, the variable is the previous value of >**<, which is in turn the previous value of >*<, which is the most recent quantity printed out by the read-eval-print loop. This quantity is updated after the print has taken place; it may be used while Pixie Scheme III is evaluating an expression in the "read" part of the read-eval-print loop. It forms part of a rudimentary command-history mechanism that is contained within Pixie Scheme III.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
(+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >***< ;; has the value 1.
Type:
Variable.
Operation:
The operation of Pixie Scheme III sets or binds this variable to the next-to-last quantity whose value was printed out by the "print" part of the top-level read-eval-print loop. That is, the variable is the previous value of >*<, which is the most recent quantity printed out by the read-eval-print loop. This quantity is updated after the print has taken place; it may be used while Pixie Scheme III is evaluating an expression in the "read" part of the read-eval-print loop. It forms part of a rudimentary command-history mechanism that is contained within Pixie Scheme III.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
(+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >**< ;; has the value 2.
Type:
Variable.
Operation:
The operation of Pixie Scheme III sets or binds this variable to the last quantity whose value was printed out by the "print" part of the top-level read-eval-print loop. The quantity is updated after the print has taken place; it may be used while Pixie Scheme III is evaluating an expression in the "read" part of the read-eval-print loop. It forms part of a rudimentary command-history mechanism that is contained within Pixie Scheme III.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
(+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >*< ;; has the value 3.
Type:
Variable.
Operation:
The operation of Pixie Scheme III sets or binds this variables to the third most recent Scheme expression that was passed as input to the "read" part of the top-level read-eval-print loop. That is, the variable is the previous value of >++<, which is in turn the previous value of >+<, which is the most recent quantity provided as input to the read-eval-print loop. This quantity is updated after the print has taken place; it may be used while Pixie Scheme III is evaluating an expression in the "read" part of the read-eval-print loop. It forms part of a rudimentary command-history mechanism that is contained within Pixie Scheme III.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
(+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >+++< ;; has the value (+ 0 1).
Type:
Variable.
Operation:
The operation of Pixie Scheme III sets or binds this variables to the next-to-last Scheme expression that was passed as input to the "read" part of the top-level read-eval-print loop. That is, the variable is the previous value of >+<, which is the most recent quantity provided as input to the read-eval-print loop. This quantities is updated after the print has taken place; it may be used while Pixie Scheme III is evaluating an expression in the "read" part of the read-eval-print loop. It forms part of a rudimentary command-history mechanism that is contained within Pixie Scheme III.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
(+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >++< ;; has the value (+ 0 2).
Type:
Variable.
Operation:
The operation of Pixie Scheme III sets or binds this variables to the last Scheme expression that was passed as input to the "read" part of the top-level read-eval-print loop. This quantity is updated after the print has taken place; it may be used while Pixie Scheme III is evaluating an expression in the "read" part of the read-eval-print loop. It forms part of a rudimentary command-history mechanism that is contained within Pixie Scheme III.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
(+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >+< ;; has the value (+ 0 3).
Type:
Variable.
Operation:
While Pixie Scheme III is evaluating a Scheme expression that was provided as input to the "read" part of the top-level read-eval-print loop, ">-<" is bound to that expression itself. This value will become the value of ">+<" after the expression has been evaluated and its result printed.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
(+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, the value of >-< is undefined. ;; But suppose you type (define a (list >-<)) ;; and then type return. Then, while the "define" ;; is being evaluated, >-< will have the value ;; (define a (list >-<)), so when you subsequently ;; type a ;; Pixie Scheme III will print ((define a (list >-<)))
Type:
Procedure.
Operation:
Arithmetic comparison: Greater than or equal to.
Arguments:
Two or more real numbers.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, each argument is greater than or equal to the one on its right. Otherwise, returns #f. Ignores the exactness of the arguments.
For Example:
(>= 2 3) ;; ==> #f (>= 3 2) ;; ==> #t (>= 2 2) ;; ==> #t (>= 2 3 4) ;; ==> #f (>= 4 3 2) ;; ==> #t
Type:
Procedure.
Operation:
Arithmetic absolute value.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
A number:
The absolute value of the argument.
For Example:
Type:
Procedure.
Operation:
Mathematical inverse cosine, or arc-cosine, function.
Arguments:
One number, in the range [-1, 1].
Side Effects:
None.
Returned Value:
A number:
A number in the range [0, pi], taken as an angle in radians, whose
cosine is the argument.
For Example:
Type:
Operation:
Boolean and.
Arguments:
Zero or more Scheme objects of any kind.
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, all the arguments are true.
(Recall that the only Scheme object that is false is #f.)
With no arguments, returns #t.
Otherwise, returns #f.
This macro operates by evaluating its arguments one
at a time, from left to right. When and if any argument
evaluates to false, "and" returns false immediately, without
evaluating any more arguments.
For Example:
Type:
Procedure.
Operation:
Obtain the angle of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The angle of the number.
For Example:
Type:
Procedure.
Operation:
Appends lists; that is, glues them together, head-to-tail.
The last object "glued" need not be a list.
Arguments:
One or more arguments: All but the last of these must be proper lists.
(A proper list is one that has finite length and is terminated by the
empty list.) The last argument may be any Scheme object.
Side Effects:
None.
Returned Value:
Any Scheme object:
With one argument, returns the argument.
With more than one argument, builds a list from all but the last argument, by
making copies of all of these lists and joining them in order, then makes the
last argument be the cdr of the list so constructed, and returns that list.
For Example:
Type:
Procedure.
Operation:
Calls a procedure with a list of arguments.
Arguments:
Two or more arguments: The first must be a procedure,
the last must be a proper list, and each of the others, if any,
may be any Scheme object.
Side Effects:
None by itself, though the procedure applied may cause side effects of its own.
Returned Value:
Any Scheme object:
Calls the given procedure -- the first argument -- with a list of
arguments built as follows:
With two arguments, as in (apply proc args), where args is a list,
"proc" is called with "args" as its arguments.
With more than two arguments, as in (apply proc arg1 arg2 ... argn args),
"proc" is called with the argument list (append (list arg1 arg2 ... argn) args).
For Example:
Type:
Procedure.
Operation:
Mathematical inverse sine, or arc-sine, function.
Arguments:
One number, in the range [-1, 1].
Side Effects:
None.
Returned Value:
A number:
A number in the range [-pi/2, pi/2], taken as an angle in radians, whose
sine is the argument.
For Example:
Type:
Procedure.
Operation:
Look up a key-value pair in a list thereof, using "equal?" as the
predicate for testing for the presence of the key.
Arguments:
Two arguments: The first may be any Scheme object; the second must be
a proper list of pairs.
Side Effects:
None.
Returned Value:
A pair:
Returns the first pair in the second argument whose car is "equal?" to the first
argument, or returns #f if there is no such pair.
For Example:
Type:
Procedure.
Operation:
Look up a key-value pair in a list thereof, using "eq?" as the
predicate for testing for the presence of the key.
Arguments:
Two arguments: The first may be any Scheme object; the second must be
a proper list of pairs.
Side Effects:
None.
Returned Value:
A pair:
Returns the first pair in the second argument whose car is "eq?" to the first
argument, or returns #f if there is no such pair.
For Example:
Type:
Procedure.
Operation:
Look up a key-value pair in a list thereof, using "eqv?" as the
predicate for testing for the presence of the key.
Arguments:
Two arguments: The first may be any Scheme object; the second must be
a proper list of pairs.
Side Effects:
None.
Returned Value:
A pair:
Returns the first pair in the second argument whose car is "eqv?" to the first
argument, or returns #f if there is no such pair.
For Example:
Type:
Procedure.
Operation:
Mathematical inverse tangent, or arc-tangent, with one or two arguments.
The two-argument version is called "atan2" by some.
Arguments:
One or two numbers.
Side Effects:
None.
Returned Value:
A number:
With one argument, returns a number in the range [-pi/2, pi/2], taken as an angle in radians, whose
tangent is the argument.
With two numbers, takes the arguments to be the coordinates of a point in the x/y plane, with the
first argument being y and the second argument being x, and returns a number in the range
(-pi, pi] which is the angle between the positive x-axis and the radius vector to that point.
(The angle returned is negative if, and only if, y is negative.)
Note that (atan 0 0) returns 0. (The "R5" Scheme report appears to indicate that (atan 0 0) should return
a value, but does not indicate what it should be.)
For Example:
Type:
Operation:
Evaluate a sequence of Scheme expressions in the order given.
Arguments:
One or more Scheme expressions of any kind.
Side Effects:
None.
Returned Value:
Any Scheme object:
Causes the evaluation each of its arguments in turn, and returns
whatever resulted from the evaluation of the last argument.
Note that "begin" does not create a new environment: Each evaluation
that "begin" causes takes place in the environment where the "begin"
was encountered.
For Example:
Type:
Procedure.
Operation:
Test whether its argument is a boolean.
Arguments:
One Scheme object of any kind.
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, the argument is either #t or #f. Returns #f otherwise.
For Example:
Type:
Procedure.
Operation:
Creates an unnamed procedure of one argument, which
encapsulates the current continuation in such a way that when that
unnamed procedure is subsequently called, it will change the
continuation that was present when the unnamed procedure was called to
the continuation which is encapsulated. The unnamed procedure is
passed as an argument to the procedure which is the argument to
"call-with-current-continuation".
A continuation is in essence the entire internal state of the Scheme
system. Thus when the unnamed procedure is called, it restores that
state to whatever the state was when the unnamed procedure was
created. If "call-with-current-continuation" was called during the
middle of the execution of a particular Scheme procedure -- let's
suppose that its name is "foo" -- then when the unnamed procedure
thereby created is called, it will be as if "foo" was still running;
"foo" will pick up right where "call-with-current-continuation" was
called.
Recall that the unnamed procedure takes one argument. When it is
called, whatever argument it was given appears in the restored
continuation as if it had been returned from
"call-with-current-continuation".
See the examples below for more details.
There is one rather technical caveat about the operation of
"call-with-current-continuation": When the environment -- a
complicated table of variable identifiers and their values -- is
encapsulated into the current continuation, it is not copied; what is
placed in the continuation is a reference, a pointer to the real
environment. It is entirely possible that other Scheme procedures,
such as "set!", will modify the real environment before the unnamed
function created by "call-with-current-continuation" is called. Since
the environment may have been modified, it is not correct to say that
calling the unnamed function is guaranteed to restore the internal
state of Scheme to what it was when the unnamed function was created.
The reason why the environment is not copied is that environments may
be very large objects: They include everything in Scheme's memory that
is not garbage. Thus there will often not be enough memory available
to make a copy.
Arguments:
One argument, which must be a procedure that itself takes one argument.
Side Effects:
Saves the current state of Scheme in such a way that it can subsequently
be restored at will.
Returned Value:
Any Scheme object, or may never return:
The value returned will be either what the argument to
"call-with-current-continuation" returns, or will be whatever value
was passed to the unnamed procedure when -- and if -- that unnamed
procedure was itself called.
For Example:
This first example is rather trivial. In it, the unnamed
procedure prepared by "call-with-current-continuation" is passed as an
argument to the predicate "procedure?", which does not call it --
"procedure?" simply affirms that that unnamed procedure is in fact a
procedure, by returning #t.
The second example is from the "R5" report. Let's discuss it in
detail.
The procedure which is the argument to "call-with-current-continuation"
begins on the second line of the example; it is the lambda expression
that starts with "(lambda (exit) ...". The unnamed procedure created
by "call-with-current-continuation" is passed to that lambda expression
as an argument, and the lambda gives the unnamed procedure a name --
"exit".
The lambda expression itself uses the "for-each" procedure with
another, shorter lambda expression, to test each number in the list of
six numbers in the sixth line, to see whether it is negative. If the
number is not negative, nothing happens -- the lambda expression goes
on to the next number. If no number were negative, the "for-each"
procedure that is running the test would end, and the outer lambda
expression would returns #t, from the seventh line, so that
"call-with-current-continuation" would thereby returns #t.
However, one of the numbers -- the fourth one -- is in fact negative;
it's -3. When the test encounters it, the "if" will call "exit" with
a value of -3. Since "exit" has as value the unnamed procedure
originally created by "call-with-current-continuation", "exit" will
immediately restore the continuation where it was created, and in
effect, "call-with-current-continuation" will returns immediately, with
a value of -3.
There are perhaps easier ways to find the first negative number in a
list. Notwithstanding, this example illustrates how
"call-with-current-continuation" can be used to returns a meaningful
value from deep within a function, without somehow going back through
all the intervening code. This facility is useful, for example, in
reporting errors in a complicated process.
Continuations are complicated and confusing. It is unlikely that any
introduction to them that is as short as this one can succeed in
describing continuations adequately to a person who is not already
familiar with them.
Type:
Procedure.
Operation:
Allow a procedure which returns multiple values to pass them as arguments
to another procedure.
Arguments:
Two procedures. The first may return multiple values, via the
"values"
procedure. The second is the procedure to which the multiple values are
intended to be passed; it will receive them as if they had been entered
as individual arguments with the usual procedure-call syntax.
Side Effects:
None.
Returned Value:
Any Scheme object, or may not return: "call-with-values" in effect passes
control to its second argument, and returns if and only if that procedure does,
returning whatever that procedure returns.
For Example:
Type:
Procedure.
Operation:
Obtain the car of a pair.
Arguments:
One pair.
Side Effects:
None.
Returned Value:
Any Scheme object:
The car of the argument.
For Example:
Type:
Procedure.
Operation:
Obtain the cdr of a pair.
Arguments:
One pair.
Side Effects:
None.
Returned Value:
Any Scheme object:
The cdr of the argument.
For Example:
caaar  
caadr  
cadar  
caddr  
cdaar  
cdadr  
cddar  
cdddr  
caaaar  
caaadr  
caadar  
caaddr  
cadaar  
cadadr  
caddar  
cadddr  
cdaaar  
cdaadr  
cdadar  
cdaddr  
cddaar  
cddadr  
cdddar  
cddddr  
Type:
Procedures.
Operation:
Convenience procedures for accessing components of nested pairs.
Arguments:
One argument, which must be a pair, and whose car and cdr may also
have specific type requirements, depending on the procedure.
Side Effects:
None.
Returned Value:
Any Scheme object:
Each of these procedures is a combination (technically, a composition)
of from two to four applications of either "car" or "cdr". Two easy
ways of figuring out which combination is intended are as follows:
Split the procedure name into individual letters, drop the initial "c"
and the final "r", change each "a" into "the car of" and change each
"d" into "the cdr of". Thus for example
becomes
which becomes
which becomes
And "(cadar x)" does indeed return the car of the cdr of the car of x.
Alternatively, in a particular procedure call, split the procedure
name into individual letters, drop the initial "c" and the final "r",
change each "a" into "car" and change each "d" into "cdr", and add
enough parentheses to make sense. Thus for example:
becomes
which becomes
which becomes
which becomes
And "(cadar x)" does indeed return what "(car (cdr (car x)))" would.
Each of these procedures will report an error if its argument
does not possess the correct pair structure to have the element
that the procedure is intended to retrieve. Thus "(caddr (list 1 2))"
will report an error, because "(list 1 2)" does not have a
caddr.
For Example:
Type:
Operation:
Evaluates an expression -- the "key" -- and compares the
result (using "eqv?") to each element in the car of each of a series
of lists -- the case clauses -- in turn. If a match is found,
evaluates each element of the cdr of that case clause in left-to-right
order, and returns whatever results from the evaluation of the last
element.
If there is no match, there may be an "else" clause -- whose car is
just "else" -- as the last clause of the case. If there is an "else"
clause, evaluates each element of the cdr of the else clause in
left-to-right order, and returns whatever results from the evaluation
of the last element. If there is no match, and no else clause,
returns #t.
Arguments:
One Scheme expression, followed by one or more proper lists, each of which has
as its car either a proper list, or the symbol "else". The symbol "else" may
only appear as the car of the last proper list of the "case" expression, and that
last proper list need not necessarily begin with "else".
Side Effects:
None in its own right, but the evaluation of items in the clauses may
cause arbitrary side effects.
Returned Value:
Arbitrary, depending on the clauses; may not return at all, depending on
the clauses.
For Example:
Type:
Procedure.
Operation:
Arithmetic round up.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
An integer:
The smallest integer not smaller than the argument.
For Example:
Type:
Procedure.
Operation:
Convert a character to the integer that represents it; Pixie Scheme III uses
the ASCII standard for representing characters by integers.
Arguments:
One character.
Side Effects:
None.
Returned Value:
An integer:
The integer whose ASCII character is the argument.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is a letter of the alphabet.
Arguments:
One character/
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, the argument is a letter of the alphabet, in either upper case or lower case.
Otherwise, returns false.
For Example:
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is
less than or equal to
the integer representation of the second. Pixie Scheme III implements case-independence by converting any
argument that is an upper-case letter to lower case before proceeding with the comparison.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Converts any argument that is an upper-case letter to lower case, and
returns #t if, and only if, the integer whose ASCII character then represents
the first argument is
less than or equal to the integer whose ASCII character then represents the
second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is
less than
the integer representation of the second. Pixie Scheme III implements case-independence by converting any
argument that is an upper-case letter to lower case before proceeding with the comparison.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Converts any argument that is an upper-case letter to lower case, and
returns #t if, and only if, the integer whose ASCII character then represents
the first argument is
less than
the integer whose ASCII character then represents the second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is
equal to
the integer representation of the second. Pixie Scheme III implements case-independence by converting any
argument that is an upper-case letter to lower case before proceeding with the comparison.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Converts any argument that is an upper-case letter to lower case, and
returns #t if, and only if, the integer whose ASCII character then represents
the first argument is
equal to
the integer whose ASCII character then represents the second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is
greater than or equal to
the integer representation of the second. Pixie Scheme III implements case-independence by converting any
argument that is an upper-case letter to lower case before proceeding with the comparison.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Converts any argument that is an upper-case letter to lower case, and
returns #t if, and only if, the integer whose ASCII character then represents
the first argument is
greater than or equal to
the integer whose ASCII character then represents the second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is
greater than
the integer representation of the second. Pixie Scheme III implements case-independence by converting any
argument that is an upper-case letter to lower case before proceeding with the comparison.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Converts any argument that is an upper-case letter to lower case, and
returns #t if, and only if, the integer whose ASCII character then represents
the first argument is
greater than
the integer whose ASCII character then represents the second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Convert a character to lower case.
Arguments:
One character.
Side Effects:
None.
Returned Value:
A character: If the argument is an upper case letter, returns it in lower case, otherwise returns it unchanged.
For Example:
Type:
Procedure.
Operation:
Test whether an alphabetic character is in lower case.
Arguments:
One alphabetic character.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is in lower case. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a character is a decimal digit.
Arguments:
One character.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a decimal digit. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether there is a character or an eof-object ready to read on a port.
Arguments:
Either none, or one port.
Side Effects:
None.
Returned Value:
A boolean:
The procedure performs a test for whether or not there is a character to be
read from a port. If there is an argument, it is taken to be the port to be
tested. If not, the port tested is whatever is returned by the procedure
"current-input-port".
Returns #t if, and only if, there is either a character to be read from the
port, or the port will return an end-of-file object. Otherwise, returns #f.
Interactive ports, such as the console (keyboard) will never return an
end-of-file object.
For Example:
Type:
Procedure.
Operation:
Convert a character to upper case.
Arguments:
One character.
Side Effects:
None.
Returned Value:
A character: If the argument is a lower case letter, returns it in upper case, otherwise returns it unchanged.
For Example:
Type:
Procedure.
Operation:
Test whether an alphabetic character is in upper case.
Arguments:
One alphabetic character.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is in upper case. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a character is white space; that is, whether it is a space, tab,
line feed, form feed, or carriage-return.
Arguments:
One character.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is white space. Otherwise, returns #t
For Example:
Type:
Procedure.
Operation:
Test whether the integer representation of the first argument is
less than or equal to
the integer representation of the second.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, the integer whose ASCII character represents
the first argument is
less than or equal to the integer whose ASCII character represents the
second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the integer representation of the first argument is
less than
the integer representation of the second.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, the integer whose ASCII character represents
the first argument is
less than to the integer whose ASCII character represents the
second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the first argument is
equal to
the second.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, the first argument is equal to the second.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the integer representation of the first argument is
greater than or equal to
the integer representation of the second.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, the integer whose ASCII character represents
the first argument is
greater than or equal to the integer whose ASCII character represents the
second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the integer representation of the first argument is
greater than
the integer representation of the second.
Arguments:
Two characters.
Side Effects:
None.
Returned Value:
A boolean:
Returns #t if, and only if, the integer whose ASCII character represents
the first argument is
greater than the integer whose ASCII character represents the
second argument.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is a character.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a character. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is a complex number.
Arguments:
One scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a complex number. Otherwise, returns #f.
Informally, "complex?" returns #t for every number except nans and infs,
because every such number
lies somewhere in the complex plane. All of Pixie Scheme III's numbers lie on the real axis, but they
are nonetheless in the complex plane.
For Example:
Type:
Operation:
Examines a series of given clauses, each of which must be a
proper list. For each clause in turn, evaluates the car of the list:
If that car is true, the evaluates all the rest of the items in the
list in turn, and returns whatever the last item evaluates to. If the
car is false, goes on to the next given clause. If no given clause has a
car that evaluates to true, returns #t. The last of the given clauses
may start with the symbol "else", which is treated as if it were #t.
Arguments:
One or more proper lists, the last of which may have "else" as car.
Side Effects:
None in its own right, but the evaluation of items in the clauses may
cause arbitrary side effects.
Returned Value:
Arbitrary, depending on the clauses; may not return at all, depending on
the clauses.
For Example:
Type:
Procedure.
Operation:
Allocate storage for a newly-formed pair.
Arguments:
Two Scheme objects.
Side Effects:
Allocates main memory.
Returned Value:
A pair whose car is the first argument and whose cdr is the
second argument. If the first argument is an item represented by a
pointer to Scheme memory, then the car of the returned pair is "eq?" to
the second argument. If the second argument is an item represented by a
pointer to Scheme memory, then the cdr of the returned pair is "eq?" to
the second argument.
For Example:
Type:
Procedure.
Operation:
Mathematical cosine.
Arguments:
One number, taken to be an angle in radians.
Side Effects:
None.
Returned Value:
A number: The cosine of the argument.
For Example:
Type:
Procedure.
Operation:
Returns the port from which input is presently being taken.
Arguments:
None.
Side Effects:
None.
Returned Value:
A port: The port from which input is presently being taken.
For Example:
Type:
Procedure.
Operation:
Returns the port from to which output is presently being sent.
Arguments:
None.
Side Effects:
None.
Returned Value:
A port: The port from which input is presently being taken.
For Example:
Type:
Operation:
Sets or binds an identifier to a value in the top-level environment,
or, as an internal definition, in an environment associated with
a procedure or special form.
Arguments:
There are three syntaxes:
First syntax: Two arguments, the first an identifier and the second any Scheme object.
Second syntax: Two or more arguments, the first a proper list of one or more identifiers,
and the rest any Scheme objects.
Third syntax: Two or more arguments, the first a list of identifiers
to which is appended a final identifier; that is, a list of the form
(identifier1 identifier2 ... identifierN-1 . identifierN), the
noteworthy feature being the dot before the final identifier, and
the rest any Scheme objects.
Side Effects:
First Syntax: If the first argument has never had a value or binding in
the relevant environment, gives it one. If a
previous binding or value of the first argument does exist in the relevant
environment, modifies it. In either case, the first
argument ends up with the second argument as its value or binding,
(depending on whether the second argument is of a kind that requires
a binding).
In the case of internal definitions, the argument cannot have
a previous binding, since the syntax restricts such definitions to the beginning of the
lexical scope for the environment in question.
Second Syntax: The second syntax is shorthand, or "syntactic sugar" for
binding an identifier to a lambda expression. The first element of
the first argument is taken to be the identifier. The remaining elements
of the first argument are taken to be the formal arguments to the
lambda expression. The remaining arguments are taken to be the contents
of the body of the lambda expression. Thus
is equivalent to
Third Syntax: The second syntax is shorthand, or "syntactic sugar" for
binding an identifier to a lambda expression. The first element of
the first argument is taken to be the identifier. The remaining
elements, of the first argument, except the one after the dot, are
taken to be formal arguments to the lambda expression, and the
identifier after the dot has bound to it a list of any remaining
actual arguments to the lambda expression when it is called. The
remaining arguments to "define" are taken to be the contents of the
body of the lambda expression. Thus
is equivalent to
and
is equivalent to
Returned Value:
First syntax: the first argument.
Second and third syntaxes: the first element of the first argument.
For Example:
Type:
Operation:
Define an hygienic macro at top-level.
Arguments:
One symbol and one <transformer spec>, the latter according to the grammar of "R5" report
section 4.3.2.
Side Effects:
If the first argument has never had a value or binding in
the top-level environment, gives it one. If a
previous binding or value of the first argument does exist in the top-level
environment, modifies it. In either case, the first
argument ends up with the macro transformer corresponding to the second argument, as its
a binding.
Returned Value:
The first argument.
For Example:
Type:
Operation:
Encapsulate a Scheme expression in such
a way that it can be evaluated subsequently,
by the "force" procedure, and its value then
returned.
Arguments:
One Scheme object of any kind.
Side Effects:
None in its own right; side effects due to the eventual
evaluation of the argument may occur, depending on the
argument.
Returned Value:
A promise.
For Example:
Type:
Procedure.
Operation:
Output an external representation of a Scheme object in a form
intended easily to be read by sentient beings. Contrast with "write",
whose output is intended easily to be read by computers and programmers ...
Arguments:
One or two arguments. The first may be any Scheme object. The second, if present,
must be an open output port.
Side Effects:
Writes output -- if there is a second argument, to that port, otherwise, to the
current output port.
Returned Value:
#t
For Example:
Type:
Operation:
Perform iteration, testing a termination condition before
each iteration; optionally, create an environment, with local
variables, in which the iterations are to be performed, and with means
of initializing those values and bindings, and of changing them during
successive iterations.
CAUTION: Pixie Scheme's III implementation of "do" is
abysmally slow, and uses vast amounts of memory.
Technical Note: Pixie Scheme III needs "do" because the
R5 standard requires it. The present release provides a version that
works, but I suggest that you avoid it when you can. I
may get around to writing a better implementation some day, but that is
a low-priority task: I don't use "do" much myself.
Arguments:
At least two:
The first argument is a proper list, each of whose arguments is a list of two
or three elements. The first is an identifier, the second an initial value or binding
for the identifier, and the third, if present, an expression to be evaluated after each iteration,
whose evaluation provides the value or binding for the identifier for the next iteration.
The second argument is a proper list of two or more arguments. The first is a test to
be evaluated before each iteration; if it evaluates to true, no further iterations are performed,
the remaining elements of the second argument are evaluated in sequence, and the "do" returns
the result of the last such evaluation. If the test evaluates to false, the next iteration is
performed.
The remaining arguments are evaluated in sequence during each iteration.
Side Effects:
None in its own right, but possibly many in consequence of the nature of the arguments.
Note that Pixie Scheme III's present implementation of "do" is very slow and uses lots of memory.
Returned Value:
Any Scheme object, depending on the arguments; or the do may never return.
For Example:
Type:
Procedure.
Operation:
Force two given procedures to be called when execution respectively
enters and leaves the dynamic extent of another given procedure. The
first argument is to be called on entry to the dynamic extent of the
second, and the third on exit from the dynamic extent of the second.
Arguments:
Three procedures, each of which must accept no arguments.
Side Effects:
None in its own right, but the given procedures may have side effects of their own.
Returned Value:
Whatever the second argument returns, if it returns at all.
For Example:
Type:
Reserved identifier, for use in "cond", which see.
Operation:
None.
Arguments:
Does not apply.
Side Effects:
Does not apply.
Returned Value:
Does not apply.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is an end-of-file object.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean.
Returns #t if, and only if, the argument is an end-of-file object.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether two Scheme objects are the same in the sense
that either
(1) the objects are of the same kind, and the same region of Scheme
main memory is used to store both, so that any alteration of one
object necessarily alters the other (this form of identity is
sometimes called "pointer equality"), or
(2) the objects are of the same kind, and each can be represented
entirely within the 64-bit pointer field of a Scheme tagged pointer,
and the necessary 64-bit representations are identical.
Technical Note: The behavior of "eq?" is allowed to be
implementation-dependent; what Pixie Scheme III does is first make sure that the
objects are the same kind, and if so, return #t if, and only if, their pointer
fields are identical, or if they are certain objects such as #t, #f
and '(), which do not require the pointer field at all.
Arguments:
Two Scheme objects.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if the two arguments are
identical in the sense described in the "Operation" section above..
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test for equality of Scheme objects by recursively descending through
pairs, lists, vectors, and strings, and applying "eqv?" to compare their
contents where further recursive descent does not occur.
Arguments:
Two Scheme objects.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the arguments are
equal in the sense described in the "Operation" section above.
Otherwise, returns #f. May not return, if the data structures being
compared are circular.
For Example:
Type:
Procedure.
Operation:
Test whether two Scheme objects should "normally be regarded as the
same object" (according to the R5 report). What Pixie Scheme III does
is return #t if the objects are "eq?", or if they are both numbers, both
have the same value, and are either both exact or both inexact.
Technical Note: Much of the vagueness in the
R5 definition of
"eqv?" stems from the prospect that some Scheme implementations may
upon occasion be able to prove that functions that do not have
identical source code always return the same value when given the same
arguments. Pixie Scheme III makes no pretensions of ever being able to
do any such thing; it returns #t from an "eqv?" test on functions only
in case of pointer identity.
Arguments:
Two Scheme objects.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if the arguments are "eq?". If not, returns
#t if the arguments are both numbers, and have the same numeric value,
and are either both exact or both inexact. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Evaluate an expression in a specified environment.
Arguments:
One Scheme object, and one instance of what is returned by one of the procedures
"interaction-environment", "null-environment", or "scheme-machine-environment".
Side Effects:
None in its own right, but the side effects of evaluating an expression may be substantial.
Returned Value:
The result of the evaluation.
For Example:
Type:
Procedure.
Operation:
Test whether an integer is even.
Arguments:
One integer.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an even number.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Create an inexact representation of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
An inexact number whose value is the same as the argument.
For Example:
Type:
Procedure.
Operation:
Test whether a number is exact.
Arguments:
One number.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is exact.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Mathematical exponentiation.
Arguments:
One number.
Side Effects:
None.
Returned Value:
A number: Returns the base of the natural logarithms raised to the argument.
For Example:
Type:
Procedure.
Operation:
Raise a number to a power.
Arguments:
Two numbers. Reports an error when Pixie Scheme's III numeric types cannot express the result, e.g.,
for the square root of -1.
Side Effects:
None.
Returned Value:
The first argument raised to the second argument.
For Example:
Type:
Procedure.
Operation:
Arithmetic round down.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
An integer:
The largest integer not larger than the argument.
For Example:
Type:
Procedure.
Operation:
Call a procedure many times, with different arguments, in a specified
order.
Arguments:
Two or more. The first argument is the procedure to call. The rest
must all be proper lists of the same length, and the number of arguments beyond the
first must equal the number of arguments with which the procedure is to be called.
On the first call, the arguments passed to the procedure are the first elements
of each list, in the same order as the lists. On the second call, the passed arguments
are the second elements of the lists, and so on.
Side Effects:
None in its own right, but the intended purpose of "for-each" is to call a procedure
repeatedly, for side effects, so there will likely be side effects, depending on the
arguments.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Cause the evaluation of a Scheme expression previously encapsulated
as a promise, for lazy evaluation, by the "delay" procedure; or if
that promise has already been forced, return whatever value it returned
at that time.
Arguments:
One promise.
Side Effects:
None in its own right, though the evaluation of the promise may cause
side effects, depending on the nature of the promise.
Returned Value:
As promised.
For Example:
Type:
Procedure.
Operation:
Mathematical greatest common divisor.
Arguments:
One or more integers.
Side Effects:
None.
Returned Value:
An integer: Returns the greatest common divisor of the two arguments.
For Example:
Type:
Operation:
Conditional evaluation, based on a test.
Arguments:
Two or three Scheme objects.
Side Effects:
None in its own right, others depending on the arguments.
Returned Value:
Evaluates the first argument: If the result is true, evaluates the second argument and returns
the result of so doing. If the first argument evaluates to false, and there is a third
argument, returns the result of evaluating the third argument. If the first argument evaluates
to false, and there is no third argument, returns #f.
For Example:
Type:
Procedure.
Operation:
Obtain the imaginary part of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The imaginary part of the number.
For Example:
Type:
Procedure.
Operation:
Create an exact representation of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
An exact number whose value is the same as the argument.
For Example:
Type:
Procedure.
Operation:
Test whether a number is inexact.
Arguments:
One number.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is inexact.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is an input port.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an input port.
Otherwise, returns #f. Note that once an input port has been closed,
it is no longer a port in the sense of the R5 report, because it cannot
deliver characters on demand.
For Example:
Type:
Procedure.
Operation:
Determine the ASCII character represented by the argument.
Arguments:
One integer in the range [0..127]
Side Effects:
None.
Returned Value:
A character: Returns the ASCII character represented by the argument.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is an integer.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an integer.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Return the Scheme environment in which expressions typed in the top-level
read-eval-print loop are evaluated.
Arguments:
None.
Side Effects:
None.
Returned Value:
The top-level environment of Pixie Scheme III.
For Example:
Type:
Operation:
Create an unnamed procedure
Arguments:
Two or more. There are three syntaxes:
First syntax: Two or more arguments, the first a proper list of one or more identifiers,
and the rest any Scheme objects.
Second syntax: Two or more arguments, the first a list of identifiers
to which is appended a final identifier; that is, a list of the form
(identifier1 identifier2 ... identifierN-1 . identifierN), the
noteworthy feature being the dot before the final identifier, and the
rest any Scheme objects.
Third syntax: Two or more arguments, the first an identifier and the rest
any Scheme objects.
Side Effects:
None.
Returned Value:
A lambda expression. The arguments after the first are the body of
the lambda expression. The meaning of the first argument varies:
First syntax: The first argument is a list of the formal arguments of
the lambda expression.
Second syntax: All elements of the first argument before the dot are
taken to be formal arguments to the lambda expression, and the identifier
after the dot will have a list of any remaining actual arguments to the lambda expression
bound to it when the lambda expression is called.
Third syntax: The first argument will have a list of all actual arguments to
the lambda expression bound to it when the lambda expression is called.
For Example:
Type:
Procedure.
Operation:
Mathematical least common multiple.
Arguments:
One or more integers.
Side Effects:
None.
Returned Value:
An integer: Returns the least common multiple of the arguments.
For Example:
Type:
Procedure.
Operation:
Find the length of a proper list.
Arguments:
One proper list.
Side Effects:
None.
Returned Value:
An integer: Returns the length of the list.
For Example:
Type:
Operation:
Creates an environment with local variables which have initial values
or bindings, and evaluates expressions therein. The local variables
created may not access each other in establishing their initial
values. Contrast with "let*".
Arguments:
Two or more. The first is a list of two-element sublists, the
first element in each sublist being an identifier and the second, when
evaluated, being the initial value or binding for that identifier. All remaining
arguments are the expressions to be evaluated, in the order given, in the
environment so created.
Side Effects:
Creates a local environment. Other side effects possible, depending on the
arguments.
Returned Value:
Whatever results from the evaluation of the last argument.
For Example:
Type:
Operation:
Creates an environment with local variables whose bindings
are the transformers of hygienic macros (according to the "R5"
description thereof), and evaluates expressions therein. The local
variables created may not access each other in establishing their
initial values. Contrast with "letrec-syntax".
Arguments:
Two or more. The first is a list of two-element sublists, the
first element in each sublist being an identifier and the second a
<transformer spec>, according to the grammar of "R5" report section 4.3.2.
All remaining arguments are the expressions to be evaluated, in the order given, in the
environment so created.
Side Effects:
Creates a local environment. Other side effects possible, depending on the
arguments.
Returned Value:
Whatever results from the evaluation of the last argument.
For Example:
Type:
Operation:
Creates an environment with local variables which have initial values
or bindings, and evaluates expressions therein. Each local variable
created may access the local variables created before it when establishing
its initial value. Contrast with "let".
Arguments:
Two or more. The first is a list of two-element sublists, the
first element in each sublist being an identifier and the second, when
evaluated, being the initial value or binding for that identifier. All remaining
arguments are the expressions to be evaluated, in the order given, in the
environment so created.
Side Effects:
Creates a local environment. Other side effects possible, depending on the
arguments.
Returned Value:
Whatever results from the evaluation of the last argument.
For Example:
Type:
Operation:
Creates an environment with local variables which have initial values
or bindings, and evaluates expressions therein. Each local variable
created may access all local variables created by the letrec when establishing
its initial value, which typically makes the most sense when what the variables
are bound functions that reference one another.. Contrast with "let" and "let*".
Pixie Scheme III does NOT report an error if the local variables
of a letrec are used in such a way that the initialization
expressions are undefined: Pixie Scheme III handles "letrec"
by creating a local environment in which the local variables all
have values of '() -- the R5 report merely states that such
pre-initialization values are undefined. Thus the example
used for let and let* gives the following result for letrec:
That latter result, however, need not obtain with other Scheme
implementations.
Arguments:
Two or more. The first is a list of two-element sublists, the
first element in each sublist being an identifier and the second, when
evaluated, being the initial value or binding for that identifier. All remaining
arguments are the expressions to be evaluated, in the order given, in the
environment so created.
Side Effects:
Creates a local environment. Other side effects possible, depending on the
arguments.
Returned Value:
Whatever results from the evaluation of the last argument.
For Example:
Type:
Operation:
Creates an environment with local variables which have initial
bindings to transformers of hygienic macros, according
to the "R5" description thereof. Evaluates expressions therein. Each local variable
created may access all local variables created by the letrec-syntax when establishing
its initial value, which typically makes the most sense when what the variables
are macros that reference one another.. Contrast with "let-syntax".
Pixie Scheme III does NOT report an error if the local variables
of a letrec-syntax are used in such a way that the initialization
expressions are undefined: Pixie Scheme III handles "letrec-syntax"
by creating a local environment in which the local variables all
have values of '().
Arguments:
Two or more. The first is a list of two-element sublists, the
first element in each sublist being an identifier and the second a
<transformer spec>, according to the grammar of "R5" report section 4.3.2.
All remaining arguments are the expressions to be evaluated, in the order given, in the
environment so created.
Side Effects:
Creates a local environment. Other side effects possible, depending on the
arguments.
Returned Value:
Whatever results from the evaluation of the last argument.
For Example:
Type:
Procedure.
Operation:
Make a list.
Arguments:
Zero or more Scheme objects.
Side Effects:
None.
Returned Value:
A list of the arguments, in order.
For Example:
Type:
Procedure.
Operation:
Convert a list of characters to a string containing them in the given order.
Arguments:
One list of zero or more characters.
Side Effects:
None.
Returned Value:
A string whose characters are those in the list, in order.
For Example:
Type:
Procedure.
Operation:
Convert a list of Scheme objects to a vector containing them in the given order.
Arguments:
One list of zero or more Scheme objects.
Side Effects:
None.
Returned Value:
A vector whose elements are the elements of the list, in order.
For Example:
Type:
Procedure.
Operation:
Obtain an element of a proper list, based on its position.
Arguments:
One proper list and one non-negative integer.
Side Effects:
None.
Returned Value:
A Scheme object: Returns the (zero-based) nth element of the first argument, where n
is the second argument.
For Example:
Type:
Procedure.
Operation:
Identify a sublist of a given list made by removing elements
from the front of the given list.
Arguments:
One proper list and one non-negative integer.
Side Effects:
None.
Returned Value:
A list: Returns the list obtained from the first argument by removing
its first n elements, where n is the second argument. The result shares
structure with the first argument: Modifying the result, for example
by set-car! or set-cdr!, will modify the first argument.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a proper list.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a proper list.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Mathematical natural logarithm.
Arguments:
One nonnegative number.
Side Effects:
None.
Returned Value:
A number: Returns the natural logarithm of the argument.
For Example:
Type:
Procedure.
Operation:
Obtain the magnitude of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The magnitude of the number.
For Example:
Type:
Procedure.
Operation:
Create a complex number from its magnitude and angle.
Arguments:
Two reals, the first the magnitude of the desired complex number, the
second its angle. Note that R5 allows the magnitude to be negative.
Side Effects:
None.
Returned Value:
A number: The complex number constructed from the given magnitude and angle.
For Example:
Type:
Procedure.
Operation:
Create a complex number from its real and imaginary parts.
Arguments:
Two reals, the first the real part of the desired complex number, the
second the imaginary part.
Side Effects:
None.
Returned Value:
A number: The complex number constructed from the given real and imaginary part.
For Example:
Type:
Procedure.
Operation:
Create a string, and optionally fill it with a specific character.
Arguments:
Zero, one or two: The first a nonnegative integer, the second, if present, a character.
Side Effects:
None.
Returned Value:
A string: Returns a string whose length is the first argument. If the second
argument is present, every character in the new string will be the same as the
second argument. If there is no second argument, the string will be filled
with blanks.
With no arguments, prompts the user to type a string in the Pixie Scheme III
dialog panel. Enclosing double-quotes are not required in this case.
For Example:
Type:
Procedure.
Operation:
Create a vector, and optionally fill it with a specific Scheme object.
Arguments:
One or two: The first a nonnegative integer, the second, if present, any Scheme object.
Side Effects:
None.
Returned Value:
A vector: Returns a vector whose length is the first argument. If the second
argument is present, every character in the new vector will be the same as the
second argument. If there is no second argument, the vector will be filled
with the empty list.
For Example:
Type:
Procedure.
Operation:
Call a procedure many times, with different arguments, in an unspecified order,
and return a list of the results.
Arguments:
Two or more. The first argument is the procedure to call. The rest
must all be proper lists of the same length, and the number of arguments beyond the
first must equal the number of arguments with which the procedure is to be called.
There will be as many calls of the procedure as there are elements in each list.
There is no guarantee that the calls will be in any specified order, but for
purposes of explanation, let us number them from one to N, N being the number
of elements in each list.
On call number 1, the arguments passed to the procedure are the first elements
of each list, in the same order as the lists. On call number 2, the passed arguments
are the second elements of the lists, and so on.
Side Effects:
None in its own right, but there may be side effects of the procedure calls, depending on the
arguments.
Returned Value:
A list of results of the call, in order from 1 to N, as outlined in the "Operation" section
above.
For Example:
Type:
Procedure.
Operation:
Arithmetic maximum.
Arguments:
Two or more real numbers.
Side Effects:
None.
Returned Value:
A number: Returns the maximum of the arguments.
For Example:
Type:
Procedure.
Operation:
Identify the first sublist of a list whose car is "equal?" to
a given object.
Arguments:
Two: The first is any Scheme object, the second a proper list.
Side Effects:
None.
Returned Value:
Returns the first (longest) sublist of the second argument whose
car is "equal?" to the first argument. If no such sublist exists,
returns #f.
For Example:
Type:
Procedure.
Operation:
Identify the first sublist of a list whose car is "eq?" to
a given object.
Arguments:
Two: The first is any Scheme object, the second a proper list.
Side Effects:
None.
Returned Value:
Returns the first (longest) sublist of the second argument whose
car is "eq?" to the first argument. If no such sublist exists,
returns #f.
For Example:
Type:
Procedure.
Operation:
Identify the first sublist of a list whose car is "eqv?" to
a given object.
Arguments:
Two: The first is any Scheme object, the second a proper list.
Side Effects:
None.
Returned Value:
Returns the first (longest) sublist of the second argument whose
car is "eqv?" to the first argument. If no such sublist exists,
returns #f.
For Example:
Type:
Procedure.
Operation:
Arithmetic minimum
Arguments:
Two or more real numbers.
Side Effects:
None.
Returned Value:
A number: Returns the minimum of the arguments.
For Example:
Type:
Procedure.
Operation:
Mathematical modulus.
Arguments:
Two integers.
Side Effects:
None.
o
Returned Value:
An integer: Returns the first argument modulo the second.
For Example:
Type:
Procedure.
Operation:
Test whether a number is negative.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is negative.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Write a newline character, the ASCII character whose
numeric representation is 10, to a port.
Arguments:
At most one, a port.
Side Effects:
Writes a newline to the given port, if there is an
argument, or to the current output port, if not.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Boolean negation.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is #f.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Return a Scheme environment which is supposed to contain only
the syntactic keywords of Scheme, but which in Pixie Scheme III
contains a few more bindings.
Arguments:
One, which must be the exact integer 5.
Side Effects:
None.
Returned Value:
The null environment of Pixie Scheme III, which contains bindings
for the following symbols:
The "extra" symbols are macros used in defining
several of the syntactic keywords. I couldn't come
up with any other reasonable place to put them.
For Example:
Type:
Procedure.
Operation:
Test whether an object is the empty list.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is the
empty list. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Create a string containing an external representation of
a given number.
Arguments:
One or two: The first a number, the second an exact integer,
either 2, 8, 10 or 16, corresponding to the radix in which the
number is to be represented.
Side Effects:
None.
Returned Value:
A string: Returns a string representing the first argument in the
given radix, if a second argument is present, or in radix 10 if there
is no second argument. The result never contains a radix prefix. The
result must be such that, informally, if you read it back in using
"string->number" in the correct radix, the number you get is "eqv?" to
the original argument.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a number.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a number.
Otherwise, returns #f. Pixie Scheme III considers nans and infs not
to be numbers.
For Example:
Type:
Procedure.
Operation:
Test whether an integer is odd.
Arguments:
One integer.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an odd number.
Otherwise, returns #f.
Many people think that all numbers are odd. I do not sympathize, but
perhaps that is because I am odd myself.
For Example:
Type:
Operation:
Boolean or.
Arguments:
Zero or more Scheme objects of any kind.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, at least one of
the arguments is true.
(Recall that the only Scheme object that is false is #f.)
With no arguments, returns #f.
Otherwise, returns #f
This macro operates by evaluating its arguments one
at a time, from left to right. When and if any argument
evaluates to true, "or" returns true immediately, without
evaluating any more arguments.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is an output port.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an output port.
Otherwise, returns #f. Note that once an output port has been closed,
it is no longer a port in the sense of the R5 report, because it cannot
accept characters on demand.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is a pair.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a pair.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Obtain the next character available from an input port -- or hang
waiting if none is available -- without doing anything to cause the
port to advance to to the next character.
Arguments:
At most one, an input port.
Side Effects:
None.
Returned Value:
A character or an end-of file object: If there is an argument, obtain
the result from that port. If there is no argument, obtain the result from
the current input port. The procedure may not return immediately, if the
port is to an interactive device, such as the keyboard, which has no
character ready.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is a port.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a
port. Otherwise, returns #f. Note that once a port has been
closed, it is no longer a port as Scheme uses the term, because
it can neither accept nor provide characters on demand.
For Example:
Type:
Procedure.
Operation:
Test whether a number is positive.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is positive.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a procedure.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a procedure.
Returns #f otherwise.
Macros and special forms are not procedures.
For Example:
Additional Syntax:
Backquote: `<whatever> is equivalent to (quasiquote <whatever>).
Type:
Operation:
Instantiate literal data with an option for partial evaluation using "unquote" or "unquote-splicing".
Thus, (quasiquote <whatever>) evaluates to <whatever>, but if any subexpression of <whatever>
begins with either "unquote" or "unquote-splicing", or with their respective syntactic equivalents, ","
or ",@", then that subexpression will be evaluated according to the rules for unquote or unquote-splicing
before being inserted into <whatever>.
The macros "quasiquote", "unquote" and "unquote-splicing" may be nested within <whatever>: Starting
with a nesting level of zero at the the left end of <whatever>, each "quasiquote" increases the nesting
level by one, and each "unquote" or "unquote-splicing" reduces it by one, and normal evaluation occurs only
when the nesting level thus determined is zero.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
The argument, with no further evaluation except as directed by "unquote" or by "unquote-splicing".
For Example:
Additional Syntax:
Quote: '<whatever> is equivalent to (quote <whatever>).
Type:
Operation:
Instantiate literal data; that is, (quote <whatever>) evaluates to <whatever>.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
The argument, without further evaluation.
For Example:
Type:
Procedure.
Operation:
Mathematical quotient.
Arguments:
Two integers.
Side Effects:
None.
Returned Value:
An integer: The quotient of the first number by the second.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is a rational number.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a rational number.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Read one Scheme object from a port. What is read must "parse"; that is, it must
be a valid external representation of a Scheme object, but "read" does not evaluate it.
Arguments:
At most one: If present, an input port.
Side Effects:
None.
Returned Value:
A Scheme object: If an argument is present, returns the
next Scheme object available from that port, or an end-of-file object;
if not, returns the next Scheme object available at the current input
port, or an end-of-file object.
For Example:
Type:
Procedure.
Operation:
Obtain the next character available from an input port -- or hang
waiting if none is available.
Arguments:
At most one, an input port.
Side Effects:
Reads from a port.
Returned Value:
A character or an end-of file object: If there is an argument, obtain
the result from that port. If there is no argument, obtain the result from
the current input port. The procedure may not return immediately, if the
port is to an interactive device, such as the keyboard, which has no
character ready.
For Example:
Type:
Procedure.
Operation:
Obtain the real part of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The real part of the number.
For Example:
Type:
Procedure.
Operation:
Test whether the argument is a real number.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a real number.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Mathematical remainder.
Arguments:
Two integers.
Side Effects:
None.
Returned Value:
An integer: The remainder of the first number when divided
(in the sense of "quotient") by the second.
For Example:
Type:
Procedure.
Operation:
Reverse a proper list.
Arguments:
One proper list.
Side Effects:
None.
Returned Value:
A list: Returns a newly-created list whose elements are the elements of
the argument in reverse order.
For Example:
Type:
Procedure.
Operation:
Arithmetic round to nearest integer.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
An integer:
The closest integer to the argument, rounding to even when the
argument is half way between two integers.
For Example:
Type:
Procedure.
Operation:
Return a Scheme environment which contains the bindings in
the null environment, plus all other bindings that are either
required by the R5 report or are optional and are supported
by Pixie Scheme III.
Arguments:
One, which must be the exact integer 5.
Side Effects:
None.
Returned Value:
The Scheme-report environment of Pixie Scheme III.
For Example:
Type:
Operation:
Arguments:
Two: The first, an identifier; the second, any Scheme object.
Side Effects:
Changes a pre-existing variable value or binding; informally, changes
the value of a variable. The second argument becomes the value or
binding of the first, in whatever environment the "set!" occurred in.
In the top-level environment, "define" may also be used to give
new values or bindings to identifiers; however, in other environments, only
"set!" has this capability.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Change the car of a pair to a new value.
Arguments:
Two: The first, a pair; the second, any Scheme object, to become the new car.
Side Effects:
Changes the pair.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Change the cdr of a pair to a new value.
Arguments:
Two: the first, a pair; the second, any Scheme object, to become the new cdr.
Side Effects:
Changes the pair.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Mathematical sine.
Arguments:
One number, taken to be an angle in radians.
Side Effects:
None.
Returned Value:
The sine of the argument.
For Example:
Type:
Procedure.
Operation:
Mathematical square root.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The square root of the argument.
For Example:
Type:
Procedure.
Operation:
Create a string containing a given list of characters.
Arguments:
Zero or more characters.
Side Effects:
None.
Returned Value:
A string containing the characters that were the arguments, in the same order
For Example:
Type:
Procedure.
Operation:
Make a list of the characters in a string.
Arguments:
One string.
Side Effects:
None.
Returned Value:
A list: Returns a list of the characters in the argument, in order.
For Example:
Type:
Procedure.
Operation:
Read the contents of a string as a number in a particular radix.
Arguments:
One or two: The first, the string to be read, the second an exact integer,
either 2, 8, 10 or 16, corresponding to the radix in which the
number is to be represented. If there is no second argument, the radix
is taken to be 10.
of the
Side Effects:
None.
Returned Value:
A number: Returns a number whose external representation in the given base
is the given string.
For Example:
Type:
Procedure.
Operation:
Create a Scheme identifier from the letters of the argument.
Arguments:
One string.
Side Effects:
None.
Returned Value:
A symbol: Returns a Scheme identifier whose characters are the same as those in the given string, in the same order.
For Example:
Type:
Procedure.
Operation:
Concatenate strings.
Arguments:
One or more strings.
Side Effects:
None.
Returned Value:
A string: Returns a string whose characters are the characters of the arguments,
in order.
For Example:
Type:
Procedure.
Operation:
Convert two strings to lower case and test for lexicographic less than or equal to.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically less than or equal to
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Convert two strings to lower case and test for lexicographic less than.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically less than
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Convert two strings to lower case and test for lexicographic equality.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically equality
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Convert two strings to lower case and test for lexicographic greater than or equal to.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically greater than or equal to
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Convert two strings to lower case and test for lexicographic greater than.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically greater than
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Copy a string.
Arguments:
One string.
Side Effects:
None.
Returned Value:
A string: Returns a newly-allocated copy of the argument.
For Example:
Type:
Procedure.
Operation:
Fill a string with a given character.
Arguments:
Two: The first a string, the second the character to fill with.
Side Effects:
Alters the string.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Determine the length of a string.
Arguments:
One string.
Side Effects:
None.
Returned Value:
An integer: Returns the number of characters in the argument.
For Example:
Type:
Procedure.
Operation:
Get a specific character from a string.
Arguments:
Two: The first a string, the second a nonnegative integer, taken as the zero-based index of the character to return.
Side Effects:
None.
Returned Value:
A character: Returns the first argument's character that was at position N from the start of the string, N being
the second argument. A value of zero for N returns the first character in the string.
For Example:
Type:
Procedure.
Operation:
Set one character in a string to a new value.
Arguments:
Three: The first a string, the second a nonnegative integer, taken as the zero-based index of the character to change,
the third the new character.
Side Effects:
Changes the string.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Test two strings for lexicographic less than or equal to.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically less than or equal to
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test two strings for lexicographic less than.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically less than
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test two strings for lexicographic equality.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically equality
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test two strings for lexicographic greater than or equal to.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically greater than or equal to
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test two strings for lexicographic greater than.
Lexicographic comparison compares strings character-by-character and defines their
ordering based on the ASCII integers that represent the first characters at which
they differ, if any. If one string ends before a difference occurs, the longer string
is taken to be greater. If both strings end with no difference, the strings are taken
to be equal.
Arguments:
Two strings.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the first string is lexicographically greater than
the second. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a string.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a string.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Make a copy of part of a given string.
Arguments:
Three: The first a string, the second and third non-negative integers, respectively taken to be
the zero-based indexes into the given string to the position of the first character
of the intended substring, and to the position just past the last character of the
intended substring. If the second and third arguments are equal, the substring
indicated has zero length, and contains no characters.
Side Effects:
None.
Returned Value:
A string: Returns a newly-allocated copy of the substring described in the "Arguments"
section above.
For Example:
Type:
Procedure.
Operation:
Make a string containing the letters of a given symbol.
Arguments:
One symbol.
Side Effects:
None.
Returned Value:
An immutable string: Returns a string with the same characters as the argument, in the same order.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a symbol.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a symbol. Otherwise, returns #f.
For Example:
Type:
Operation:
Primitive for construction of hygienic macros.
Arguments:
The form of a macro call of "syntax-rules" should match the grammar
for <transformer spec> given in section 4.3.2 of the "R5"
report.
Side Effects:
None.
Returned Value:
A procedure, suitable for use as the transformer of an hygienic macro.
For Example:
Strictly, there are no examples: The formal definition of Scheme
mentions "syntax-rules" only in the context of the syntax required for
the standard implementation of hygienic macros. There is no
specification of what sort of entity "syntax-rules" should be, or even
of whether or not there should be a Scheme object associated with that
identifier. There is also no specification of what behavior should
obtain if "syntax-rules" is used in some other context, such as
I mention "syntax-rules" here only because its use in the "R5" report
resembles the use of a procedure or special form: You might like to know
what happens if you try to use it that way. The answer is, that if
the call to "syntax-rules" matches the grammar
for <transformer spec> given in section 4.3.2 of the "R5"
report, you will get a procedure suitable for use as the transformer
of an hygienic macro. If not, you will probably get some form of
error message. For example, noting that hex values may vary:
The reason for this behavior is an implementation detail of Pixie
Scheme III: In Pixie Scheme III, "syntax-rules" itself does not do any
tests to make sure that it is being called with the correct
grammar. All appropriate syntax checking is done by forms
"define-syntax", "let-syntax", and "letrec-syntax", which use
the symbol "syntax-rules" as part of their implementation.
Thus in:
the macro call is obviously not a <transformer spec>, and
the error message noted occurs when the macro "syntax-rules" stumbles
because of that failing. On the other hand, when Pixie Scheme III
encounters the form:
it produces a more useful error report:
If you wish to experiment with "syntax-rules" all by itself, go ahead,
but beware of mysterious failures and puzzling error messages when you
use it in any other context than an instance of "define-syntax",
"let-syntax", or "letrec-syntax".
Type:
Procedure.
Operation:
Mathematical tangent.
Arguments:
One number, taken as an angle in radians.
Side Effects:
None.
Returned Value:
The tangent of the argument.
For Example:
Type:
Procedure.
Operation:
Arithmetic truncation toward zero.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
An integer:
The integer closest to the argument whose absolute value is not
larger than the absolute value of the argument.
For Example:
Additional Syntax:
Comma: ,<whatever> is equivalent to (unquote <whatever>).
Type:
Operation:
Reduce the level of nesting by one within a quasiquoted expression, (quasiquote <whatever>).
When that level is zero, the evaluation that was inhibited by "quasiquote" resumes, and the
argument of "unquote" is inserted into <whatever>.
The macros "quasiquote", "unquote" and "unquote-splicing" may be nested within <whatever>: Starting
with a nesting level of zero at the the left end of <whatever>, each "quasiquote" increases the nesting
level by one, and each "unquote" or "unquote-splicing" reduces it by one, and normal evaluation occurs only
when the nesting level thus determined is zero.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A Scheme object: Returns the argument, either evaluated or not, according to whether the nesting level,
defined in the "Operation" section above, is zero or not. In either case the returned value is spliced
into the enclosing quasiquoted expression.
For Example:
Additional Syntax:
Comma and at-sign: ,@<whatever> is equivalent to (unquote-spicing <whatever>).
Type:
Operation:
Reduce the level of nesting by one within a quasiquoted expression, (quasiquote <whatever>).
When that level is zero, the evaluation that was inhibited by "quasiquote" resumes, and the
elements of the argument of "unquote-splicing" -- which is a list -- are spliced into <whatever>.
The macros "quasiquote", "unquote" and "unquote-splicing" may be nested within <whatever>: Starting
with a nesting level of zero at the the left end of <whatever>, each "quasiquote" increases the nesting
level by one, and each "unquote" or "unquote-splicing" reduces it by one, and normal evaluation occurs only
when the nesting level thus determined is zero.
Arguments:
One proper list.
Side Effects:
None.
Returned Value:
One or more Scheme objects: If the nesting level, defined in the "Operation" section above, is zero,
returns the elements of the argument; if not, returns the argument, which in either case is spliced
into the enclosing quasiquoted expression.
For Example:
Type:
Procedure.
Operation:
In the abstract sense, "values" modifies the
continuation (in the first sense discussed herein) when it is
called, so that the continuation is set up to deliver multiple values
to a Scheme procedure -- the values being those provided as arguments
to "values" itself, in the order given.
Such a continuation is only useful when the next thing following those
values is a procedure call which can accept those values as its arguments.
In practical terms, "values" provides a mechanism for returning multiple
values from a procedure. Although it is technically a procedure in its
own right, it is perhaps most useful to think of it as a special syntactic
form, used at the end of a procedure, to return values. In that sense,
"values" is analogous to the "return" statement in the C programming
language, except that C's "return" can return only one value, whereas
"values" can return many.
Arguments:
One or more Scheme objects.
Side Effects:
None.
Returned Value:
A "Multiple Values Return" object, which can only be interpreted
in the continuation established by
"call-with-values". Other Scheme
implementations likely handle the return from "values" differently.
For Example:
Type:
Procedure.
Operation:
Make a vector.
Arguments:
Zero or more Scheme objects.
Side Effects:
None.
Returned Value:
A vector of the arguments, in order.
For Example:
Type:
Procedure.
Operation:
Make a list of the elements in a vector.
Arguments:
One vector.
Side Effects:
None.
Returned Value:
A list: Returns a newly-allocated list whose elements are the elements of the argument, in the same order.
For Example:
Type:
Procedure.
Operation:
Fill every element of a vector with the same Scheme object.
Arguments:
Two: The first a vector to be filled, the second a Scheme object to fill it with.
Side Effects:
Modifies the first argument.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Obtain the length of a vector.
Arguments:
One vector.
Side Effects:
None.
Returned Value:
An integer: Returns the length of the argument.
For Example:
Type:
Procedure.
Operation:
Obtain a specified element of a vector.
Arguments:
Two: The first a vector, the second a non-negative integer, taken to be the zero-based index
of the argument requested.
Side Effects:
None.
Returned Value:
A Scheme object: Returns the element of the first argument that is at
the zero-based index which is the second argument.
For Example:
Type:
Procedure.
Operation:
Set one element of a vector to a new value.
Arguments:
Three: The first a vector, the second a nonnegative integer, taken as the zero-based index of the element to change,
the third the new element.
Side Effects:
Changes the vector.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a vector.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a vector. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Write a Scheme object to a port.
Arguments:
One or two: The first, a Scheme object to be written; the second, if present,
an output port to write to. If there is no second argument, the object will be written
to the current output port.
Side Effects:
Writes something, somewhere.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Write a character to a port.
Arguments:
One or two: The first, a character to be written; the second, if present,
an output port to write to. If there is no second argument, the character will be written
to the current output port.
Side Effects:
Writes a character somewhere.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Test whether a number is zero.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is zero; the test is done using
the Scheme predicate "=". Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Find the number of bytes free in the current Pixie Scheme III active memory generation.
Rationale, Explanation, Excuses:
Simple storage-instrumentation procedure: Just returns a
number. Contrast with "e::show-room", which prints out text
describing memory use.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the number of bytes free in the current Pixie
Scheme III active memory generation.
For Example:
Type:
Procedure.
Operation:
Find the size of the active generation in use by the Pixie Scheme III
generational garbage collector.
Rationale, Explanation, Excuses:
"e::active-store-size" is a basic memory-inspection function. Do
not confuse it with "e::active-room": The former shows how many bytes
the active generation has. The latter shows how many of those bytes
are presently in use.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the size, in bytes, of Pixie Scheme III's active generation.
For Example:
Type:
Procedure.
Operation:
Find the number of bytes free in the current Pixie Scheme III aging memory generation.
Rationale, Explanation, Excuses:
Simple storage-instrumentation procedure: Just returns a
number. Contrast with "e::show-room", which prints out text
describing memory use.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the number of bytes free in the current Pixie
Scheme III aging memory generation.
For Example:
Type:
Procedure.
Operation:
Test whether all objects in a list are "true"; that is, that no object in the list is #f.
Rationale, Explanation, Excuses:
This procedure might be useful when you would like to write
but you cannot, because "and" is a special form.
Arguments:
One proper list.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, no element of the given list is #f.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether any object in a list is "true"; that is, that at least one object in the list is not #f.
Rationale, Explanation, Excuses:
This procedure might be useful when you would like to write
but you cannot, because "or" is a special form.
Arguments:
One proper list.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, at least one element of the given list is not #f.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a Pixie Scheme III object is an atom.
Note
that what kinds of objects are atoms may vary from Scheme implementation
to Scheme implementation.
Rationale, Explanation, Excuses:
Useful for characterizing Pixie Scheme III objects and for determining
whether it is useful to make an object forgettable.
Arguments:
One Scheme object of any kind.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an atom.
Otherwise, returns #f.
For Example:
Type:
Procedure. (All of them.)
Operation:
These enhancements provide traditional bitwise boolean and shift operations for integers which
can be stored as 64-bit fixnums; that is, integers in the range [-9223372036854775808 .. 9223372036854775807].
Rationale, Explanation, Excuses:
Arguments:
"e::bit-and", "e::bit-or" and "e::bit-xor": Two integers in the range that can be stored as 64-bit fixnums.
"e::bit-not": One integer in the range that can be stored as 64-bit fixnums.
"e::bit-shift-left", "e::bit-shift-right-arithmetic" and "e::bit-shift-right-logical": Two integers,
the first in the range that can be stored as 64-bit fixnums and the second nonnegative.
Side Effects:
None.
Returned Value:
An integer stored as a 64-bit fixnum.
"e::bit-and", "e::bit-or" and "e::bit-xor" return respectively the bitwise logical and, or,
and xor of their arguments. "e::bit-not" returns the bitwise logical negation of its
argument. The shift operators return their first argument shifted a number of bits equal to the
second argument, in the direction indicated. "e::bit-shift-left" and "e::bit-shift-right-logical"
pad at the shifted-in end with zeros. "e::bit-shift-right-arithmetic" pads with the most significant
bit; that is, the sign bit.
For Example:
Type:
Procedure.
Operation:
Test whether a symbol has a value or binding in any environment in the
lexical scope of where "e::bound-instance?" was called.
Rationale, Explanation, Excuses:
Many Lisp systems would call this procedure "boundp" or "bound?".
It can be useful when investigating Scheme memory, or when one needs to
make sure that a haphazardly chosen symbol has no value or binding.
Arguments:
One symbol.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument has a value or binding
in the current lexical scope. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Convert numbers, taken as C-style booleans, to #t or #f.
Rationale, Explanation, Excuses:
Useful with the Pixie Scheme III foreign-function interface, for dealing with foreign booleans.
Arguments:
One number.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is nonzero.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Clear the internal flag that tell Pixie Scheme III to compile defines automatically.
Rationale, Explanation, Excuses:
Provides Scheme-program control of an important internal flag.
Arguments:
None.
Side Effects:
Turns off automatic compilation.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Rationale, Explanation, Excuses:
To make it difficult inadvertently to redefine fundamental Scheme
procedures like "+" and "cons", I provide symbols with a
"permanent" flag. When set, any attempt to change the value or
binding of the given symbol causes Pixie Scheme III to report an error.
Procedure "e::clear-permanent!" clears this flag, so you can, for example,
redefine "cons", if you really, really, want to. Procedure "e::set-permanent!"
sets it, so you can't. Procedure "e::permanent?" tests whether it is set
or not.
On your head be it.
You may of course use "e::clear-permanent" and its companion,
"e::set-permanent!", for new variables that you yourself create.
Arguments:
One symbol.
Side Effects:
Makes it possible to change what the value or binding of the argument.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Clear the internal flag that tell Pixie Scheme III to display numbers with the full precision available.
Rationale, Explanation, Excuses:
Provides Scheme-program control of an important internal flag.
Arguments:
None.
Side Effects:
Causes Pixie Scheme III's numeric display routines to use reduced precision.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Test whether a port is closed.
Rationale, Explanation, Excuses:
The entities that Pixie Scheme III uses for ports persist
even after they have been closed; they are in fact reused.
"Open" and "closed" are elements of port state. Thus it
makes sense to have a procedure to test whether a port
is open or closed.
Arguments:
One port -- either an input port or an output port will do.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is closed.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Coerces a real to long ratnum form, if the real is in the range where that is possible.
Rationale, Explanation, Excuses:
Useful for dealing with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
Either the real expressed as a long ratnum, or #f if the conversion is not possible.
For Example:
Type:
Procedure.
Operation:
Determines whether an object is an integer in the range wherein it can
be coerced to a 64-bit signed integer.
Rationale, Explanation, Excuses:
Useful for dealing with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an integer in the
range of 64-bit signed integers. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Determines whether an object is a number that can be
expressed as a rational using 64-bit signed integers.
Rationale, Explanation, Excuses:
Useful for dealing with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a
number that can be expressed as a rational using 64-bit signed
integers. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Return the value of the internal flag that controls whether
Pixie Scheme III compiles defines automatically.
Rationale, Explanation, Excuses:
Allow Scheme programs to examine important internal state of the
Pixie Scheme III interpreter.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns the (boolean) flag that controls whether Pixie
Scheme III compiles defines automatically. That flag is true if, and only
if, defines are automatically compiled.
For Example:
Type:
Procedure.
Operation:
Invoke the Pixie Scheme III compiler on a Scheme object.
Rationale, Explanation, Excuses:
Pixie Scheme III has a rather minimal compiler built in; this is
how you use it. Actually, it is perhaps better used by setting
the "Compile Defines" flag from the Interpreter Menu, but this
procedure allows you to compile individual objects.
The compiler only compiles lambda expressions.
The top-level loop will print out #<Interpreted lambda expression>
when it returns from "e::compile-form", but if you use "e::inspect" on
what it returns you will see that variable references have been
replaced by references to specific locations in the environment; the
form is being interpreted, but much of the work in interpreting an
uncompiled form -- looking up the values or bindings of symbols -- will
now be side-stepped.
Arguments:
One Scheme object; preferably, a lambda expression.
Side Effects:
Compiles the lambda expression.
Returned Value:
A Scheme object.
For Example:
Type:
Procedure.
Operation:
Cons the argument with the Pixie Scheme III continuation, which will cause it to be evaluated immediately,
in the environment in which "e::cons-with-continuation" was called.
Rationale, Explanation, Excuses:
This procedure is what many Lisp interpretations would call "eval". At the time I implemented it, there
was much debate in the Scheme community about whether Scheme should have an "eval" procedure at all, and
if it did, what that procedure should do. Much of the debate centered around the environment in which
the evaluation should take place. I side-stepped the debate by (1) not calling "e::cons-with-continuation"
"eval", and (2) choosing a name that made it very clear what environment was in use.
At least, it is clear if you know what a "continuation" is.
Note that
is not equivalent to
In Pixie Scheme III, the interaction environment is the one encountered when entering
Scheme expressions into the top-level loop, but "e::cons-with-continuation" uses the environment
in which it was called, which may be the local environment of a lambda expression containing
that call.
Note further that because of the renaming of formal parameters of lambda
expressions during macro expansion, use of "e::cons-with-continuation" within lambda
expressions, with quoted arguments, may give unexpected results, such as:
What is happening is that in Pixie Scheme III, "let" is a macro, which in this case
expands using a renamed lambda variable, into something like:
(The actual name used will vary depending on how many similar substitutions
Pixie Scheme III has made since it was started.)
Arguments:
One Scheme object.
Side Effects:
Evaluates the argument immediately, in the environment in which "e::cons-with-continuation" is called.
Returned Value:
Any Scheme object. Strictly, e::cons-with-continuation does not
return; where you would have expected a return value to appear, what
appears is the result of evaluating the argument.
For Example:
Type:
Procedure.
Operation:
Accepts a list of numbers in the usual form for representing a continued fraction and returns
the corresponding value as a long ratnum.
Rationale, Explanation, Excuses:
Useful in connection with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
A proper list of integers.
Side Effects:
None.
Returned Value:
A long ratnum.
For Example:
Type:
Procedure.
Operation:
Not built in to Pixie Scheme III; to be defined by the user.
Rationale, Explanation, Excuses:
Pixie Scheme III has no complicated built-in debugger; proper
use of the symbol "e::debug" allows loading run at run-time,
or at start-Pixie-Scheme-III time, or whenever you like.
Fundamentally, a debugging program is no different from any other
Scheme program. You should be able to install whatever debugger you
like, and -- if you have the source code -- modify it to suit
yourself. The catch is, that the Pixie Scheme III program needs to be
able to call your debugging program when an error occurs, and to do so
it needs to know the program's "name". Thus I have provided a special
symbol, "e::debug", which the Pixie Scheme III program recognizes and
uses for that purpose.
When a non-fatal error occurs, the Pixie Scheme III error-handling
mechanism prints out an error message, then determines whether
"e::debug" has been defined. If not, error handling provides
some simple trace information -- in effect using a very simple
built-in debugger.
Alternatively, If "e::debug" has been defined, Pixie Scheme III will call
it (and it had better be a procedure accepting one argument), passing
as an argument a list of all the environments within the lexical scope
of the place where the error occurred, that list being sorted in order
of lexical nesting, so that more closely-nested environments occur earlier in
the list.
The procedure "e::debug" may do whatever its creator wishes with that
information. It might well terminate with a call to "e::reset": A
normal return will merely return control to the Pixie Scheme III error-handling
mechanism, which will then proceed with its simple, built-in trace.
Any value returned by "e::debug" will be ignored.
Arguments:
A list of all the environments in the lexical scope of the call to "e::debug".
Side Effects:
Depends on the definition of "e::debug".
Returned Value:
Undefined.
For Example:
Does not apply.
Type:
Procedure.
Operation:
Return a copy of its argument which is "equal?" to the argument, but
in which copied vectors, lists and strings in corresponding positions in
the structure are not "eq?".
Rationale, Explanation, Excuses:
I needed this procedure for development of Pixie Scheme III, and thought
it might be generally useful. The source code for "e::deep-copy" is:
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A Scheme object of the same structure as the argument, and "equal?" to it,
but containing newly-allocated structures for lists, vectors and strings,
where applicable.
For Example:
Type:
Procedure.
Operation:
Automatically skips automatic compilation; even when the "Compile
Defines" menu item is set, "(e::define-no-compile foo <bar>)"
does not compile <bar>, and binds it to "foo". That is,
it does what "(define foo <bar>)" would do if the "Compile
Defines" menu item were not set.
Rationale, Explanation, Excuses:
Sometimes it is useful to compile most things but not all, or to exempt
some procedures from being compiled.
Arguments:
Two: The first an identifier, the second any Scheme object.
Note that "e::define-no-compile" only accepts the simple, two-argument
syntax for "define". It is an error, for example, to attempt
Side Effects:
Causes the second argument to become the value or binding of the first.
Returned Value:
A symbol: Returns the first argument.
For Example:
Type:
Procedure.
Operation:
If necessary, convert a real number to a form that is not
a rational in which numerator and denominator are stored separately.
Rationale, Explanation, Excuses:
Useful for dealing with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
One real number.
Side Effects:
If the argument is a rational in which numerator and denominator are
stored separately, divide the numerator by the denominator and return
the result as some other form of number. Otherwise, return the
argument unchanged.
Returned Value:
A real number.
For Example:
Type:
Constant -- a very large integer.
Operation:
Intended to provide a Unix time for use with forgettable objects
that is sufficiently far in the future that it is unlikely to be
passed by any executing Pixie Scheme III program.
Rationale, Explanation, Excuses:
Adds clarity of purpose to code and saves typing large integers.
For Example:
Type:
Procedure.
Operation:
Print an error message and reset to top-level loop.
Rationale, Explanation, Excuses:
Useful primitive for error-handling.
Arguments:
One string.
Side Effects:
Resets Pixie Scheme III to the top-level loop.
Returned Value:
Does not return.
For Example:
Type:
Procedure.
Operation:
Return the default output port for error messages.
Rationale, Explanation, Excuses:
Pixie Scheme III generally handles the output from error messages
differently from normal output: Error messages are usually sent to
the console. "e::error-port" returns the port to which Pixie Scheme's III
error messages are sent, so that you may make procedures that you
create handle errors in the same way.
Arguments:
None.
Side Effects:
None.
Returned Value:
An output port: Returns the current error port, which is
typically the console.
For Example:
Type:
Procedure.
Operation:
Exit the Pixie Scheme III program immediately, with no second chances and no
confirmation dialog.
Rationale, Explanation, Excuses:
It is sometimes useful to run a Scheme program autonomously -- perhaps
from the Unix command line or from a script. A forced exit is useful in
such circumstances.
Arguments:
None.
Side Effects:
Quits from the Pixie Scheme III program.
Returned Value:
Does not apply.
For Example:
Type:
Procedure.
Operation:
Rationale, Explanation, Excuses:
A "call" or invocation of a Pixie Scheme III macro
involves using a procedure -- sometimes called a "transformer" -- that
was created when the macro was defined, to
transform the expression in which the macro call
occurred, into something else. That "something else" is
evaluated by Pixie Scheme III, to produce the
result of the macro "call".
"e::expand-macro" does all of these steps except for the last one:
It produces the "something else", but does not evaluate it.
For example, in Pixie Scheme III, "if" is a macro. When Pixie Scheme III
encounters an expression like "(if #t 1 2)", Pixie Scheme III
e::expand-macro does all of that except for the last step. It returns
(c::if #t 1 2) as its result. I installed this procedure primarily for
debugging Pixie Scheme III's low-level macro implementation.
Arguments:
Side Effects:
None in its own right, but macro expansion may have side effects that depend
on the transforming procedure associated with the particular macro.
Returned Value:
A list: Returns the expansion of the macro.
For Example:
Type:
Procedure.
Operation:
Recursively expand all the macros, in a Pixie Scheme III expression
until none remain, but do not evaluate the expanded form.
Note that this procedure modifies its argument. (Perhaps I should have
named it "e::expand-macros-recursively!".) For that reason, an attempt to use
"e::expand-macros-recursively" with an argument that is a quoted expression, like
will fail, because quoted expressions are supposed to be constants, and are
not supposed to be modifiable, and Pixie Scheme III is pretty good about catching
attempts to do so. Use e::deep-copy, as shown in
the example below.
Rationale, Explanation, Excuses:
This procedure is rather an elaboration of "e::expand-macro", immediately
above: Whereas "e::expand-macro" only expands the outermost macro in a Scheme
expression (and only works if the car of the expression is in fact a macro),
"e::expand-macros-recursively" goes through the entire expression, expanding
every macro it can find, and doesn't stop until no macros remain.
Like "e::expand-macro", "e::expand-macros-recursively" does not
evaluate the fully-expanded expression.
Arguments:
A Scheme expression, presumably containing macros.
Side Effects:
None in its own right, but macro expansion may have side effects that depend
on the transforming procedure associated with the particular macro.
Returned Value:
Returns the given Scheme expression with all macros expanded.
For Example:
Type:
Procedure.
Operation:
Determine whether a Scheme object is a number stored as a fixnum.
Rationale, Explanation, Excuses:
I installed this procedure to aid in debugging Pixie Scheme's III
functions that deal with numbers. In the present version of
Pixie Scheme III, the only fixnums stored are 64-bit integers.
Note that it is possible to store integers as flonums: Pixie
Scheme III does so frequently.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a number stored
as a fixnum. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Determine whether a Scheme object is a number stored as a flonum
Rationale, Explanation, Excuses:
I installed this procedure to aid in debugging Pixie Scheme III's
functions that deal with numbers. In the present version of
Pixie Scheme III, flonums are used to store only 64-bit
floating-point numbers.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a number stored
as a flonum. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a promise has been forced.
Rationale, Explanation, Excuses:
In case the evaluation of a promise causes
side effects, it may be useful to determine
whether or not that evaluation has already
taken place.
Recall that the result of forcing a promise
the first time is cached, so that subsequent
forces of the same promise cause no additional
evaluation.
Arguments:
One promise.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument has been forced.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether its argument is a forgettable object.
Rationale, Explanation, Excuses:
Predicate to identify object of this type.
Arguments:
One Scheme object of any kind.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a forgettable object. Returns #f otherwise.
For Example:
Type:
Procedure.
Operation:
Retrieve a the expiration time of a Scheme object that has been made forgettable.
Rationale, Explanation, Excuses:
Primitive required to access the content of forgettable objects.
Arguments:
One forgettable object.
Side Effects:
None.
Returned Value:
Multiple-values return: The first item is a boolean indicating whether the forgettable object
has not been forgotten; that is, it is #t if the forgettable object is remembered or unexpired
and #f if the forgettable object has been forgotten. The second item is the expiration time
that was provided for the object. The second value is returned even if the object has expired.
For Example:
Type:
Procedure.
Operation:
Test whether its argument is a forgettable object that has been forgotten.
Rationale, Explanation, Excuses:
Predicate to identify object of this type.
Arguments:
One Scheme object of any kind.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a forgettable object that has been forgotten. Returns #f otherwise.
For Example:
Type:
Procedure.
Operation:
Retrieve a reference or copy of a Scheme object that has been made forgettable.
Rationale, Explanation, Excuses:
Primitive required to access the content of forgettable objects.
Arguments:
One forgettable object.
Side Effects:
None.
Returned Value:
Multiple-values return: The first item is a boolean indicating whether the forgettable object
has not been forgotten; that is, it is #t if the forgettable object is remembered or unexpired
and #f if the forgettable object has been forgotten. The second item is the object that has
been made forgettable, if it has not been forgotten (that is, if the first item is #t), or
undefined, if that object has been forgotten.
If the object made forgettable was not an atom, then the reference to it returned
by this procedure is sufficient to prevent the forgettable object itself from being forgotten,
as long as that reference remains non-garbage. If the object made forgettable was an atom, then
what is returned is not the actual object but a copy of it; no reference exists, and the
forgettable object is given no additional protection against being forgotten.
It is not particularly useful to make atoms forgettable.
Pixie Scheme III provides the procedure e::atom? to determine what kinds
of objects are atoms.
For Example:
Type:
Procedure.
Operation:
Test whether its argument is a forgettable object that has been remembered.
Rationale, Explanation, Excuses:
Predicate to identify object of this type.
Arguments:
One Scheme object of any kind.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a forgettable object that has been remembered. Returns #f otherwise.
For Example:
Type:
Procedure.
Operation:
Retrieve a the probability of remembering a Scheme object that has been made forgettable.
Rationale, Explanation, Excuses:
Primitive required to access the content of forgettable objects.
Arguments:
One forgettable object.
Side Effects:
None.
Returned Value:
Multiple-values return: The first item is a boolean indicating whether the forgettable object
has not been forgotten; that is, it is #t if the forgettable object is remembered or unexpired
and #f if the forgettable object has been forgotten. The second item is the expiration time
that was provided for the object, if the forgettable object has not been forgotten (that is,
if the first item is #t), and is undefined if the forgettable object has been forgotten.
For Example:
Type:
Procedure.
Operation:
Test whether its argument is a forgettable object that has been unexpired.
Rationale, Explanation, Excuses:
Predicate to identify object of this type.
Arguments:
One Scheme object of any kind.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a forgettable object that has been unexpired. Returns #f otherwise.
For Example:
Type:
Procedure.
Operation:
Cause garbage collection.
Rationale, Explanation, Excuses:
Garbage collection happens automatically, when Pixie Scheme's III current
main memory is about to fill up. It may be useful to force it; for
example, when about to measure code speed, or when a time-consuming
interruption of a process controlled by Pixie Scheme III would be
unfortunate ...
Computer: Captain! CAPTAIN!! Klingons close on the port bow!
Captain James T. Schemer: Shields up! Fire photon torpedoes!
Computer: Just a few minutes while I garbage-collect. Be patient ...
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Generate a symbol that has no value or binding.
This operation is atomic, in the sense that even if many Pixie Scheme III
procedures call "e::gensym", even at the same time, every gensym'd
value returned will be unique.
Rationale, Explanation, Excuses:
Gensym'd symbols are useful for various kinds of software that
needs "scratch" labels for things.
The symbols created by "e::gensym" are of the general form
"gNNNNN...", where the N's constitute the external representation
of a positive integer greater than or equal to 23000. The value
of "NNNNN..." will be congruent to the kitten number of the Pixie
Scheme III process that called "e::gensym", modulo the maximum possible
number of kittens: That constraint provides a different set of
gensym symbols for each kitten, and so allows more than one kitten
to use the "gensym" mechanism at the same time with no possibility
that two kittens will inadvertently create the same symbol.
I chose to use these particular gensym symbols in memory of Ratfor
(rational Fortran), which generated symbols of the same form.
The procedure will check each generated symbol before returning; if
the symbol it generates already happens to have a value or
a binding, it will choose another; that is, the
user is free to use symbols of the form "gNNNNN..." without worrying
about conflict with symbols generated by "e::gensym".
Arguments:
None.
Side Effects:
None.
Returned Value:
A symbol: Returns a symbol that had no value or binding when it
was generated.
For Example:
Type:
Procedure.
Operation:
Obtain the 64-bit tag portion of the Pixie Scheme III
tagged aval associated with a Pixie Scheme III object.
Rationale, Explanation, Excuses:
This procedure provides a low-level view of part of
the structure of Pixie Scheme III objects. I implemented it
to aid in debugging Pixie Scheme III.
I am reluctant to document what the tag bits mean because
their meaning will almost certainly change from release
to release. Send me EMail if you really want to know.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
An integer: Returns the tag associated with the argument.
For Example:
Type:
Procedure.
Operation:
Hides the Pixie Scheme III sense lights, without changing their illumination
state; that is, if you subsequently make the sense lights visible, they will
appear the way you last set them.
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
None.
Side Effects:
Makes all of the Pixie Scheme III sense lights invisible.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is an "inf" -- a special flonum value used to represent
an infinity. (More commonly, used to represent the result of a calculation
that has overflowed the allowed range of flonums.) Also returns #t if the object is a rational whose
numerator and denominator are stored separately, when the denominator is zero and the numerator is not.
Rationale, Explanation, Excuses:
Pixie Scheme III uses IEEE floating-point numbers, which have infs and nans, so it
is useful to be able to test for their presence.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an inf (of any sign),
or if it is a rational whose
numerator and denominator are stored separately, when the denominator is zero and the numerator is not.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Report a useful selection of information about the low-level structure of
a Pixie Scheme III object.
Rationale, Explanation, Excuses:
I installed this procedure primarily for debugging Pixie Scheme III. It is also
useful for satisfying one's curiosity about what Pixie Scheme III is doing.
"e::inspect" returns its argument. Thus you may wrap "(e::inspect ...)"
around basically any Scheme object, anywhere, to print out useful information,
without interrupting the flow of calculation at the point where the object
is used.
The first line of output from "e::inspect" is generally the numeric values
of the Pixie Scheme III tagged aval that represents it, with the 64-bit tag
separated from the 64-bit value by a dash. The numbers will be printed in
hexadecimal, and will be followed by information about the cdr-coding
(if any) of the object.
"e::inspect" is capable of printing lots of output, such as the entire
source code or compiled code of a lambda expression or macro. The volume
of printout is thus affected by the settings of the print-length and
print-depth variables for lists and for vectors. Set these quantities to
large numbers if you want to see all of the output from "e::inspect".
Arguments:
Any Scheme object.
Side Effects:
None.
Returned Value:
Any Scheme object: "e::inspect" returns its argument.
For Example:
Type:
Procedures.
Operation:
Get and set internal variables used to control printing
of large data structures.
Rationale, Explanation, Excuses:
Printing a circularly-linked data structure is a
task that does not end. To help avoid such conditions,
Pixie Scheme III uses four internal variables to control
how many elements of lists and vectors are printed,
and to control how deep nested lists and vectors are
printed.
The variables are not accessible by name; procedures
are used to set and obtain their values, but for purposes
of discussion, let us imagine that they are called:
Current values of all these variables are displayed in the
Pixie Scheme III Instrument Panel.
When a list is longer than the value of "list-print-length",
the print routines use an ellipsis to indicate the "extra" elements. Thus
if "list-print-length" is 6, a list might print as:
and similarly for vectors.
When lists are nested more deeply than the value of "list-print-depth",
the print routines use an ellipsis to indicate the "extra" elements. Thus
if "list-print-depth" is 6, a deeply-nested list might print as:
Two caveats apply to the use of these internal variables:
Arguments:
The "set" procedures: An integer no less than three.
The other procedures: None.
Side Effects:
None.
Returned Value:
The "set" procedures: #t.
The other procedures: An integer: Return the present value of the indicated special variable.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a "logic constant" -- one of "#u" and "#s".
Rationale, Explanation, Excuses:
This procedure is for logic programming along the lines described in
Daniel P. Friedman, William E. Byrd and Oleg Kiselyov,
The Reasoned Schemer, MIT Press, 2005. Pixie Scheme III provides the
logic constants #u and #s.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is either #u or #s.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a "long complex" -- a complex number
with nonzero imaginary part.
Rationale, Explanation, Excuses:
Useful for dealing with Pixie Scheme III's internal representation of complex
numbers, in which the real and imaginary parts are stored separately.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a complex number
with nonzero imaginary part. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a "long ratnum" -- a rational number
in which the numerator and denominator are stored separately.
Rationale, Explanation, Excuses:
Useful for dealing with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a rational number
in which the numerator and denominator are stored separately. Otherwise, returns #f.
For Example:
Type:
Operation:
Create a Pixie Scheme III low-level macro, and make it be the value of a symbol.
Rationale, Explanation, Excuses:
The macros referred to are Pixie Scheme III's low-level internal
implementation, not the hygienic macros defined in the R5 report.
A "call" or invocation of a Pixie Scheme III macro involves using
a procedure that was created when the macro was defined, to transform
the expression in which the macro call occurred, into something else.
That "something else" is evaluated by Pixie Scheme III, to produce the
result of the macro "call".
"e::macro" creates the procedure in question, makes it part of a
Pixie Scheme III low-level macro object, and binds that object to a
symbol -- the symbol being what we might informally call
the macro's "name".
The Pixie Scheme III code for a macro "call" is similar to the code
for a procedure call: It is a list whose first item evaluates to
the macro in question. When Pixie Scheme III encounters such an
expression, it passes the entire list as an argument to the lambda
expression associated with that macro, then further evaluates
whatever the lambda expression returns.
The most conventional use of macros is to perform some syntactic
transformation on the list which constitutes the macro call, but
other uses are certainly possible.
Arguments:
Two: The first, a symbol, and the second, a lambda expression of
one argument, which will be passed the entire expression that constitutes
a macro "call", when the macro in question is called.
Side Effects:
None.
Returned Value:
A symbol: Returns the first argument.
For Example:
Type:
Operation:
Create a Pixie Scheme III low-level macro, but do not bind it to a symbol.
Rationale, Explanation, Excuses:
The macros referred to are Pixie Scheme's III low-level internal
implementation, not the macros defined in the R5 report.
A "call" or invocation of a Pixie Scheme III macro involves using
a procedure that was created when the macro was defined, to transform
the expression in which the macro call occurred, into something else.
That "something else" is evaluated by Pixie Scheme III, to produce the
result of the macro "call".
"e::macro-body" creates the procedure in question and makes it part of a
Pixie Scheme III low-level macro object, but does not bind that
object to a symbol -- less formally, the object is not given a "name".
The Pixie Scheme III code for a macro "call" is similar to the code
for a procedure call: It is a list whose first item evaluates to
the macro in question. When Pixie Scheme III encounters such an
expression, it passes the entire list as an argument to the lambda
expression associated with that macro, then further evaluates
whatever the lambda expression returns.
The most conventional use of macros is to perform some syntactic
transformation on the list which constitutes the macro call, but
other uses are certainly possible.
Arguments:
One lambda expression of one argument, which will be passed the entire expression that constitutes
a macro "call", when the macro in question is called.
Side Effects:
None.
Returned Value:
A macro.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a Pixie Scheme III low-level macro.
Rationale, Explanation, Excuses:
The macros referred to are Pixie Scheme III's low-level implementation,
not the kind defined in the R5 report.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a Pixie Scheme III
low-level macro. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Create a new instance of an unexpired forgettable object.
Rationale, Explanation, Excuses:
Constructor for forgettable objects.
Arguments:
Three: The first may be any Scheme object. The second to be an integer representing a "Unix time" (a number of seconds
presumed to have elapsed since the start of calendar year 1970, common era), taken as the "expiration time" of the
forgettable object being created. The third to be a real number between zero and one (inclusive), taken as the
probability that the forgettable object shall be remembered after its expiration time has passed.
Side Effects:
Creates a new forgettable object.
Returned Value:
The new instance of forgettable object created.
For Example:
Type:
Procedure.
Operation:
Create a list of evenly-spaced exact integers.
Rationale, Explanation, Excuses:
Uses include iteration, as with "map" or "for-each".
Arguments:
Three integers: The first is the start of the range; the second is the next integer past the end of the range;
the third is the spacing between adjacent integers in the range.
Side Effects:
None.
Returned Value:
A list of exact integers that starts at the first argument and advances
toward the second argument, but not to or past it, in steps of the third argument.
If the third argument has sign different from the sign of (second argument
minus first argument), the result is the empty list. If the first argument
equals the second argument, the result is the empty list.
For Example:
Type:
Procedure.
Operation:
Create a rational number in which the numerator and denominator are
stored separately.
Rationale, Explanation, Excuses:
Useful for dealing with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
Two integers.
Side Effects:
None.
Returned Value:
A rational number obtained from the arguments by treating
the first as the numerator and the second as the denominator, and
reducing the resulting fraction to lowest terms. The numerator will
bear the appropriate sign, regardless whether the first or second
argument was signed. If both arguments are exact, the stored
numerator and denominator will be exact and the overall result will be
exact. Otherwise, the stored numerator and denominator will both be
inexact and the overall result will be inexact.
For Example:
Type:
Procedure.
Operation:
Create a class in the Pixie Scheme III class system. See the section of the
Pixie Scheme III Help File
titled "Class System" for details of what this system is and how to use it.
Rationale, Explanation, Excuses:
The fundamental primitive for access to the Pixie Scheme III class system
Arguments:
Four. The first a symbol that identifies the class, the second a list of
classes from which the new class inherits, the third a list of lists of
symbols and their bindings, representing the class variables of the new
class and their default values, and the fourth a list of lists of
symbols and their bindings, representing the instance variables of the new
class and their default values.
Side Effects:
None.
Returned Value:
A class in the Pixie Scheme III class system.
For Example:
Type:
Procedure.
Operation:
Merges two previously sorted lists into one list sorted in the same way.
This procedure is stable when used with comparison predicates that
return #f when applied to identical arguments.
Rationale, Explanation, Excuses:
Widely useful.
Arguments:
Three or four. The first two, the lists to be merged. The
role of the third depends on whether the fourth, optional argument is
present. If there is no fourth argument, then the third argument
should be a procedure that accepts two arguments of the kind in the
lists to be merged, and returns a boolean indicating whether its first
argument is to be considered "less than" its second argument.
If the fourth argument is present, then it must be a procedure
accepting one argument of the kind in the lists being merged. The
fourth argument is applied to each element of the lists being merged
in turn, and the arguments passed to the third argument are what the
fourth argument returns. Thus if the elements of the lists being
merged are some sort of structure, such as lists or vectors, the
fourth argument might be used to extract one particular item from such
a structure for use in the comparison. See the examples below.
Side Effects:
None.
Returned Value:
A new list, whose elements are the elements of the two given lists,
in sort order.
For Example:
Type:
Procedure.
Operation:
Merges two previously sorted lists into one list sorted in the same way, in
the process destroying the structure of the original lists. Merging lists
this way reduces the amount of Scheme main memory used in the merge operation.
This procedure is stable when used with comparison predicates that
return #f when applied to identical arguments.
Rationale, Explanation, Excuses:
Widely useful.
Arguments:
Three or four. The first two, the lists to be merged. The
role of the third depends on whether the fourth, optional argument is
present. If there is no fourth argument, then the third argument
should be a procedure that accepts two arguments of the kind in the
lists to be merged, and returns a boolean indicating whether its first
argument is to be considered "less than" its second argument.
If the fourth argument is present, then it must be a procedure
accepting one argument of the kind in the lists being merged. The
fourth argument is applied to each element of the lists being merged
in turn, and the arguments passed to the third argument are what the
fourth argument returns. Thus if the elements of the lists being
merged are some sort of structure, such as lists or vectors, the
fourth argument might be used to extract one particular item from such
a structure for use in the comparison. See the examples below.
Side Effects:
Destroys the structure of the original lists.
Returned Value:
A list, whose elements are the elements of the two given lists,
in sort order. The returned list will not be entirely new: It will
contain some of the cons cells of the original list, in such a way
that the list structure of the original lists is destroyed.
For Example:
Type:
Procedure.
Operation:
Construct a Pixie Scheme III string containing a number formatted with two
digits to the right of the decimal point.
Rationale, Explanation, Excuses:
Standard R5 Scheme procedures offer little immediate capability for
formatting numbers in many ways.
Arguments:
One real number:
Side Effects:
None.
Returned Value:
A string: Returns the first argument formatted with two digits to the right of the decimal point.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a "multiple-values return" -- a special
type of Scheme object used by Pixie Scheme III as an intermediary between "values"
and "call-with-values".
Rationale, Explanation, Excuses:
"Multiple-values returns" are a class of object peculiar to Pixie
Scheme III, whose existence and use is a low-level implementation detail
that might become visible to users, and that might be of interest to
some. This predicate provides a way to distinguish these objects.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a multiple-values return.
Otherwise, returns #f
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a "nan" -- a special flonum
value used to represent the result of a mathematical calculation that
could not produce a numerical result. Also returns #t if the object is a rational whose
numerator and denominator are stored separately and are both zero.
Rationale, Explanation, Excuses:
Pixie Scheme III uses IEEE floating-point numbers, which have infs and nans, so it
is useful to be able to test for their presence.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a nan,
or if it is a rational whose
numerator and denominator are stored separately and are both zero.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether the amount of Pixie Scheme III main memory in use equals
or exceeds ninety percent of the amount available.
Rationale, Explanation, Excuses:
It may occasionally be useful to know when Pixie Scheme III is about to garbage-collect.
A user could easily write this procedure, but it is faster as a built-in.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the amount of Pixie Scheme III main memory in use
equals or exceeds ninety percent of the amount available. Otherwise, returns #f
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a "non-printing object"; that is, whether it is #n.
Rationale, Explanation, Excuses:
I added non-printing objects primarily as a value to return
from interrupt handlers. In a project I was working on, I had some
interrupts that were called frequently but mostly did nothing; I
wanted to have them print nothing at all so as not to clutter up log
files with repetitive meaningless output. An interrupt handler has to
return something to the top-level read-eval-print loop of the kitten
which handles it, so a non-printing object was just the thing to use
for a returned value from such handlers
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is #n.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is different from the empty list.
Rationale, Explanation, Excuses:
This operation is marginally faster than the composition of "not"
and "null?", and allowed rapid modification of code when I converted
my Scheme system from one that used the empty list to represent falsehood
to one that didn't.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is not the empty list.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Construct a Pixie Scheme III string containing a number formatted with a given number of
digits to the right of the decimal point.
Rationale, Explanation, Excuses:
Standard R5 Scheme procedures offer little immediate capability for
formatting numbers in many ways.
Arguments:
Two: The first is a real number to be formatted; the second an integer in the range [0..10],
indicating the number of digits to appear to the right of the decimal point.
Side Effects:
None.
Returned Value:
A string: Returns the first argument formatted with n digits to the right of the decimal point, where n is
the second argument. The value of n must be in the range [0 .. 10].
For Example:
Type:
Procedure.
Operation:
A version of call-with-current-continuation
that does not support dynamic-wind.
Rationale, Explanation, Excuses:
Pixie Scheme III implements dynamic-wind generally along the
lines of the implementation demonstrated by Jonathan Rees (1992) in "The Scheme of Things: The June
Meeting", published in Lisp Pointers V(4), October-December 1992. That implementation
involves modifying call-with-current-continuation.
The unmodified version is "e::original-cwcc".
Arguments:
One argument, which must be a procedure that itself takes one argument.
Side Effects:
Saves the current state of Scheme in such a way that it can subsequently
be restored at will. See call-with-current-continuation
for details.
Returned Value:
See call-with-current-continuation for details.
For Example:
Type:
Procedure.
Operation:
Perform a block of code in a
referentially transparent
manner.
Rationale, Explanation, Excuses:
Referentially transparent programming has many enthusiasts and is
theoretically interesting; this primitive provides support for it.
Arguments:
One procedure of no arguments.
Side Effects:
The interpretation of referential transparency used by this
procedure allows the block of code invoked to perform input and
output, which many may consider as allowing side effects, but that
block is not allowed to use public Pixie Scheme III procedures that
change state; any attempt to use them is treated as an error.
The procedures so treated are:
Returned Value:
Whatever is returned by the block of code that is the passed argument.
For Example:
but
produces the error message:
Type:
Procedure.
Operation:
Test whether the value or binding of a
variable is "permanent", in the sense that an attempt to change it
with, for example, "set!", is an error.
Rationale, Explanation, Excuses:
To make it difficult inadvertently to redefine fundamental Scheme
procedures like "+" and "cons", I provide symbols with a
"permanent" flag. When set, any attempt to change the value or
binding of the given symbol causes Pixie Scheme III to report an error.
Procedure "e::clear-permanent!" clears this flag, so you can, for example,
redefine "cons", if you really, really, want to. Procedure "e::set-permanent!"
sets it, so you can't. Procedure "e::permanent?" tests whether it is set
or not.
Arguments:
One symbol.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the given symbol has
a value or binding that is permanent, in the sense described above.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Test whether a Scheme object is a promise.
Rationale, Explanation, Excuses:
In Pixie Scheme III, promises are a distinct type; it
seemed useful to have a simple way to test for them.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a promise.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Return a random number generated by the Unix "random" procedure.
Rationale, Explanation, Excuses:
Unix provides the high-quality random-number generator "random",
and the procedure "srandom" to seed it. Pixie Scheme III provides
a simple interface to these procedures.
Pixie Scheme III seeds the Unix "random" mechanism with the Unix time
every time Pixie Scheme III is launched. If you wish to make "e::random"
generate the same series of numbers on several separate occasions --
for example, for debugging a calculation that uses "e::random" -- you
will have to seed the random number generator with the same seed before
each occasion. Use "e::srandom" to do so.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer. Returns the result of a call to Unix "random()".
For Example:
Type:
Procedure.
Operation:
Present a prompt in the Pixie Scheme III dialog panel, and accept a string
read therefrom. Enclosing double-quotes are not required as the string
is typed.
Rationale, Explanation, Excuses:
Useful for Scheme programs which interact with the user.
Arguments:
One string, to be displayed in the Pixie Scheme III dialog panel, as a prompt.
Side Effects:
None.
Returned Value:
The string typed by the user in the Pixie Scheme III dialog panel. Enclosing
double-quotes are not required when that string is typed.
For Example:
Type:
Procedure.
Operation:
Applies the given operation to the first two elements of the list,
then applies the given operation to the result and the next element
of the list, and so on. If the optional start value is given, starts
out by applying the given operation to the start value and the first
element of the list.
Rationale, Explanation, Excuses:
Variously useful, perhaps with the "map-reduce" programming paradigm.
Arguments:
Two or three: The first a procedure which should accept two
arguments of the same kind and return a result that is also of the
same kind; the second a list whose elements are that kind of object;
the third, if present, a single element of that kind.
Side Effects:
None in its own right, though the procedure might have side effects of its own.
Returned Value:
An object of the same kind as the elements of the list.
For Example:
Type:
Procedure.
Operation:
Accepts a real in the range where it may be converted to a long ratnum, and returns the
list of numbers that represents that real as a continued fraction in the usual form.
Rationale, Explanation, Excuses:
Useful in connection with Pixie Scheme III's internal representation of rational
numbers, in which the numerator and denominator are stored separately, as
64-bit signed integers.
Arguments:
A real in the range where it may be converted to a long ratnum.
Side Effects:
None.
Returned Value:
A list of integers.
For Example:
Type:
Procedure.
Operation:
Abandon processing and restart the top-level loop.
Rationale, Explanation, Excuses:
Being able to unpaint yourself from a corner is a
useful control feature.
Arguments:
None.
Side Effects:
None.
Returned Value:
Does not apply; "e::reset" never returns.
For Example:
Type:
Procedure.
Operation:
Find the number of bytes free in Pixie Scheme III main memory.
Rationale, Explanation, Excuses:
Simple storage-instrumentation procedure: Just returns a
number. Contrast with "e::show-room", which prints out text
describing memory use.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the number of bytes free in Pixie
Scheme III main memory.
For Example:
Type:
Procedure.
Operation:
Circularly rotate the pattern of sense lights -- both illumination and visibility --
by the given integer. Positive integers rotate to the left. The rotation is
done modulo the number of sense lights.
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
One integer.
Side Effects:
Changes the pattern of the Pixie Scheme III sense lights.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Makes up a new list comprising all elements of the given list for which
the predicate returns true.
Rationale, Explanation, Excuses:
Widely useful.
Arguments:
Two or three: The first a procedure that takes one operation; the second a list
of elements for which it is of interest whether the procedure returns
true or false. The third, if present, is a procedure intended to be applied
to each element of the list before applying the first argument, in which case
it is of interest whether the functional composition of the first and third
arguments returns true, with the third argument being applied before the first.
Side Effects:
None in its own right, though the procedures might have side effects of their own.
Returned Value:
With two arguments, a list of those elements of the given
list for which the procedure returns a value other than #f. With
three arguments, a list of those elements of the given list for which
would return true.
For Example:
Type:
Procedure.
Operation:
Determine whether its argument is suitable for identifying
a Pixie Scheme III sense light; that is, whether it is an exact
integer in the range [0..7].
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean. Returns #t if, and only if, the argument is an exact integer
in the range allowed as a sense-light identifier; that is, in the range
[0..7]. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Determine whether its argument is suitable for identifying
a Pixie Scheme III sense-light illumination-state; that is, whether it is an exact
integer in the range [0..7].
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean. Returns #t if, and only if, the argument is an exact integer
in the range allowed as a sense-light illumination-state; that is, in the range
[0..7]. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Set all of the Pixie Scheme III sense lights to the same illumination state.
Does not change the visibility of any sense light.
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
One exact integer in the range allowed as a sense-light illumination-state; that is,
in the range [0..7].
Side Effects:
Changes the illumination state of all of the Pixie Scheme III sense lights.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Set a particular Pixie Scheme III sense lights to a particular illumination state.
Does not change the visibility of the sense light.
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
Two: The first an exact integer in the range allowed as a
sense-light identifier; that is, in the range [0..7]. The second, an
exact integer in the range allowed as a sense-light
illumination-state; that is, in the range [0..7].
Side Effects:
Changes the illumination state of the given sense light to the given value.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
If the second argument is #t, makes the given sense light
visible; if the second argument is #f, makes the given sense light
invisible. Does not change the illumination state of the sense light.
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
Two: The first an exact integer in the range allowed as a
sense-light identifier; that is, in the range [0..7]. The second, a
boolean.
Side Effects:
Changes the visibility of the given sense light.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Turns all of the Pixie Scheme III sense lights off; that is, sets their
illumination state to zero. Does not change the visibility of any sense light.
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
None
Side Effects:
Turns off all sense lights.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Set the internal flag that tell Pixie Scheme III to compile defines automatically.
Rationale, Explanation, Excuses:
Provides Scheme-program control of an important internal flag.
Arguments:
None.
Side Effects:
Turns on automatic compilation.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Change the expiration time of a forgettable object that has not expired.
Rationale, Explanation, Excuses:
Provides flexibility of use of forgettable objects.
Arguments:
Two: The first, a forgettable object; the second, a Unix time (an integer indicating the number
of seconds presumed to have passed since the start of calendar year 1970, common era).
Side Effects:
Changes the expiration time of a forgettable object that has not expired, to the new
value given. Has no effect on forgettable objects that have been remembered or forgotten.
Returned Value:
A boolean indicating whether the change took effect; that is, #t if the forgettable object
was unexpired when the procedure was executed, and #f if it had been remembered or forgotten.
For Example:
Type:
Procedure.
Operation:
Change the probability of remembering a forgettable object that has not expired.
Rationale, Explanation, Excuses:
Provides flexibility of use of forgettable objects.
Arguments:
Two: The first, a forgettable object; the second, a real number between zero and one (inclusive).
Side Effects:
Changes the probability of remembering a forgettable object that has not expired, to the new
value given. Has no effect on forgettable objects that have been remembered or forgotten.
Returned Value:
A boolean indicating whether the change took effect; that is, #t if the forgettable object
was unexpired when the procedure was executed, and #f if it had been remembered or forgotten.
For Example:
Type:
Procedure.
Operation:
Set the "permanent" flag associated with a symbol.
Rationale, Explanation, Excuses:
To make it difficult inadvertently to redefine fundamental Scheme
procedures like "+" and "cons", I provide symbols with a
"permanent" flag. When set, any attempt to change the value or binding
of the given symbol causes Pixie Scheme III to report an error.
Procedure "e::clear-permanent!" clears this flag, so you can, for example,
redefine "cons", if you really, really, want to. Procedure "e::set-permanent!"
sets it, so you can't. Procedure "e::permanent?" tests whether it is set
or not.
You may of course use these procedures for new symbols that you yourself create.
Arguments:
One symbol.
Side Effects:
Makes it an error to change the value or binding of the argument.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Set the internal flag that tell Pixie Scheme III to display numbers with the full precision available.
Rationale, Explanation, Excuses:
Provides Scheme-program control of an important internal flag.
Arguments:
None.
Side Effects:
Causes Pixie Scheme's III numeric display routines to use full precision.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Change the 64-bit tag portion of the Pixie Scheme III
tagged aval associated with a Pixie Scheme III object.
Rationale, Explanation, Excuses:
This procedure provides detailed and destructive low-level control of
part of the structure of Pixie Scheme III objects. I implemented it to
aid in debugging Pixie Scheme III.
ALMOST ANY USE OF THIS PROCEDURE WILL CAUSE PIXIE SCHEME III TO CRASH!!
Proper operation of Pixie Scheme III depends on tags accurately characterizing the
structure of the objects with which they are associated. On the basis of an
incorrect tag, Pixie Scheme III might decide to dereference something that would have
been a valid pointer if the tag had been correct, but actually isn't. Other forms
of disaster are also possible.
I am reluctant to document what the tag bits mean because
their meaning will almost certainly change in subsequent
releases. Send me EMail if you really want to know.
Arguments:
Two: The first, any Scheme object; the second, an integer, taken to be the new tag value for the
first argument.
Side Effects:
Alters the low-level structure of the argument, likely disastrously.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Provide a lengthy printout describing that part of the
Pixie Scheme III active generation that is presently in use.
Rationale, Explanation, Excuses:
For use in debugging.
Caution: This procedure can produce
enormous amounts of output.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Provide a lengthy printout describing that part of the
Pixie Scheme III aging generation that is presently in use.
Rationale, Explanation, Excuses:
For use in debugging.
Caution: This procedure can produce
enormous amounts of output.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Print human-readable information about all the environments
lexically visible from the point where "e::show-dynamic-environment-list"
was called, but only for environments which were created by the execution of a
lambda expression or by some other Scheme form that creates an environment. That is,
this procedure tells nothing about the interaction environment, the Scheme-report
environment, or the null environment.
Rationale, Explanation, Excuses:
The fundamental construct in a Pixie Scheme III environment is a pair whose
car is a value or binding -- any Scheme object -- and whose cdr is the symbol which
has teat value or binding. The top-level environment is hashed: It is a vector,
each of whose elements is a list of value/symbol pairs. All other environments
are lists of value/symbol pairs.
At any given point in the execution of Pixie Scheme III code, there
exists an implicit list of all the environments that are lexically visible from
that point, sorted so that those lexically closer to
the code executing are nearer
the car of the list.
This procedure shows human-readable information about all the environments
on that list that are created dynamically, by procedures that are running. It omits the environments
that are visible from the top-level loop. These latter environments are large:
Printing them out would take
many lines and much time. With "e::show-dynamic-environment-list", you
don't need to look at printout of the top-level environment if you
don't need it.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Print human-readable information about the nearest environment
lexically visible from the point where "e::show-environment"
was called.
Rationale, Explanation, Excuses:
The fundamental construct in a Pixie Scheme III environment is a pair whose
car is a value -- any Scheme object -- and whose cdr is the symbol to which
that value is bound. The top-level environment is hashed: It is a vector,
each of whose elements is a list of value/symbol pairs. All other environments
are lists of value/symbol pairs.
At any given point in the execution of Pixie Scheme III code, there
exists an implicit list of all the environments that are lexically visible from
that point, sorted so that those lexically closer to
the code executing are nearer
the car of the list.
This procedure shows human-readable information about only one
environment on that list -- the one lexically nearest to the point at
which "e::show-environment" was called.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Print human-readable information about all environments
lexically visible from the point where "e::show-environment-list"
was called.
Rationale, Explanation, Excuses:
The fundamental construct in a Pixie Scheme III environment is a pair whose
car is a value or binding -- any Scheme object -- and whose cdr is the symbol which
has teat value or binding. The top-level environment is hashed: It is a vector,
each of whose elements is a list of value/symbol pairs. All other environments
are lists of value/symbol pairs.
At any given point in the execution of Pixie Scheme III code, there
exists an implicit list of all the environments that are lexically visible from
that point, sorted so that those lexically closer to
the code executing are nearer
the car of the list.
This procedure shows human-readable information about every
environment on that list.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Return the value of the internal flag that controls whether
Pixie Scheme III displays numbers with the full precision available.
Rationale, Explanation, Excuses:
Allows Scheme programs to examine important internal state of the
Pixie Scheme III interpreter.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns the (boolean) flag that controls whether Pixie
Scheme III displays numbers with the full precision available. This flag is
true if, and only if, numbers are displayed with the full precision available.
For Example:
Type:
Procedure.
Operation:
Show a low-level description of every locked object in Scheme main
memory, and of the state of locking of bins of the hash tables used to
control access to Pixie Scheme III's oblist and top-level environment.
Rationale, Explanation, Excuses:
For use in debugging.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Provide an extremely lengthy printout describing that part of
Pixie Scheme III main memory that is presently in use.
Rationale, Explanation, Excuses:
For use in debugging.
Caution: Pixie Scheme III main memory can be as large
as 64 Gigabytes. If so, and if you call "e::show-room" at a time
when a large part of that memory is in use, the
procedure will produce several billion lines of output -- or
at least to try to do so -- and there is no way to preselect just part
of it.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Describe current Pixie Scheme III memory use in human-readable form.
Rationale, Explanation, Excuses:
Simple storage-instrumentation procedure: Contrast with "e::room", which
just returns the number of bytes available in Pixie Scheme III main memory.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Shows the Pixie Scheme III sense lights, without changing their illumination
state; that is, they will now become visible and will look the way you last set them.
Rationale, Explanation, Excuses:
Useful for controlling the Pixie Scheme III sense lights.
Arguments:
None.
Side Effects:
Makes all of the Pixie Scheme III sense lights visible.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Sorts a list or a vector.
This procedure is stable when used with comparison predicates that
return #f when applied to identical arguments.
Rationale, Explanation, Excuses:
Widely useful.
Arguments:
Two or three. The first is the list or vector to be
sorted. The role of the second depends on whether the third, optional
argument is present. If there is no third argument, then the second
argument should be a procedure that accepts two arguments of the kind
in the list or vector to be sorted, and returns a boolean indicating
whether its first argument is to be considered "less than" its second
argument.
If the third argument is present, then it must be a procedure
accepting one argument of the kind in the list or vector being sorted. The
third argument is applied to each element of the list or vector being sorted
in turn, and the arguments passed to the second argument are what the
third argument returns. Thus if the elements of the list or vector being
sorted are some sort of structure, such as lists or vectors, the
third argument might be used to extract one particular item from such
a structure for use in the comparison. See the examples below.
Side Effects:
None.
Returned Value:
A new list or vector, whose elements are the elements of the
given list or vector, sorted from least to greatest, in the sense
given by the second and third arguments.
For Example:
Type:
Procedure.
Operation:
Sorts a vector "in place"; that is, permutes the
elements of the given vector into sorted order.
This procedure is stable when used with comparison predicates that
return #f when applied to identical arguments.
Rationale, Explanation, Excuses:
Widely useful.
Arguments:
Two or three. The first is the vector to be
sorted. The role of the second depends on whether the third, optional
argument is present. If there is no third argument, then the second
argument should be a procedure that accepts two arguments of the kind
in the vector to be sorted, and returns a boolean indicating
whether its first argument is to be considered "less than" its second
argument.
If the third argument is present, then it must be a procedure
accepting one argument of the kind in the vector being sorted. The
third argument is applied to each element of the vector being sorted
in turn, and the arguments passed to the second argument are what the
third argument returns. Thus if the elements of the vector being
sorted are some sort of structure, such as lists or vectors, the
third argument might be used to extract one particular item from such
a structure for use in the comparison. See the examples below.
Side Effects:
Rearranges the elements of the given vector.
Returned Value:
The original vector, sorted from least to greatest, in the
sense given by the second and third arguments.
For Example:
Type:
Procedure.
Operation:
Tests whether a list or vector is sorted.
Rationale, Explanation, Excuses:
Widely useful.
Arguments:
Two or three. The first is the list or vector to be
tested. The role of the second depends on whether the third, optional
argument is present. If there is no third argument, then the second
argument should be a procedure that accepts two arguments of the kind
in the given list or vector, and returns a boolean indicating
whether its first argument is to be considered "less than" its second
argument.
If the third argument is present, then it must be a procedure
accepting one argument of the kind in the given list or vector. The
third argument is applied to each element of the list or vector being tested
in turn, and the arguments passed to the second argument are what the
third argument returns. Thus if the elements of the list or vector being
tested are some sort of structure, such as lists or vectors, the
third argument might be used to extract one particular item from such
a structure for use in the comparison. See the examples below.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the given list or vector is
sorted from least to greatest in the sense implied by the second and
third arguments. Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Seed the Unix random number generator, "random", by calling "srandom".
Rationale, Explanation, Excuses:
Unix provides the high-quality random-number generator "random",
and the procedure "srandom" to seed it. Pixie Scheme III provides
a simple interface to these procedures.
Pixie Scheme III seeds the Unix "random" mechanism with the Unix time
every time Pixie Scheme III is launched. If you wish to make "e::random"
generate the same series of numbers on several separate occasions --
for example, for debugging a calculation that uses "e::random" -- you
will have to seed the random number generator with the same seed before
each occasion. Use "e::srandom" to do so.
Arguments:
One integer, taken as an argument to be passed to Unix "srandom".
Side Effects:
Seeds the Unix "random" random-number generator.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Determine the number of items on Pixie Scheme's III
run-time stack.
Rationale, Explanation, Excuses:
The Scheme engine that underlies Pixie Scheme III has a
run-time stack, much like the run-time stack used by
more conventional programming languages, such as
BCPL and PL/M -- er, make that C and Java.
(Pixie Scheme III's Scheme engine is not running directly
on the hardware: What actually executes
is a C program, with its own run-time stack, which runs
the Scheme engine and manipulates the Scheme engine's
run-time stack -- which is different from the run-time
stack of the C code -- as an emulated program on an
emulated Scheme processor that I designed as I
wrote Pixie Scheme, Pixie Scheme's III predecessor.
Got all that?)
(Just think of Pixie Scheme III as being powered by the
Little Scheme Engine That Cdr, er, Could.)
That stack is not infinitely deep; it has a size in bytes equal to
approximately one-tenth the size of either of Pixie Scheme III's main
memories. To show how deep it is -- how many Pixie Scheme III tagged
avals have been pushed onto it -- use "e::stack-depth".
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the number of items pushed onto the run-time
stack of Pixie Scheme's III Scheme engine.
For Example:
Type:
Procedure.
Operation:
Find the size of each of Pixie Scheme III's main memories.
Rationale, Explanation, Excuses:
"e::store-size" is a basic memory-inspection function. Do
not confuse it with "e::room": The former shows how many bytes
each main memory has. The latter shows how many bytes of main
memory are actually in use.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the size, in bytes, of each of Pixie Scheme's III main memories.
For Example:
Type:
Procedure.
Operation:
Search through the body of a compiled procedure for symbols that have been made permanent since it
was compiled, and substitute the values of those symbols in the procedure.
Rationale, Explanation, Excuses:
Correct use of this procedure allows the compiler to make compiled code run faster.
Arguments:
One compiled procedure.
Side Effects:
Modifies the body of the argument.
Returned Value:
A compiled procedure: Returns the argument, appropriately modified.
For Example:
Type:
Procedure.
Operation:
Get the Unix time.
Rationale, Explanation, Excuses:
The Unix time is the number of seconds that have elapsed since 0 hours, 0
minutes, 0 seconds, January 1, 1970, in Coordinated Universal Time, without
including leap seconds, at least insofar as you have remembered to set your
system clock.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the Unix time.
For Example:
Type:
List of pointers to Scheme machine primitive functions.
Operation:
When this list is pushed into the continuation, a top-level loop runs.
Rationale, Explanation, Excuses:
This list of pointers to Scheme machine primitive functions
constitutes the never-ending read-eval-print loop that is
the "top loop" of Pixie Scheme III. When this list is pushed
into the continuation, a top-level loop runs, and when that
push is done when Pixie Scheme III either starts or resets, it is
the top-level loop that is running.
How can a finite list of functions run forever? Well, the last
function in the list pushes the entire list into the continuation.
Arguments:
Does not apply.
Side Effects:
Does not apply.
Returned Value:
Does not apply.
For Example:
Type:
Procedure.
Operation:
Invoke the Unix "usleep" function on the
thread of the Pixie Scheme III application that
is running the Pixie Scheme III engine.
Rationale, Explanation, Excuses:
This procedure provides a convenient way
for Pixie Scheme III to stop execution for a while
without wasting system resources in an idle loop.
The argument to "e::usleep" is the intended sleep
time in microseconds, but the time wasted in
setting up the call to Unix "usleep" and in
recovering after waking up means that naps much
shorter than 0.01 second are hard to achieve
reliably.
Pixie Scheme III will do no processing while asleep.
The "Reset Scheme" command will not work.
(Actually, it will work eventually, but not till
Pixie Scheme III wakes up.) Pushing the iPad "Home"
button will still work.
CAUTION!! The iPad operating system is
not fond of long sleep durations. If it detects that
an application is unresponsive -- which includes going
to sleep -- for too long, it will terminate the
application without warning.
Arguments:
One integer, taken as the number of microseconds to sleep.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Return a string telling when the current version of
Pixie Scheme III was built.
Rationale, Explanation, Excuses:
Useful for version identification. This string
is printed as part of the "banner" when Pixie
Scheme III starts.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Print a warning message and then continue.
Rationale, Explanation, Excuses:
Useful primitive for error-handling.
Arguments:
One string.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Write out the contents of the continuation.
Rationale, Explanation, Excuses:
I installed this procedure as a debugging aid.
It writes out (in the sense of the Scheme procedure,
"write") the current continuation.
There usually isn't much in the continuation.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Write out the contents of the Pixie Scheme III
run-time stack.
Rationale, Explanation, Excuses:
I installed this procedure as a debugging aid.
It writes out (in the sense of the Scheme procedure,
"write") the current Pixie Scheme III run-time stack.
The stack usually contains pointers to some
rather large objects, such as the full environment
list, so "e::write-stack" will usually produce
lots of output.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Test whether the "Compile Defines" menu item is set.
Rationale, Explanation, Excuses:
Provided on the general principle that it is desirable
to make internal program state available at the Scheme-language
level.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the "Compile Defines" menu item
is set; that is, if Pixie Scheme III is automatically compiling definitions.
Otherwise, returns #f.
For Example:
Type:
Procedure.
Operation:
Like "define" with only the simple, two-argument syntax, and no automatic compilation.
Rationale, Explanation, Excuses:
The real "define" is a macro; "c::define" is one of the primitives from which
it is built.
Pixie Scheme III reports an error when "c::define" is used to attempt to redefine a
"permanent" symbol.
Arguments:
Two: The first a symbol, the second any Scheme object.
Side Effects:
Causes the second argument to become the value or binding of the first, overwriting any previous
value or binding.
Returned Value:
A symbol: Returns the first argument.
For Example:
Type:
Procedure.
Operation:
Test the Pixie Scheme III mechanism for reporting fatal errors by crashing Pixie Scheme III.
Rationale, Explanation, Excuses:
For further development of Pixie Scheme III, I needed an easy mechanism
to verify that the Pixie Scheme III mechanism for reporting fatal errors
was working correctly.
Arguments:
None.
Side Effects:
PIXIE SCHEME III CRASHES.
Returned Value:
Does not apply.
For Example:
Type:
Procedure.
Operation:
Get the entire current environment.
Rationale, Explanation, Excuses:
Provided for development and testing, described herein on the general
principle that it is desirable to make internal program state available
at the Scheme-language level.
The fundamental logical construct in a Pixie Scheme III environment is a pair whose
car is a value or a binding -- any Scheme object -- and whose cdr is a variable which
has that value or binding. The top-level environment is hashed: It is a vector,
each of whose elements is a list of value/symbol pairs. All other environments
are lists of value/symbol pairs.
Arguments:
None.
Side Effects:
None.
Returned Value:
A list: Returns a list of all the environments visible from the
lexical scope in which
"c::environment" was called, that list being sorted in order
of lexical nesting, so that more closely-nested environments occur earlier in
the list.
For Example:
Type:
Procedure.
Operation:
Return the hash value of the string, as used by Pixie Scheme III in
deciding to which hash bucket of the top-level environment a symbol
identified by the string should belong.
Rationale, Explanation, Excuses:
Provided on the general principle that it is desirable to make internal
program mechanisms available at the Scheme-language level.
The hash algorithm presently used returns an integer
in the range [0 .. 16383]. That range may change in the future.
Arguments:
One string.
Side Effects:
None.
Returned Value:
An integer: Returns the hash value of the string, obtained as described above.
For Example:
Type:
Procedure.
Operation:
Read a Scheme string, and process its contents as if
they had been entered at the keyboard. Pixie Scheme III
prints the results of any such evaluation, but not the
literal text of the string itself.
Rationale, Explanation, Excuses:
Useful for parsing strings that were prepared outside of Pixie Scheme III.
Arguments:
One string.
Side Effects:
Depends on the content of the string.
NOTE that if parentheses or quotation marks are not balanced in the
string, Pixie Scheme III will wait patiently for additional top-level input after it has
completed reading the string.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Construct a Pixie Scheme III string containing a number formatted using a C (or C++)
format string.
Rationale, Explanation, Excuses:
Standard R5 Scheme procedures offer little immediate capability for
formatting numbers in many ways.
Arguments:
Two: The first a real number, the second a string.
Side Effects:
None, but ...
WARNING!! "c::number->string-with-c-format" does no checking whatsoever of
whether its "string" argument is appropriate for use as a C++ "format" string.
Thus there is a noteworthy probability that ill-considered use of this procedure may cause
Pixie Scheme III to crash. This procedure is perhaps best used as a primitive for procedures
which are themselves well tested and debugged.
Returned Value:
A string: Returns a string containing the formatted number. The number is first formatted as
Then the scratch buffer is used to construct a newly-allocated Pixie Scheme III string, so
there is no need to copy anything to use the new string, and no concern about overwriting it.
For Example:
Type:
Procedure.
Operation:
Show a low-level description of every locked object in Scheme main
memory, and of the state of locking of bins of the hash tables used to
control access to Pixie Scheme's III oblist and top-level environment,
and then release every lock found.
Rationale, Explanation, Excuses:
For use in debugging.
Arguments:
None.
Side Effects:
Quite possibly, Pixie Scheme III will crash. With luck, Pixie Scheme III
will end up in a state in which you can investigate what was causing
any mysterious locks that may have been giving you cause for concern.
Returned Value:
#t
For Example:
Type:
Procedure.
Operation:
Find the value or binding of a symbol, if there is one.
Rationale, Explanation, Excuses:
This procedure was useful for the compiler; it is in essence a mini "eval"
that works only for symbols. It obtains the value or binding of the symbol
in the lexical scope where "c::symeval" was called.
Arguments:
One symbol.
Side Effects:
None.
Returned Value:
Any Scheme object: Returns the value or binding or the argument in the
current lexical scope. Reports an error if the argument has no value
or binding in the current lexical scope.
For Example:
This term refers to a style of programming, or a type of
programming language, that emphasizes the application of functions to
arguments, and avoids changes of state and mutable data. An
applicative program is one which reaches a result by applying
successive functions to its data. "Applicative programming" and
"functional programming" are very nearly synonyms.
Scheme is not quite an applicative language, but insofar as only
a few Scheme procedures and special forms change state -- those
whose identifiers end with a "!" -- it is relatively easy to
write applicative programs in Scheme.
An atom is a Scheme object that contains no references (pointers)
to other Scheme objects. Just what kinds of Scheme objects are atoms
is implementation-dependent, but in Pixie Scheme III, atoms
include all objects of the the following kinds:
The term "binding" is Lisp jargon referring to some, but
not all, kinds of assignments of a value to a variable.
The distinction being made is whether the actual data are
stored somewhere where another process or program can get at them,
and change them, without actually having access to the variable
in question. When the data are of that nature, the
variable is said to be bound to the data. The word is
perhaps intended to indicate that the data and the variable
are tied together, so that when the data are changed by
whatever means, the value associated with the variable
necessarily changes as well.
If you are familiar with the concept of a pointer, or a memory
reference, as used in other programming languages, then the essence of
binding is easy to explain: When a variable is bound to data, the
actual value of the variable is a pointer to the data. Unfortunately,
there is more to it than that.
In Lisp systems, the means whereby another process or program can get
at the data are understood to be normal Lisp operations; we are not
considering the possibility of someone going in with a debugger or a
monitor. Thus to speak of a binding in a Lisp system, the memory
reference or pointer involved must point into the main memory of the
Lisp system itself, and the Lisp system must provide a standard
way to follow the pointer and change the data to which it points.
For example, in Pixie Scheme III -- as is typical of Lisp systems --
a pair is a data object in main memory; when you let a variable
stand for a pair, via a command like
then what in most other computer languages would be
called the "value" of "my-pair" is a pointer into main memory, to the
place where the newly-allocated pair is located. (To be very precise,
in Pixie Scheme III the value of "my-pair" is a
tagged aval -- which see -- whose tag bits identify the
value as a pointer to a pair, and whose 64-bit field is the actual
pointer in question.)
Scheme provides built-in primitives to alter a pair; they
are "set-car!" and "set-cdr!". Thus, here is an example in
which some "other program" alters data associated with a variable
by binding:
Just which kinds of objects are associated with variables by
bindings and which are not will vary from Lisp system to
Lisp system. In Pixie Scheme III, objects which require bindings
include pairs (and therefore all non-empty lists), strings,
and vectors; objects which do not require bindings include
booleans, characters, the empty list, numbers, ports,
symbols and procedures.
That list is a little fuzzy, because Pixie Scheme III has some
non-standard procedures, like "e::set-tag!", which allow you to cheat,
and modify the structure of things even when there are no standard
Scheme procedures to do so. (For example, you can use "e::set-tag!" to "change"
lots of objects into pairs, then go in with "set-car!" and "set-cdr!"
to do what you will. Just be careful not to crash the system,
and note that not everything can be "changed" to a pair without
immediate ill effect.)
Note that there may well also be cases when the actual value of a
variable is a pointer to something, in which most Lisp users would not
speak of a binding, because there are no procedures to follow the
pointer and alter the data.
Much written material about Lisps blurs the distinction between binding
and simple assignment of values to variables. I tend to use
the word "binding" to refer to both, if only to keep reminding
you -- and myself -- that there is something complicated going
on.
Jargon for operations whose intent is to affect specific
bits of a datum, often in parallel. For example, a bitwise and of two
64-bit words returns a word whose least-significant bit is 1 if and
only if the least significant bits of both operands are 1, whose
next-to-least-significant bit is 1 if and only if the next-to-least
significant bits of both operands are 1, and so on.
Pixie Scheme III provides several bit-wise operations which act on numbers
stored as 64-bit fixnums.
Computer jargon for something that makes a program or a computer
work incorrectly.
The first such "bug" was an actual insect that had gotten into
the mechanical workings of a relay, back in the very old days
when computers used large-scale electromechanical parts rather
than transistors. When the problem was identified and fixed,
the computer in question was reported to be "debugged".
Semi-official name given to a simple animal-like icon used in one of
the "symbol" fonts provided with very early Macintoshes. No one
seemed to be quite sure whether the creature depicted was dog or a cow,
and after a while, a consensus emerged that Clarus was really -- or
perhaps un-really -- a hybrid species.
Clarus was reported to have several vocalizations: The most common
was "Moof!&trade" (and I have never been quite sure how to pronounce
the "&trade"), but when very agitated, Clarus would give voice to an
enthusiastic "Boo-woo! Boo-woo!"
Clarus was a source of much entertainment and good fellowship to
Macintosh programmers in the early days, and I didn't want him --
or is it her? -- to be forgotten.
The resemblance of the name "Clarus" to the name of a software company
once spun off by Apple is, of course, mere coincidence.
Yes, both "DogCow" and "Moof" are trademarks of Apple Computer Corporation.
A widely-known and well-standardized Lisp dialect, that has
been implemented on many platforms. See Guy L. Steele Jr.'s Common
Lisp (Digital Press, 1984).
Common Lisp has a very thick manual. Scheme has a rather thin one.
A compiler is a computer program that translates
instructions for the computer that are written in a form that is easy
for humans to read and use -- called "source code" -- into instructions
in a form that are easy for the computer to read and use.
Many compilers translate source code into "machine language", or
"binary" -- the native language, so to speak, of the computer on which
the compiled source code will be used. The compiler used by Pixie
Scheme III does not undertake such a complete transformation of the source code.
what it does is perform as much as possible of the time-consuming work
of looking up the values or bindings of variables, at the time of
compilation, and store the result in the compiled code. For symbols
whose values or bindings that have been declared "permanent", the
compiler considers it safe to store the actual value or binding in the
compiled code; for others, it stores shorthand information about where
in the environment to look for whatever binding actually obtains at
run-time.
The compiler also expands any macros that it finds in the source code.
If you make a "permanent" symbol un-permanent, and then change its
value or binding, you must recompile any procedures that use that
symbol in order for the compiled code to reflect the new value or
binding.
Lisp jargon for "allocating memory". The term seems to have
originated via guilt-by-association from the Lisp (and Scheme)
primitive operation "cons", which does indeed allocate memory. For a
program to cons excessively is generally considered bad, but is
sometimes unavoidable.
The term "continuation" has two meanings in Lisp jargon.
Continuation -- First Meaning:
To begin with "continuation" may refer, somewhat vaguely, to the
entire future of the world, or at least that part of it that affects
the result or side effects of a calculation in progress. In this
sense, the Scheme function "call-with-current-continuation" provides
time travel, at least metaphorically, in that it is supposed to
package up the current state of Scheme for future use, with the intent
that any Scheme procedure or program using the package will achieve
the same result as if it had run at the moment that
"call-with-current-continuation" was itself called.
It can't really do that, for several reasons:
Therefore, Scheme implementations are perhaps more likely to package
up a pointer to any large, identifiable portion of Scheme
memory that is part of the continuation. That means that if anything
happens to change the memory pointed to between the time
"call-with-current-continuation" is called, and the time the packaged
continuation is used, the use will "see" the modified memory.
What Pixie Scheme III packages up as a continuation, for
"call-with-current-continuation", is in essence a complete copy of the Pixie
Scheme III call stack (with a few other things besides). This copy is not a "deep" copy, in that many
things on the call stack are pointers, and the copy merely duplicates
the pointers rather than copying the things they point to. Among the
objects pointed to are various continuations in the second sense of
the term, described immediately below, and various environments.
Thus if anything alters either those continuations or those
environments before the packaged "continuation" is used, the use
will reflect those alterations.
Continuation -- Second Meaning:
The second meaning of "continuation" is more specific: It then refers
to a list of the instructions of the currently-active Scheme procedure
that are yet to be accomplished before the procedure returns. That
list is often very short, even for a long or complicated procedure,
for the procedure may gain its length and complexity by calling other
procedures of by calling itself recursively.
In many register-level models of processors designed to implement
Lisp-like languages, there is a specific register -- often called the
"C register" -- which contains a pointer to the "continuation" in the
present sense. The C register is analogous to the program counter
of a more conventional processor, though at a rather different level
of logical abstraction: A conventional program counter is an index
into a sequence of machine-language instructions, whereas a "C
register" points to a list of individual Lisp or Scheme expressions
that may well be readable, parseable source code -- some portion of
the body of a function or lambda expression.
Pixie Scheme III is based on a register-level model of a Lisp processor
called an "SECD machine", and does use a "C register" of this kind.
For further discussion of SECD machines, see, for example,
Peter Henderson's Functional Programming Application and
Implementation (Prentice-Hall, 1980).
Computer jargon for "fixing computers or programs that do the wrong thing".
The first such "bug" was an actual insect that had gotten into
the mechanical workings of a relay, back in the very old days
when computers used large-scale electromechanical parts rather
than transistors. When the problem was identified and fixed,
the computer in question was reported to be "debugged".
The term "environment" has several meanings in the context of Lisp and
Scheme.
Environment -- First Meaning:
Informally, "environment" refers to the context in which an expression
is evaluated, most notably to the values or bindings of symbols used
in the evaluation.
Environment -- Second Meaning: Rather more formally,
there is not one environment but a hierarchy of them, in order of lexical scope, from the one most closely
enclosing the program location where the "environment" is referenced,
out through successively less-enclosing environments, to the top-level
environment, which might also be called the global environment or the
interaction environment, which contains all all
non-Scheme-report-environment and non-null-environment bindings
"visible" in the top-level loop of Pixie Scheme III, then to the Scheme
report environment, which contains all non-null-environment bindings
required by the R5 report or listed therein as optional and provided
by Pixie Scheme III, then to the null environment, which is supposed to
contain only bindings for the syntactic keywords of Scheme but which
contains a few more in the case of Pixie Scheme III.
The hierarchy of environments might make more sense if you consider it
in the opposite direction. The null environment contains the syntactic
keywords of Scheme, plus a few extras for Pixie Scheme III macros that implement
some of the syntactic keywords. The Scheme report environment adds everything
else from the R5 report that Pixie Scheme III implements. The interaction
environment adds Pixie Scheme III's enhancements to R5 Scheme, plus whatever
other bindings the user has chosen to put there. The environments of
executing lambda expressions add local variables accessible from within
those expressions.
When a Scheme
implementation looks up
the value or binding of a symbol, it starts looking in the most closely
enclosing environment, then works outward through successive environments
until it finds a value or binding; it is probably an error if there is none
to be found.
The second meaning of "environment" is the entire hierarchy just described.
Environment -- Third Meaning:
The third meaning of "environment" is any of the individual environments in
the hierarchy just described.
By way of illustration, here is an example in which there are three environments
(in the third sense) in the hierarchy. We are going to print out (list a b c)
in three different environments, in which the values or bindings of those variables
are not all the same. Each time we print the list, Pixie Scheme III will use the
binding of each variable that exists in the closest lexical scope to the place
where the print occurs.
The term "environment list" refers to the hierarchy of environments
described as the second meaning of "environment" in the discussion
above. Pixie Scheme III represents that hierarchy as a list, though
there is no formal requirement to use such a representation.
Evaluation is the act of performing all necessary Scheme computations
to determine what value a Scheme expression represents; loosely, it is
the act of running a program, or a portion thereof.
All Scheme systems evaluate. Yet there has been a substantial issue
in the evolution of the Scheme programming language, about how and
whether a Scheme system should evaluate an expression created by the
user while a program is running, as opposed to one that was written
down in source code beforehand.
Since Scheme programs have the same syntactic form as any other
kind of data, it is quite easy to for a program build up a chunk
of code as it runs, and then to evaluate that code. For example:
The question is, when -- if ever -- is Scheme allowed to turn
"my-expression" into "4".
If all expressions to be evaluated were as simple as "my-expression",
there probably wouldn't have been much debate. But there is a possibility
of great confusion when the expression contains references to variables
that have different values or bindings in different environments.
Suppose we had built up "my-expression" to be a simple list, perhaps
If "my-expression" is going to be evaluated, Scheme must look up the
values of the variables "a", "b", and "c", but those variables may
have different values or bindings in different environments.
Which environment, or environments, should Scheme use when it looks
up the values or bindings of those symbols?
Here is an example, based on the example given under the discussion
of "Environment", that might illustrate the problem. In it, we
define variables "a", "b", and "c", with different values in
different environments, and construct some lists using those
variable names.
So far, so good, but what we have done is deceptive.
The three lists, "top-level-list", "let-list", and
"lambda-list", are all just lists of symbols:
There is nothing in the lists per se to show that
"a", "b" or "c" have particular values or bindings. There isn't
even anything to show that "list" names a procedure -- though
we know it does. The example is constructed to give the
impression that "lambda-list" somehow captures the values
of "a", "b" and "c" that obtained within the lambda expression,
but that's not so: The symbols in the three lists do not have
specific values associated with them.
Therefore, if we were somehow to "evaluate" the three lists,
the evaluation would "get" whatever values of "a", "b", and
"c" obtained in the environment in which the evaluation took
place, and those values wouldn't necessarily be the values
that obtained in the place where the lists were constructed.
If you think that's confusing, it would not be hard to construct
an example that built up (list a b c) by splicing in the "a",
"b", and "c" in different environments. The list would be passed
around from environment to environment, with different things
being added in different places. Yet it would still end up just
a list of symbols, with no special values associated with them.
The R5 version of the Scheme standard has defined a somewhat
complicated "eval", which allows some choice over which
environment is used. Pixie Scheme III provides an implementation
of that "eval".
Pixie Scheme III also provides is the
procedure "e::cons-with-continuation", which evaluates its
argument in the environment where "e::cons-with-continuation"
is called. Many Lisps have an "eval" function which does
exactly that. Let's use "e::cons-with-continuation" like
eval, and try it out on our lists:
So indeed, each of the three lists evaluates using the bindings
to "a", "b" and "c" that obtained in the top level.
This term refers to a style of programming, or a type of programming
language, that envisions computation as a series of applications of
mathematical functions to data, and avoids dealing directly with
changes of state and mutable data. An applicative program is one
which reaches a result by applying successive functions to its data.
"Applicative programming" and "functional programming" are very nearly
synonyms.
Scheme is not quite a functional language, but insofar as only
a few Scheme procedures and special forms change state -- those
whose identifiers end with a "!" -- it is relatively easy to
do functional programming in Scheme.
Things in the main memory of a Lisp system, which are
provably not usable in future operations of that system, are
called "garbage", in the sense of waste material that takes
up space. The storage space containing them may in principle
be reclaimed for other uses.
The proof that an item is not usable in future operations of a Lisp
system might, for example, be a demonstration that no sequence of
pointer dereferences starting from pointers "officially"
known to the Lisp system, can reach the item. The canonical
way to do that is to start with the pointers officially known
and mark everything reachable from them. Any part of main
memory that is left over, is garbage.
The process of identifying garbage and reclaiming its space for
subsequent reuse is called "garbage collection".
Pixie Scheme III has two different garbage collectors, which can
interact. The first is of the kind that stops all Scheme processing
and reclaims all the garbage in all of memory, all at once. That
garbage collector is called the "full garbage collector". It can do
the whole job of garbage collection all by itself, but if you are
using a large Pixie Scheme III main memory, the time required to garbage
collect may be long enough to be a bother. Lisp users say that you
should never use a Lisp system to control a toaster, because the toast
may burn while the system has stopped to collect garbage.
The second garbage collector is what is called a generational garbage
collector. Its operation is based on the principle -- well-known in
the Lisp community -- that most objects that a Lisp system creates are
for temporary use: They become garbage very soon. Therefore, if you
have some way to keep track of just those objects that have been
created recently, you can reclaim a lot of garbage very quickly -- and
not burn the toast -- by looking at
only the recently-created objects.
There usually aren't very many of them, so that task can be accomplished quickly.
On the average, when Pixie
Scheme III is using the generational garbage collector, it spends a higher
proportion of its time collecting garbage than when it is not, but its
response time is quicker, so the toast does not burn.
What Pixie Scheme III does when the generational garbage collector is
running is use two small "generation spaces" in addition to the main
memory. One is called the "active generation" and one is the "aging
generation".
The way it works is that the two small generation spaces change roles
regularly. The active generation is where new objects are being
created. When it is full, it becomes the aging generation, and the
old aging generation -- which hold objects that were created a little
while ago -- is checked for garbage by the generational garbage
collector. Anything in the aging generation that is not garbage is
copied into main memory. Then the old aging generation -- now
empty -- becomes the new active generation, and the old active
generation is put aside, as the new aging generation, to "age". After
a while, perhaps main memory fills up, and then Pixie Scheme III runs the
full garbage collector, to see if any of the stuff in main memory has
become garbage since it was put there.
I didn't understand that the first time I heard about it, either, so
let's try an analogy. Suppose your office has two desks and a file
cabinet. You change which desk you are working on once a week, and
most of what you are doing is with new stuff on your current desktop,
though you can go to the other desk or to the file cabinet when you
need to. At the end of this week, you abandon your current desktop,
go to last week's desktop, and clean it. You find that most of the
stuff there that was so important last week is now unimportant, and
throw it away. Anything that remains goes into the file cabinet. You
now have a clean desktop to work on for the next week, while the
desktop you just left is sitting and waiting for stuff on it to become
unimportant. Once in a great while you have to clean out the file
cabinet, and that is a big, time-consuming job.
The operation of the full garbage collector is fairly straightforward.
Pixie Scheme III uses two main memory spaces -- one at a time -- and
performs garbage collection by
The operation of the generational garbage collector is much messier.
In addition to the "officially known" pointers mentioned above in
the discussion of the full garbage collector, Pixie Scheme III maintains
a list of pointers that are in main memory and point to either the
active generation or to the aging generation. Garbage collection
is performed by
These discussions of how the garbage collectors operate
are necessarily abbreviated and simplified. There are a lot of messy
details which I have not mentioned, some of which I would rather not
think about except when I absolutely have to. Both garbage collectors
involve what programmers wryly call "interesting" algorithms.
The term "gensym" is Unix slang for "generate symbol".
Pixie Scheme III, like many other languages, has a procedure --
"e::gensym" -- for creating new symbols that are guaranteed not to
have any value or binding at the time of creation.
The essence of any "gensym" procedure is likely the ability
to generate new symbols randomly, coupled with the ability
to test each symbol so created, to make sure that the random
process has not inadvertently created a symbol that is
already in use.
In Scheme, a global variable is one defined in the top-level
environment. Such a variable may be
read or changed anywhere else in Scheme, except where it is
shadowed by another variable of the same name.
An "inf" is a special value of a flonum used to indicate
that a calculation has produced a number too large to
represent. The intended value of the calculation might
be a mathematical infinity, or it might not.
One of my personal rules for software engineering is "Never
create a data structure without creating a procedure that can
describe it in human-readable form". For that reason, Pixie
Scheme III is full of procedures that describe its internal structure
at a more intimate level than required by the Scheme standard.
The procedure "e::inspect" is probably the most widely useful
of these -- it will tell something useful about any Scheme object.
There are other procedures for Scheme objects that do not have
values, and so cannot be used as arguments to "e::inspect".
Scan this document for words like "inspect", "describe", and
"show", to find them.
Scheme allows definitions -- using define --
not only at top level, but also at particular positions within
procedures and special forms: Any number of "define" statements
may occur at the beginning of the body of a
begin,
lambda,
let,
let*,
letrec,
let-syntax,
letrec-syntax,
or a
define.
Quantities so defined have lexical scope local to the expression where the
definition occurs, except that quantities defined at the beginning
of a begin have the same lexical scope as
the begin itself.
Computer programs often let a variable for represent different
things in different places. The variable "x" may stand for "3" in
one part of the code, and for "(list a b c)" in another.
The scope of a value or binding of a variable is the range of the
program within which it is visible; that is, it is the range
within which a reference to the variable name will obtain
that value or binding instead of some other one.
To say that a scope is "lexical" is to say that you can tell
what the scope is by looking at the program source code without
worrying about control flow: Even if you don't know about
calls, jumps, if/else branches, and "call-with-current-continuation",
you can tell what is going on just by reading the code.
In Scheme, certain expressions define a source-code domain within
which a variable value or binding may be created and used without
being visible, or perhaps the word should be "accessible", outside the
domain. Such bindings may be said to be local to the domain. These
expressions include "let", "let*", "letrec", and "lambda". The first
three have particular syntax for creating values and bindings for new
symbols. Lambda allows new values and bindings only to the symbols
which are its formal parameters. New symbols may also be created and
defined at top-level -- outside any local domain of the kind just
mentioned -- using "define".
With each such domain is associated an environment -- in the third sense
of the term as defined in this glossary -- which contains all the symbols
that exist solely in that domain, together with their values or bindings.
The point of lexical scoping is that domains may be nested. In particular,
any "let", "let*", "letrec" or "lambda" is necessarily nested in some
other domain, if only the top-level one. The same symbol may have
different values or bindings in any number of nested domains. When Scheme looks
up the value or binding of a variable, it obtains the one in the most closely
enclosing nested domain in which the variable has a value or binding. That's how
lexical scoping works.
To expedite variable lookup, the environments of the various domains
are represented in a way that makes it easy to go through them in
order from most closely-enclosing to least closely-enclosing. That
representation is typically a list.
For example, consider the following, just as source code -- perhaps
as text to be cut-and-pasted into Pixie Scheme III at top level.
A local variable is one whose existence and use is confined to
a particular place or time. In the context of Scheme's
lexical scope, a local variable
is one defined in a particular lexical scope; it can only be
seen or used within that lexical scope.
Scheme has many ways to declare local variables: The arguments
of a procedure created with define are
local variables within the body of that define, and the arguments
to a lambda expression are local variables
within its body. The variable names used in the
bindings of a let,
let* or letrec are
local variables within the bodies of those forms.
Furthermore, when internal definitions
are used correctly, they create additional local variables within the
bodies of the expressions in which they occur.
MacLisp was one of the first widely used Lisps, and in this case, the
initial syllable "Mac" does not indicate a product designed for
use on the Apple Macintosh: MacLisp originated in the late 1960s and
early 1970s in MIT's "Project MAC". Unfortunately, no one seems to
remember for sure what the "MAC" in "Project MAC" did stand for.
MacLisp originally ran on various computers produced by Digital
Equipment Corporation. It was the first Lisp that I myself
encountered, at a time in the early 1980s when I was working for a
company that had bought a DEC-20 and didn't know what to do with it:
In essence, I had a mainframe computer for personal use, via a
terminal on my desktop. I only knew one computer language at the time
-- 1966 Fortran -- and I decided to learn another one, that was as
different from Fortran as I could readily find. The '20 had a MacLisp
installation, so I decided to learn Lisp, and it warped my mind
forever.
MacLisp was an excellent Lisp, and there were plenty of books about
Lisp programming that were source-code compatible with it. The DEC 20
was a fine machine for its day, though I suspect that here in the
early twenty-first century there are toasters in production that have
more processor power. They probably don't run MacLisp, though --
you might burn the toast while you were garbage-collecting.
(Remember, if you don't have a 36-bit word, you're not playing with
a full DEC!) (Remember, that December 20 is DEC-20 day, when we
all celebrate the greatness and glory of the DEC-20 computer!)
(Yes, the '20 did have a 36-bit word: That was so you could pack
two 18-bit addresses into one word of memory -- just think, a
whole 256K of address space! Or, you could cram in five 7-bit
characters -- this was before ASCII -- with a bit left over
for parity. There was a 36-bit floating-point number format,
too.)
But I digress ...
Loosely, macros provide a systematic way to alter program
source code under program control.
The R5 Scheme report defines a macro facility for R5 Scheme.
That is only part of what is discussed here. Pixie Scheme III also
has a built-in macro low-level macro capability that works
as follows:
A Pixie Scheme III macro is a special kind of object that has
a lambda expression of one parameter associated with it.
When a macro occurs as the car of a Pixie Scheme III list,
the Pixie Scheme III evaluator calls the lambda expression
associated with the macro, passing it the entire list
as parameter, and evaluates whatever the lambda expression
returns. Typically, the macro's lambda expression will
transform or alter the list in some way.
For further details, see the entry for "e::macro" in the Command
Summary portion of this document.
One of several particular identifiers whose use
usually indicates that it doesn't really matter
what identifier is used or what value or binding it has.
Or, perhaps, a default default identifier when there
are no defaults to default to.
Metasyntactic variables in use in the Lisp community
have included "foo", "bar", "baz", "frob", "mumble", "quux",
and "grundoon".
For example:
"You can use 'call-with-current-continuation' with
any function foo ..."
If you think this makes complete sense, or if you
think that it makes no sense whatsoever, you are missing
the point.
A "nan" is a special value of a flonum used to indicate
that a calculation cannot produce a numerical result.
Floating-point operations that are given nans as input
generally produce nans as output. Thus a nan produced
deep within a calculation will propagate through to the
final result, where perhaps someone will notice it.
The central idea of numerical accuracy is that we are trying to
use one number to model another. There is some number we would
like to know -- perhaps something that can be calculated, like pi,
or perhaps a physical quantity that needs to be measured, like
the distance to the Moon, in miles. Unfortunately, the number we've
got is not necessarily the number we want: The issue is, how
close is it? When we speak of "numerical accuracy", we are
talking about that closeness.
Note that it is meaningless to talk about the accuracy of a number:
Accuracy has to do with two numbers, not just one. For example,
consider the number 3. If we were trying to calculate the value
of the integer that lies between 2 and 4, then "3" is very accurate
-- it's dead on. On the other hand, if we were trying to calculate
pi, we have missed it by several percent.
Numerical accuracy and numerical precision are often confused, and
one of the sources of confusion is a common convention for implicitly
characterizing accuracy by means of precision. Many of us were at
one time or another taught, for example, that the number "3.5"
stands for, or should stand for, or ought to stand for, any number from
3.45 through 3.55; that is, for any number that rounds to 3.5 when
the usual rounding rules are applied.
That convention uses precision -- the number of digits used to represent a
number -- to make a statement about accuracy. Sometimes that convention
is useful, and sometimes not, but in any case, precision and accuracy
are different concepts.
The Scheme programming language deals intrinsically with accuracy in
only one way; namely, by means of the concept of "exactness", which
has to do with whether Scheme's internal representation of a number is
or is not precisely what the user provided as data or what a mathematical
operation was trying to calculate. Thus if I type in "123", Pixie Scheme III can
indeed store the integer 123 with no problem, and will annotate it
as an exact number, whereas if I type "4/3", Pixie Scheme III will store an
inexact number whose value is close to 1.333333 ... . Similarly, the
mathematical primitives that Pixie Scheme III uses are capable of noticing
whether certain algorithms return approximate or exact results. Thus
Pixie Scheme III will store the result of (sqrt 4) as an exact 2, but will
store the result of (acos 0) as an inexact number close to pi/2.
There are several related ways to look at numerical
precision. We might consider it in essence a typographical
property of the representations of numbers. Thus we say that
"3.00000000000" is more precise than "3.00" because the former
contains more digits than the latter.
By close analogy, though getting a bit away from typography, we
say that a 64-bit floating-point number is more precise than
a 32-bit floating-point number because the former uses more bits
to store its value than does the latter.
These notions are closely related to the mathematical discipline
of information theory, and to the physical notion of entropy.
To provide information is to indicate which of many alternatives
is in fact in effect, and the greater the number of alternatives,
the more information is being provided when we actually pick one.
Thus we say that a 32-bit quantity contains more information
than a 16-bit one simply because there are 4294967296 different
32-bit quantities but only 65536 different 16-bit quantities.
That is, to specify a 32-bit quantity is to pick one in four billion,
whereas to specify a 16-bit quantity is merely to pick one in
sixty-six thousand.
Precision is different from accuracy: Thus, "3.000000000"
could be either a perfectly accurate representation of the integer
"three", or a representation of "pi" that is inaccurate by several
percent.
Numerical accuracy and numerical precision are often confused, and
one of the sources of confusion is a common convention for implicitly
characterizing accuracy by means of precision. Many of us were at
one time or another taught, for example, that the number "3.5"
stands for, or should stand for, or ought to stand for, any number from
3.45 through 3.55; that is, for any number that rounds to 3.5 when
the usual rounding rules are applied.
That convention uses precision -- the number of digits used to represent a
number -- to make a statement about accuracy. Sometimes that convention
is useful, and sometimes not, but in any case, precision and accuracy
are different concepts.
Scheme's "number->string" procedure attempts to print out an external
representation with enough precision accurately to represent the
internal value of the number that was provided as its argument.
An ob-list is a list of all the symbols in use in a Lisp
system. Pixie Scheme III uses one in such a way that there is always
only one copy of each symbol in use: That is, if there is need in many
different places to use "the same" symbol, each of those places will
get a pointer to the single copy of the symbol in use, rather than a
new duplicate of it. That way, symbols can be compared by pointer
equality, rather than by comparing the strings that name them -- and
pointer equality is faster.
Technical Note: Actually, there is a little more to it.
Internally, Pixie Scheme III defines a symbol as a pointer to a
small Scheme data structure that contains the symbol's name -- which
is a string -- and a few other items of data about it, and makes sure
that there is only one such data structure -- in the ob-list -- for
any given name. Symbols are compared for equality by comparing these
pointers. A symbol's names is printed by following the pointer to get
to the appropriate string.
Pixie Scheme III allows the symbols to be declared "permanent", which
means that Pixie Scheme III will report an error if you try to change the
value or binding of such a symbol. (If you really want to change one,
there is a way to make a symbol un-permanent again.) Making a symbol
permanent reduces the probability of changing what it stands for by
mistake, and also allows the Pixie Scheme III compiler to use the actual
value or binding for the symbol, instead of just the symbol itself,
in compiled code.
Pixie was the cat for whom Pixie Scheme, Pixie Scheme II,
and Pixie Scheme III, are named. He was one of Wraith's kittens. He was a
classic Hallowe'en cat -- coal-black, with brilliant yellow eyes. He
also seemed a little bit fey, rather more so than most cats.
Pixie Scheme was an "R3" Scheme for mid- to late-1980s versions of
the Apple Macintosh, that I created and developed from 1987 through
1991. It was available as shareware at that time -- for that matter,
it still is. Pixie Scheme is the direct ancestor of Pixie Scheme III;
indeed, much of Pixie Scheme's source code was incorporated in
the first release of Pixie Scheme III without change.
Pixie Scheme II is a Scheme implementation for the Apple
Macintosh that is based on
Wraith Scheme,
but has fewer features and a
notably different user interface. Pixie Scheme II was in great part a
design prototype for Pixie Scheme III.
Pixie Scheme II is available from the software page of my web site,
http://web.mac.com/Jay_Reynolds_Freeman/My/Software.html.
Pixie Scheme II is open-source under the GNU General Public License.
Copies of the source distribution are available from that same
web site: One source distribution includes the source for both
Wraith Scheme and Pixie Scheme II.
The computer operation of giving a procedure a collection of arguments and
letting it do what it will with them. The idea generalizes slightly to
things that are not procedures: When Scheme sees a list that is to be evaluated,
something like
"Referential Transparency" is the idea that you can "refer" to something as many
times as you like and always have the same result. The result is "transparent" to
how many times the reference has occurred. A "reference" might be a procedure call,
a variable-value lookup, or something else.
Here is a Scheme procedure which is referentially transparent:
Thus for example, you may call it with "3" as an argument as many
times as you like, and you will get back "4" each and every time.
Here is a Scheme procedure which is not referentially transparent:
Consecutive calls to "next-number" will return 1, 2, 3 ...
Here is another Scheme procedure which is not referentially transparent:
This standard Scheme procedure returns the next character from some
port -- typically the keyboard. There is no guarantee that it will
always return the same value.
To "reset" Pixie Scheme III is to make it stop whatever processing it
is doing and restart the top-level loop.
The "R5 Report" is the Revised5 report on the Algorithmic Language
Scheme
People working in computer science sometimes find it useful to create
a mental model of a computer that does not actually exist, as an aid
to understanding a particular kind of computer language or programming
style. One such model is the "SECD machine". I first
encountered it in Peter Henderson's Functional Programming
Application and Implementation (Prentice-Hall, 1980).
An SECD machine is envisioned as a special kind of processor, designed
for working with lexically scoped Lisp-class programming languages. It can address
memory and perform operations in the usual way, and has four
special-purpose registers that contain pointers to four special lists.
The four registers are called "S", "E", "C", and "D". Those letters
stand respectively for "Stack", "Environment", "Continuation", and
"Dump".
This use of a stack is somewhat simpler than the most common stack use
in conventional processors. Conventional processors generally use a
stack not only for calculations, but also for maintaining information
about functions that have been called but have not yet returned.
The kind of stack used by an SECD machine resembles the kind explicitly
modeled in the programming language "Forth".
An SECD machine processes a procedure call by making a
list of the current content of the S, E, and C registers, pushing that
list onto the Dump, clearing the Stack, and loading the E and C
registers respectively with the environment and code for the
newly-called procedure. An SECD machine processes a return from a
procedure by popping the car of the Dump -- that car will be a
three-element list -- and reloading the S, E, and C registers from its
elements.
Pixie Scheme III's predecessor, Pixie Scheme,
started out as an SECD machine -- not a non-existent one, but not
quite a real one, either; it was a virtual SECD machine, implemented
as a program in the programming language C, pretty much as outlined by
Henderson. It soon changed somewhat: I re-implemented the Stack as a
more traditional kind of stack in separately-allocated memory, and
arranged to save what would otherwise have gone into the Dump, on the
Stack. Thus Pixie Scheme had no S or D
registers. I also added several additional registers to the model,
for purposes other than process control and memory management. Pixie
Scheme III uses the same kind of virtual machine model and implementation
that Pixie Scheme did.
In Scheme, one variable is said to shadow another when both have
the same name and the first occurs in a more closely enclosing
scope than the second. Thus if a procedure contains a variable
named "foo", and there is also a variable named "foo" at top level, then
any reference to "foo" within the body of the procedure necessarily
refers to the binding of the variable
that is associated with the procedure, rather than to the one
at top level. Speaking loosely, within the procedure, Scheme can
only see the more local binding, and the less local binding is, so to
speak, in the shadow of the more local one.
The term "Special Form" is Lisp jargon for any kind of Lisp
expression, that is bounded by parentheses, that is not a
procedure call. The distinction is useful because every argument
to a procedure call is evaluated before being passed to the
procedure itself, whereas what happens to the arguments to special
forms depends on the form. For example, the special form "set!"
evaluates its second argument but not its first.
Macros are typically special forms, though to be technical, it is
possible -- though not necessarily useful -- to define a macro that
evaluates all its arguments, just like a procedure.
Every Pixie Scheme III object has associated with it an
instance of a data type peculiar to Pixie Scheme III, that I call a
"tagged aval". Such an instance is composed of a 64-bit tag field
that further identifies the type of the object and provides a place to
store information about how it fits into Pixie Scheme III main memory,
and a 64-bit field that is either the actual data the object
represents, or a pointer to that data. The term "aval" refers to the
latter field; I intend it to be analogous to "rval" or "lval" (which
are programmer jargon in themselves), but to mean "ambiguous value",
for the 64-bit field may either be literal data -- an "rval", or a
place to put data -- an "lval".
By and large, when the 64-bit field is literal data, the tagged aval
represents the value of a Pixie Scheme III object, and when the
64-bit field is a pointer, the tagged aval represents the
binding of a Pixie Scheme III object.
A tagged-object Lisp -- or indeed, a tagged-object implementation
any kind of programming language -- associates some kind of "tag" with
every object, to tell what kind of thing the object is. Such a
tagging system is a rather specialized class mechanism, in which
the number of classes is restricted to the number of available
tags, and in which the the means of defining and using new classes
and new methods are not necessarily made visible to the user of
the language.
Since Lisp-class languages are often very polymorphic, a tagged-object
Lisp constitutes an interesting canard, in which strong typing at a
very low level is used to implement a system that is essentially
type-free at a higher level.
Pixie Scheme III is a tagged-object Lisp. See "tagged aval", above.
There are other ways to identify objects; for example, one might
have a number of disjoint memory regions in which to put objects,
one for each kind of object. Memory-address arithmetic would allow
determining which region an object was in, and therefore, what
kind of object it was.
In most computer systems, calling a procedure necessarily
requires allocating some memory for it to use. Possible memory uses
might include storage space for the procedure's local variables,
"scratchpad" space for calculations, storage space for a pointer to
the environment to use, and so on.
Such a memory allocation is only temporary. The memory used can be
reclaimed, and used for something else, after the procedure returns.
Yet if a computer program involves a deeply-nested series of procedure
calls, the total amount of space temporarily allocated for those calls
may become quite large, perhaps so large that the system will run out
of allocatable memory. In that case, the program will fail.
For example, here is a simple function to find the length
of a list:
This function works recursively. It keeps calling itself with successively
shorter portions of the given list, until it finally reaches the end
of the list. Then all those calls return, computing the answer in the
process.
If this function were used to calculate the length of a list
that contained, say, a hundred million items, it would use a
whole lot of memory.
Fortunately, it is sometimes possible to free up a procedure call's
temporary memory before the procedure returns. The general idea
is to free the temporary memory as soon as the procedure is finished
with it. That will be so, in particular, when the last thing a
procedure does before returning is to call another procedure.
For example, consider procedure "foo":
This procedure does some things that we don't care about, indicated by
the ellipsis, then calls another procedure, "bar". At the time of the
call to "bar", "foo" has nothing else to do: It is going to return
whatever "bar" returns, without any further computation. Thus any
temporary memory allocated for the use of "foo" could be reclaimed
before the call to "bar", provided we patched our call stack, or
whatever, so that "bar" returned to wherever "foo" was going to
return.
It doesn't even matter if "bar" never returns at all. The little bit
of space that "foo" was using can get cleaned up before "bar" even
begins to run. All we do is start off "bar" set up so that when and
if it ever returns, it goes back to whatever location is expecting the
return from "foo".
That example shows how to save a little space, but not much. On the
other hand, suppose that "foo" had been a recursive procedure, written
like this:
Procedure "foo" is said to be "tail recursive", because the last
thing it does -- the code in the tail of its continuation -- is
to call itself.
The same logic about reclaiming memory applies: We reclaim the
temporary memory used for one call of "foo", and allocate some more
memory for another such call, with an argument smaller by 1.
We are in effect reusing the temporary memory for foo, and if the
computer system is so designed, it may in fact actually reuse that
memory, rather than freeing one chunk and then allocating another
identical chunk.
Now suppose we call the recursive version of "foo" with some
starting argument. Do you see what happens? If we do not
reuse the temporary memory, the system will keep allocating new,
separate blocks of temporary memory, one for each call to "foo".
And since "foo", as written, never returns, the system will
eventually run out of memory.
On the other hand, if the system is reclaiming temporary memory
in the manner described, it will reuse just one block of temporary
memory forever. It doesn't matter that "foo" never returns.
The procedure "lnth", a few paragraphs back, is not
tail-recursive. After a recursive call, there is some addition to be
done before returning a value. But it is not hard to write a
tail-recursive procedure to find the length of a list. It uses
an auxiliary procedure, like this:
When the procedure "lnth-aux" recurses, it does so in a tail-recursive
manner -- there is nothing to do after "lnth-aux" returns. Thus the system
can reclaim the temporary memory for "lnth-aux" before the recursive call
is made. Procedure "lnth" is just used to get things going -- it calls
"lnth-aux" with starting values. Thus with these definitions, we can find
the length of a list of 100 million items without running out of memory.
Note that although the business of freeing up temporary memory when there
is no further use for it is traditionally associated with tail recursion,
the idea is more widely applicable -- as shown by the example in which
"foo" calls "bar".
Pixie Scheme III checks for the possibility of reclaiming temporary space
at run-time: When one procedure is about to call another, if the
continuation of the current procedure contains nothing other than the
call, then the temporary space for the current procedure is reclaimed.
Transcript files are a Scheme feature, described in the R5 report, for
logging user interactions with Scheme. See the discussion of "transcript-on"
and "transcript-off" in the Command Summary portion of this document.
A world file is a special kind of binary file that contains the entire
non-garbage content of Scheme memory, and can be reloaded when
necessary, to restore the state of the Scheme world to what it was
when the world file was created.
When Pixie Scheme III is launched, it loads a private world file of its own,
but Pixie Scheme III provides no means for users to create or load their
own world files.
Wraith Scheme is a Scheme implementation for the Apple Macintosh;
Pixie Scheme II
was derived from Wraith Scheme by removing features and
creating a notably different user interface, then ported to the iPad
as Pixie Scheme III. Wraith Scheme has the full
"R5" set of procedures for access to files, as well
as a foreign-function interface and parallel processing capability.
Wraith Scheme is available from the software page of my web site,
http://web.mac.com/Jay_Reynolds_Freeman/My/Software.html.
Wraith Scheme is open-source under the GNU General Public License.
Copies of the source distribution are available from that same
web site: One source distribution includes the source for both
Wraith Scheme and Pixie Scheme II.
The cat for whom Wraith Scheme is named. I named her
Wraith not because of any supernatural qualities she possessed, but
because she was wary of humans, stealthy, pale gray in color and thus
well camouflaged in many circumstances, and when I first encountered
her you could count every rib: She was living wild in my new back yard in
Davenport, California, trying to be a good mother to three kittens,
and slowly starving.
So I took them all in. Wraith was feral to the point of being
vicious: My hands were in ribbons for several months after I acquired
her. She eventually turned into a sweetheart. I miss her.
abs
(abs 3) ;; ==> 3
(abs -3) ;; ==> 3
acos
(acos 1) ;; ==> 0
(acos 0) ;; ==> 1.5707963267948966
(acos -1) ;; ==> 3.1415926535897931
(acos +i) ;; ==> 1.5707963267948966-0.8813735870195428i
and
(and) ;; ==> #t
(and #t) ;; ==> #t
(and #f) ;; ==> #f
(and #t #t) ;; ==> #t
(and #f #t) ;; ==> #f
(define (foo) (begin (display "foo ") #f)) ;; ==> foo
(define (bar) (begin (display "bar ") #t)) ;; ==> bar
(and (foo) (bar)) ;; ==> foo #f
;; It didn't print "bar".
angle
(angle 1) ;; ==> 0
(angle -1) ;; ==> 3.1415926535897931
(angle +i) ;; ==> 1.5707963267948966
(angle -i) ;; ==> -1.5707963267948966
append
(append 1) ;; ==> 1
(append (list 1 2) (list 3 4)) ;; ==> (1 2 3 4)
(append (list 1 2) 3) ;; ==> (1 2 . 3)
(define a (list 1 2 3)) ;; ==> a
(define b (list 4 5 6)) ;; ==> b
(define ab (append a b)) ;; ==> ab
a ;; ==> (1 2 3)
;; Not (1 2 3 4 5 6)
b ;; ==> (4 5 6)
ab ;; ==> (1 2 3 4 5 6)
;; But:
(set-cdr! (cddr b) 7) ;; ==> #t
b ;; ==> (4 5 6 . 7)
ab ;; ==> (1 2 3 4 5 6 . 7)
(define c (list 1)) ;; ==> c
(set-cdr! c c) ;; ==> #t
c ;; ==> (1 1 1 1 1 1 1 1 1 1 1 ... )
(append c ab) ;; ==> <error>
;; c is not a proper list.
apply
(apply + (list 1 2)) ;; ==> 3 ;; Equivalent to (+ 1 2)
(apply + 1 2 (list 3 4)) ;; ==> 10 ;; Equivalent to
;; (+ 1 2 3 4), and to
;; (apply + (list 1 2 3 4)
asin
(asin 1) ;; ==> 1.5707963267948966
(asin 0) ;; ==> 0
(asin -1) ;; ==> -1.5707963267948966
(asin +i) ;; ==> 0.8813735870195428i
assoc
(assoc 1 '((1 2) (3 4))) ;; ==> (1 2)
(assoc 3 '((1 2) (3 4))) ;; ==> (3 4)
(assoc 42 '((1 2) (3 4))) ;; ==> #f
assq
(assq 1 '((1 2) (3 4))) ;; ==> (1 2)
(assq 3 '((1 2) (3 4))) ;; ==> (3 4)
(assq 42 '((1 2) (3 4))) ;; ==> #f
(assq (list 1 2) '(((1 2) 'foo) ((3 4) 'bar))) ;; ==> #f
(define a (list 1 2)) ;; ==> a
(define pair-list (list (list a 'foo) (list (list 3 4) 'bar)))
;; ==> pair-list
pair-list ;; ==> (((1 2) foo) ((3 4) bar))
(assq a pair-list) ;; ==> ((1 2) foo) ;; The two "(1 2)"s refer
;; to the same object.
assv
(assv 1 '((1 2) (3 4))) ;; ==> (1 2)
(assv 3 '((1 2) (3 4))) ;; ==> (3 4)
(assv 42 '((1 2) (3 4))) ;; ==> #f
(assv (list 1 2) '(((1 2) 'foo) ((3 4) 'bar))) ;; ==> #f
(define a (list 1 2)) ;; ==> a
(define pair-list (list (list a 'foo) (list (list 3 4) 'bar)))
;; ==> pair-list
pair-list ;; ==> (((1 2) foo) ((3 4) bar))
(assv a pair-list) ;; ==> ((1 2) foo)
atan
(atan 1000) ;; ==> 1.5697963271282296
(atan -1000) ;; ==> -1.5697963271282296
(atan -1 0) ;; ==> -1.5707963267948966
(atan 0 -1) ;; ==> 3.1415926535897931
(atan +2i) ;; ==> 1.5707963267948966+0.5493061443340549i
(atan -0.0000000001 -1000000000) ;; ==> -3.1415926535897931
(atan 0 0) ;; ==> 0
begin
(begin 1 2 3 4) ;; ==> 4
(begin (display "first ") (display "second ")) ;; ==> first second #t
;; In the top-level loop ...
(begin (define a 42) (define b 137)) ;; ==> b
a ;; ==> 42
b ;; ==> 137
boolean?
(boolean? #t) ;; ==> #t
(boolean? #f) ;; ==> #t
(boolean 'whatever) ;; ==> #f
call-with-current-continuation
(call-with-current-continuation procedure?) ;; ==> #t
(call-with-current-continuation
(lambda (exit)
(for-each (lambda (x)
(if (negative? x)
(exit x)))
'(54 0 37 -3 245 19))
#t))
;; ==> -3
call-with-values
;; Here is a fancy way to add up the integers
;; from one through ten: This example passes
;; the list returned by "values" to "+", just
;; as if you had entered
;;
;; (+ 1 2 3 4 5 6 7 8 9 10)
(call-with-values
(lambda () (values 1 2 3 4 5 6 7 8 9 10))
+) ;; ==> 55
;; We could equally well just list the numbers:
(call-with-values
(lambda () (values 1 2 3 4 5 6 7 8 9 10))
list)
;; ==> (1 2 3 4 5 6 7 8 9 10)
;; This rather cute example is from the R5 report:
;; Remember that the procedure call "(*)" returns "1".
(call-with-values * +) ;; ==> 1
car
(car '(1 2)) ;; ==> 1
(car '(1 . 2)) ;; ==> 1
(car '(1)) ;; ==> 1
(car (list 1 2 3 4 5 6)) ;; ==> 1
cdr
(cdr '(1 2)) ;; ==> (2)
(cdr '(1 . 2)) ;; ==> 2
(cdr '(1)) ;; ==> ()
(cdr (list 1 2 3 4 5 6)) ;; ==> (2 3 4 5 6)
caar  
cadr  
cdar  
cddr  
cadar
c a d a r
a d a
the car of the cdr of the car of
(cadar x)
(c a d a r x)
(a d a x)
(car cdr car x)
(car (cdr (car x)))
(define a (list 1 2 3 4 5 6)) ;; ==> a
(cadr a) ;; ==> 2
(cddr a) ;; ==> (3 4 5 6)
(cdar a) ;; ==> <error>
(caar a) ;; ==> <error>
(cdddr a) ;; ==> (4 5 6)
(cddddr a) ;; ==> (5 6)
(cadddr a) ;; ==> 4
(define b (list (list (list (list 'a))) 2 3 4))
;; ==> b
b ;; ==> ((((a))) 2 3 4)
(car b) ;; ==> (((a)))
(caar b) ;; ==> ((a))
(caaar b) ;; ==> (a)
(caaaar b) ;; ==> a
;; et cetera ad nauseam
(case (+ 1 0)
((1 3) 'first)
((2 3) 'second)
(else 'third)
) ;; ==> first
(case 2
((1 3) 'first)
((2 3) 'second)
(else 'third)
) ;; ==> second
(case 3
((1 3) 'first)
((2 3) 'second)
(else 'third)
) ;; ==> first
(case 4
((1 3) 'first)
((2 3) 'second)
(else 'third)
) ;; ==> third
(case 4
((1 3) 'first)
((2 3) 'second)
) ;; ==> #t
ceiling
(ceiling -6.5) ;; ==> -6.
(ceiling 4) ;; ==> 4
char->integer
(char->integer #\C) ;; ==> 67
(char->integer #\newline) ;; ==> 10
char-alphabetic?
(char-alphabetic? #\a) ;; ==> #t
(char-alphabetic? #\!) ;; ==> #f
char-ci<=?
(char-ci<=? #\a #\A) ;; ==> #t
(char-ci<=? #\A #\b) ;; ==> #t
(char-ci<=? #\a #\B) ;; ==> #t
(char-ci<=? #\B #\a) ;; ==> #f
(char-ci<=? #\b #\A) ;; ==> #f
(char-ci<=? #\a #\[) ;; ==> #f
(char-ci<=? #\A #\[) ;; ==> #f
char-ci<?
(char-ci<? #\a #\A) ;; ==> #f
(char-ci<? #\A #\b) ;; ==> #t
(char-ci<? #\a #\B) ;; ==> #t
(char-ci<? #\B #\a) ;; ==> #f
(char-ci<? #\b #\A) ;; ==> #f
(char-ci<? #\a #\[) ;; ==> #f
(char-ci<? #\A #\[) ;; ==> #f
char-ci=?
(char-ci=? #\a #\A) ;; ==> #t
(char-ci=? #\A #\b) ;; ==> #f
(char-ci=? #\a #\B) ;; ==> #f
(char-ci=? #\B #\a) ;; ==> #f
(char-ci=? #\b #\A) ;; ==> #f
(char-ci=? #\a #\[) ;; ==> #f
(char-ci=? #\A #\[) ;; ==> #f
char-ci>=?
(char-ci>=? #\a #\A) ;; ==> #t
(char-ci>=? #\A #\b) ;; ==> #f
(char-ci>=? #\a #\B) ;; ==> #f
(char-ci>=? #\B #\a) ;; ==> #t
(char-ci>=? #\b #\A) ;; ==> #t
(char-ci>=? #\a #\[) ;; ==> #t
(char-ci>=? #\A #\[) ;; ==> #t
char-ci>?
(char-ci>? #\a #\A) ;; ==> #f
(char-ci>? #\A #\b) ;; ==> #f
(char-ci>? #\a #\B) ;; ==> #f
(char-ci>? #\B #\a) ;; ==> #t
(char-ci>? #\b #\A) ;; ==> #t
(char-ci>? #\a #\[) ;; ==> #t
(char-ci>? #\A #\[) ;; ==> #t
char-downcase
(char-downcase #\A) ;; ==> #\a
(char-downcase #\a) ;; ==> #\a
(char-downcase #\!) ;; ==> #\!
char-lower-case?
(char-lower-case? #\a) ;; ==> #t
(char-lower-case? #\A) ;; ==> #f
(char-lower-case? #\!) ;; ==> <error>
char-numeric?
(char-numeric? #\3) ;; ==> #t
(char-numeric? #\a) ;; ==> #f
char-ready?
;; From the console, at top-level:
(char-ready ?) ;; ==> #t ;; The character is the "return"
;; that sent the text
;; "(char-ready?)"
;; to Pixie Scheme III.
(define (foo) (read-char) (char-ready?)) ;; ==> foo
(foo) ;; ==> #f ;; "read-char" read past the "return".
;; Suppose "port" is an input port to a file containing
;; just the text "abc".
(char-ready? port) ;; ==> #t
(read-char port) ;; ==> #\a
(char-ready? port) ;; ==> #t
(read-char port) ;; ==> #\b
(char-ready? port) ;; ==> #t
(read-char port) ;; ==> #\c
(char-ready? port) ;; ==> #t
(read-char port) ;; ==> #<End of File> ;; How Pixie Scheme III
;; displays an
;; end-of-file object.
(char-ready? port) ;; ==> #t
(read-char port) ;; ==> #<End of File>
(char-ready? port) ;; ==> #t
(read-char port) ;; ==> #<End of File>
(char-ready? port) ;; ==> #t
(read-char port) ;; ==> #<End of File>
;; To infinity, and beyond ...
char-upcase
(char-upcase #\A) ;; ==> #\A
(char-upcase #\a) ;; ==> #\A
(char-upcase #\!) ;; ==> #\!
char-upper-case?
(char-upper-case? #\a) ;; ==> #f
(char-upper-case? #\A) ;; ==> #t
(char-upper-case? #\!) ;; ==> <error>
char-whitespace?
(char-whitespace? #\a) ;; ==> #f
(char-whitespace? #\space) ;; ==> #t
char<=?
(char<=? #\a #\A) ;; ==> #t
(char<=? #\A #\b) ;; ==> #t
(char<=? #\a #\B) ;; ==> #f
(char<=? #\B #\a) ;; ==> #t
(char<=? #\b #\A) ;; ==> #f
(char<=? #\a #\[) ;; ==> #f
(char<=? #\A #\[) ;; ==> #t
char<?
(char<? #\a #\A) ;; ==> #f
(char<? #\A #\b) ;; ==> #t
(char<? #\a #\B) ;; ==> #f
(char<? #\B #\a) ;; ==> #t
(char<? #\b #\A) ;; ==> #f
(char<? #\a #\[) ;; ==> #f
(char<? #\A #\[) ;; ==> #t
char=?
(char=? #\a #\A) ;; ==> #f
(char=? #\A #\b) ;; ==> #f
(char=? #\a #\B) ;; ==> #f
(char=? #\B #\a) ;; ==> #f
(char=? #\b #\A) ;; ==> #f
(char=? #\a #\[) ;; ==> #f
(char=? #\A #\[) ;; ==> #f
char>=?
(char>=? #\a #\A) ;; ==> #t
(char>=? #\A #\b) ;; ==> #f
(char>=? #\a #\B) ;; ==> #t
(char>=? #\B #\a) ;; ==> #f
(char>=? #\b #\A) ;; ==> #t
(char>=? #\a #\[) ;; ==> #t
(char>=? #\A #\[) ;; ==> #f
char>?
(char>=? #\a #\A) ;; ==> #f
(char>=? #\A #\b) ;; ==> #f
(char>=? #\a #\B) ;; ==> #t
(char>=? #\B #\a) ;; ==> #f
(char>=? #\b #\A) ;; ==> #t
(char>=? #\a #\[) ;; ==> #t
(char>=? #\A #\[) ;; ==> #f
char?
(char? #\a) ;; ==> #t
(char? #\!) ;; ==> #t
(char? 42) ;; ==> #f
complex?
(complex? 0) ;; ==> #t
(complex? (expt 10 1000000)) ;; ==> #f ;; It's an inf.
(complex? #t) ;; ==> #f
cond
(cond (#f 1) (#f 2) (#f 3)) ;; ==> #t
(cond (#f 1) (#f 2) (#t 3)) ;; ==> 3
(cond (#f 1) (#f 2) (#t 3 4 (+ 5 6))) ;; ==> 11
(cond (#f 1) (#f 2) (else 3)) ;; ==> 3
(cond
((= (* 6 9) 42) 'peculiar)
((= (* 6 9) 54) 'mundane)
) ;; ==> mundane
cons
(cons 1 2) ;; ==> (1 . 2)
(cons 'a '()) ;; ==> (a)
(cons 1 (list 2 3 4 5)) ;; ==> (1 2 3 4 5)
(cons (list 1 2 3) (list 4 5 6))
;; ==> ((1 2 3) 4 5 6)
cos
(cos 0) ;; ==> 1
(cos 1.5707963267948966)
;; ==> 6.123031769111886e-17 ;; Very nearly zero.
(cos 0.7853981633974483)
;; ==> 0.7071067811865476
(cos +i) ;; ==> 1.5430806348152437
current-input-port
;; When input is being taken from the keyboard:
(current-input-port) ;; ==> #<Console Input Port>
current-output-port
;; When input is being sent to the display:
(current-output-port) ;; ==> #<Console Output Port>
define
(define (name var1 var2 ... varN)
expression1
expression2
...
expressionN
)
(define name
(lambda (var1 var2 ... varN)
expression1
expression2
...
expressionN
)
)
(define (name var1 var2 ... varN-1 . varN)
expression1
expression2
...
expressionN
)
(define name
(lambda (var1 var2 ... varN-1 . varN)
expression1
expression2
...
expressionN
)
)
(define (name . var)
expression1
expression2
...
expressionN
)
(define name
(lambda var
expression1
expression2
...
expressionN
)
)
(define a 42) ;; ==> a
a ;; ==> 42
(define a 'foo) ;; ==> a
a ;; ==> foo
(define (hypotenuse x y)
(sqrt (+ (* x x) (* y y))))
;; ==> hypotenuse
(hypotenuse 5 12) ;; ==> 13
(define (foo a) (display a)) ;; ==> foo
(foo 1 2 3 4 5) ;; ==> (1 2 3 4 5)#t
(define (foo b . c)
(display b)
(display c)) ;; ==> foo
(foo 1 2 3 4 5) ;; ==> 1(2 3 4 5)#t
define-syntax
(define-syntax
when
(syntax-rules ()
((when test stmt) (if test stmt))
((when test stmt ...) (if test (begin stmt ...))
)))
;; ==> when
(when #t 3) ;; ==> 3
(when #f 3) ;; ==> #f
(when #t (display "foo\n") (display "bar\n") 42) ;; ==>
foo
bar
42
delay
;; Note how Pixie Scheme III displays a promise:
(delay (display "Carpe diem\n")) ;; ==> #<Promise>
(define foo (delay (begin (display "Carpe diem\n") 123)))
;; ==> foo
(force foo) ;; ==>
Carpe diem ;; Side effect of evaluation.
123 ;; The returned value.
(force foo) ;; ==>
123 ;; Evaluation happens only once --
;; the returned value is saved so
;; it may be returned repeatedly.
(force foo) ;; ==> 123
display
(display "This string\nhas three\nembedded newlines.\n") ;; ==>
This string
has three
embedded newlines.
#t
(display 5/7) ;; ==> 0.7142857142857143#t
(let ((my-port (open-output-file "Foo")))
(display 5/7 my-port)
(close-output-port my-port)) ;; ==> #t ;; And writes to "Foo".
do
(do ((vec (make-vector 3))
(k 0 (+ k 1)))
((= k 3) vec)
(vector-set! vec k (* k k))) ;; ==> #(0 1 4)
The syntax of "do" is sometimes confusing. Let me put some comments and some extra words
into the previous example, to make it clearer: Think of the italicized words as comments.
(do
;; List of initialization-and-update clauses:
;; Each specifies a variable name, its initial
;; value, and any automatic update to it, that
;; takes place after each pass through the loop.
((vec (make-vector 3)) ;; No automatic change to vec.
(k 0 (+ k 1))) ;; Change k to (+ k 1) after each loop.
;; Loop test and body follow ...
(if (= k 3)
then-return vec) ;; ((= k 3)) would stop the do but
;; return an undefined value.
else
(vector-set! vec k (* k k))
;; Update variables as specified in the clauses for
;; initialization-and-update -- e.g., replace k by
;; (+ k 1) -- and then go back for another pass
;; through the loop test and body.
)
;; ==> #(0 1 4)
dynamic-wind
(let ((path '())
(c #f))
(let ((add (lambda (s) (set! path (cons s path)))))
(dynamic-wind
(lambda () (add 'connect))
(lambda ()
(add
(call-with-current-continuation
(lambda (c0)
(set! c c0)
'talk1))))
(lambda () (add 'disconnect)))
(if (< (length path) 4)
(c 'talk2)
(reverse path))))
;; ==> (connect talk1 disconnect connect talk2 disconnect)
else
See "cond".
eof-object?
;; Suppose foo is an input port to a file containing
;; three characters, and that Pixie Scheme III has already
;; read those characters.
(eof-object? (read-char? foo)) ;; ==> #t
(eof-object? 42) ;; ==> #f
eq?
(eq? 1 1) ;; ==> #t
(eq? 1 2) ;; ==> #f
(eq? #\a #\a) ;; ==> #t
(eq? #\a #\b) ;; ==> #f
(eq? #t #t) ;; ==> #t
(eq? #t #f) ;; ==> #f
(define a (list 1 2)) ;; ==> a
(define b (cons a '())) ;; ==> b
(eq? a (car b)) ;; ==> #t
(define c (list 1 2)) ;; ==> c
(eq? a c) ;; ==> #f
;; Two different lists.
(eq? (list 1 2) (list 1 2)) ;; ==> #f ;; Ditto.
equal?
(equal? 1 1) ;; ==> #t
(equal? 1 2) ;; ==> #f
(equal? #\a #\a) ;; ==> #t
(equal? #\a #\b) ;; ==> #f
(equal? #t #t) ;; ==> #t
(equal? #t #f) ;; ==> #f
(define a (list 1 2)) ;; ==> a
(define b (cons a '())) ;; ==> b
(equal? a (car b)) ;; ==> #t
(define c (list 1 2))
(equal? a c) ;; ==> #t
;; Different lists notwithstanding.
(equal? (list 1 2) (list 1 2)) ;; ==> #t ;; Ditto.
eqv?
(eqv? 1 1) ;; ==> #t
(eqv? 1 2) ;; ==> #f
(eqv? #\a #\a) ;; ==> #t
(eqv? #\a #\b) ;; ==> #f
(eqv? #t #t) ;; ==> #t
(eqv? #t #f) ;; ==> #f
(define a (list 1 2)) ;; ==> a
(define b (cons a '())) ;; ==> b
(eqv? a (car b)) ;; ==> #t
(define c (list 1 2))
(eqv? a c) ;; ==> #f
;; Two different lists.
(eqv? (list 1 2) (list 1 2)) ;; ==> #f ;; Ditto.
(eqv? 1 #e1.0) ;; ==> #t
(eqv? 1 #i1.0) ;; ==> #f
eval
(eval '(+ 2 2) (interaction-environment))
;; ==> 4
(eval '(+ 2 2) (scheme-report-environment 5))
;; ==> 4
(eval '(+ 2 2) (null-environment 5))
;; ==> <error> ;; "+" is not defined in the null environment.
(eval '(if #t 2 3) (null-environment 5))
;; ==> 2
(define a 42)
;; ==> a
a
;; ==> 42
(let ((a 3)) a)
;; ==> 3
(let ((a 3)) (eval 'a (interaction-environment)))
;; ==> 42
even?
(even? 42) ;; ==> #t
(even? 137) ;; ==> #f
exact->inexact
(exact->inexact 1) ;; ==> 1.
(exact->inexact #i1) ;; ==> 1.
(exact->inexact +i) ;; ==> 1.i
exact?
(exact? 1) ;; ==> #t
(exact? 1.) ;; ==> #f
exp
(exp 0) ;; ==> 1
(exp 1) ;; ==> 2.7182818284590451
(exp -2.5) ;; ==> 0.0820849986238988
(exp 3.1415926535897931i) ;; ==> -1.+1.2246467991473532e-16i
expt
(expt 2 3) ;; ==> 8
(expt 3 2) ;; ==> 9
(expt 2 0.5) ;; ==> 1.4142135623730951
(expt 1.4142135623730951 0.5) ;; ==> 1.189207115002721
(expt -1 0.5) ;; ==> 6.123233995736766e-17+1.i
(expt (exp 1) 3.1415926535897931i) ;; ==> -1.+1.2246467991473532e-16i
floor
(floor -6.5) ;; ==> -7.
(floor 4) ;; ==> 4
for-each
(define (make-sandwich first second bread)
(display first)
(display " and ")
(display second)
(display " on ")
(display bread)
(newline)
'yum) ;; ==> make-sandwich
(for-each
make-sandwich
(list "ham" "tuna" "tofu" "peanut butter")
(list "cheese" "tomato" "sprouts" "asparagus")
(list "rye" "whole wheat" "seven-grain" "banana bread")
) ;; ==>
ham and cheese on rye
tuna and tomato on whole wheat
tofu and sprouts on seven-grain
peanut butter and asparagus on banana bread
#t
force
;; Note how Pixie Scheme III displays a promise:
(delay (display "Carpe diem\n")) ;; ==> #<Promise>
(define foo (delay (begin (display "Carpe diem\n") 123)))
;; ==> foo
(force foo) ;; ==>
Carpe diem ;; Side effect of evaluation.
123 ;; The returned value.
(force foo) ;; ==>
123 ;; Evaluation happens only once --
;; the returned value is saved so
;; it may be returned repeatedly.
(force foo) ;; ==>
123
gcd
(gcd 28 98) ;; ==> 14
(gcd 999999999999 209457) ;; ==> 333
if
(if #t (+ 1 2) (+ 3 4)) ;; ==> 3
(if #f (+ 1 2) (+ 3 4)) ;; ==> 7
(if #f (+ 1 2)) ;; ==> #f
imag-part
(imag-part 1) ;; ==> 0
(imag-part +i) ;; ==> 1
(imag-part 1.+i) ;; ==> 1.
inexact->exact
(inexact->exact 1) ;; ==> 1
(inexact->exact #i1) ;; ==> 1
(inexact->exact 1.i) ;; ==> +i
inexact?
(inexact? 1) ;; ==> #f
(inexact? 1.) ;; ==> #t
input-port?
(define foo (open-input-file "This.file.must.exist")) ;; ==> foo
(input-port? foo) ;; ==> #t
(close-input-port foo) ;; ==> #t
(input-port? foo) ;; ==> #f
(input-port? 42) ;; ==> #f
integer->char
(integer->char 65) ;; ==> #\A
(integer->char 128) ;; ==> <error>
integer?
(integer? 3) ;; ==> #t
(integer? 3.1) ;; ==> #f
;; Technically, an integer is a real number with no fractional
;; part. The floating-point representations used by Pixie
;; Scheme III do not contain enough bits to represent the
;; fractional parts of numbers of large absolute value, hence
;; such numbers are necessarily reported as integers. Thus:
(integer? (/ 1.e100 3)) ;; ==> #t
;; Note that in Pixie Scheme III
(/ 1.e100 3) ;; ==> 3.3333333333333332e99
;; which is 33333333333333332 followed by lots of zeros --
;; unarguably the external representation of an integer.
interaction-environment
(eval '(+ 2 2) (interaction-environment))
4
lambda
(define hypotenuse
(lambda (x y)
(sqrt (+ (* x x) (* y y)))))
;; ==> hypotenuse
(hypotenuse 5 12) ;; ==> 13
(define foo
(lambda a (display a))) ;; ==> foo
(foo 1 2 3 4 5) ;; ==> (1 2 3 4 5)#t
(define foo
(lambda (b . c)
(display b)
(display c))) ;; ==> foo
(foo 1 2 3 4 5) ;; ==> 1(2 3 4 5)#t
lcm
(lcm 24 60) ;; ==> 120
(lcm 99 88) ;; ==> 792
length
(length (list 'a 'b 'c)) ;; ==> 3
(length '()) ;; ==> 0
(length '(1 2 . 3)) ;; ==> <error>
let
(define a 'aa) ;; ==> a
(define b 'bb) ;; ==> b
(define c 'cc) ;; ==> c
(let
((a c) ;; Local a gets the top-level value of c, which is 'cc
(b a) ;; Local b gets the top-level value of a, which is 'aa
(c b)) ;; Local c gets the top-level value of b, which is 'bb
(list a b c)) ;; ==> (cc aa bb) ;; The values local to the let.
let-syntax
(let ((x 'outer))
(let-syntax ((m (syntax-rules () ((m) x))))
(test::let ((x 'inner))
(m))))
;; ==> outer
let*
(define a 'a) ;; ==> aa
(define b 'b) ;; ==> bb
(define c 'c) ;; ==> cc
(let*
((a c) ;; Local a gets the top-level value of c, which is cc
(b a) ;; Local b gets the local value of a, which is cc
(c b)) ;; Local c gets the local value of b, which is cc
(list a b c)) ;; ==> (cc cc cc) ;; The values local to the let.
letrec
(define a 'aa) ;; ==> a
(define b 'bb) ;; ==> b
(define c 'cc) ;; ==> c
(letrec
((a c) ;; Local a gets the top-level value of c, which is 'cc
(b a) ;; Local b gets the top-level value of a, which is 'aa
(c b)) ;; Local c gets the top-level value of b, which is 'bb
(list a b c)) ;; ==> (() () ()) ;; All uninitialized.
(letrec
((my-even? (lambda (n)
(if (zero? n)
#t
(my-odd? (- n 1)))))
(my-odd? (lambda (n)
(if (zero? n)
#f
(my-even? (- n 1))))))
(my-even? 42)) ;; ==> #t
letrec-syntax
(letrec-syntax
((my-or (syntax-rules ()
((my-or) #f)
((my-or e) e)
((my-or e1 e2 ...)
(let ((temp e1))
(if temp
temp
(my-or e2 ...)))))))
(my-or))
;; ==> #f
list
(list) ;; ==> ()
(list 1 2 3) ;; ==> (1 2 3)
list->string
(list->string '()) ;; ==> ""
(list->string '(#\C #\a #\t)) ;; ==> "Cat"
list->vector
(list->vector '()) ;; ==> #()
(list->vector (list 1 (list 2 3 4) (* 6 7) "Foo"))
;; ==> #(1 (2 3 4) 42 "Foo")
list-ref
(list-ref '(1 2 3) 0) ;; ==> 1
(list-ref '(1 2 3) 1) ;; ==> 2
(list-ref '(1 2 3) 2) ;; ==> 3
list-tail
(list-tail '(1 2 3) 0) ;; ==> (1 2 3)
(list-tail '(1 2 3) 1) ;; ==> (2 3)
(list-tail '(1 2 3) 2) ;; ==> (3)
(list-tail '(1 2 3) 3) ;; ==> ()
list?
(list '()) ;; ==> #t
(list '(1 2 3 4 5) ;; ==> #f
(list '(1 2 3 4 . 5) ;; ==> #f
(define a (list 1)) ;; ==> a
(set-cdr! a a) ;; ==> #t
(list? a) ;; ==> #f ;; circular list
log
(log 1) ;; ==> 0
(log 2.7182818284590451) ;; ==> 1.
(log (/ 2.7182818284590451)) ;; ==> -1.
(log -1) ;; ==> 3.1415926535897931i
magnitude
(magnitude 1) ;; ==> 1
(magnitude -1) ;; ==> 1
(magnitude +i) ;; ==> 1
(magnitude 1.+i) ;; ==> 1.4142135623730951
make-polar
(make-polar 1 0) ;; ==> 1
(make-polar -1 0) ;; ==> -1
(make-polar 1 1.5707963267948966) ;; ==> 6.123233995736766e-17+1.i
make-rectangular
(make-rectangular 1 1) ;; ==> 1+i
(make-rectangular 0 1) ;; ==> +i
(make-rectangular 1 0) ;; ==> 1
make-string
(make-string 0) ;; ==> ""
(make-string 3) ;; ==> " "
(make-string 3 #\q) ;; ==> "qqq"
(make-string) ;; Pixie Scheme III prompts the user to
;; type in a string.
make-vector
(make-vector 0) ;; ==> #()
(make-vector 3) ;; ==> #(() () ())
(make-vector 3 (list 1 2))
;; ==> #((1 2) (1 2) (1 2))
map
(define (make-sandwich first second bread)
(display first)
(display " and ")
(display second)
(display " on ")
(display bread)
(newline)
(if (equal? bread "banana bread")
'yech
'yum)) ;; ==> make-sandwich
(map
make-sandwich
(list "ham" "tuna" "tofu" "peanut butter")
(list "cheese" "tomato" "sprouts" "asparagus")
(list "rye" "whole wheat" "seven-grain" "banana bread")
) ;; ==> ham and cheese on rye
;; tuna and tomato on whole wheat
;; tofu and sprouts on seven-grain
;; peanut butter and asparagus on banana bread
;; (yum yum yum yech)
max
(max -17 23 -102.5 9) ;; ==> 23
member
(member 2 (list 1 2 3)) ;; ==> (2 3)
(member 'b '(a b c)) ;; ==> (b c)
(member (list 'a) '(b (a) c)) ;; ==> ((a) c)
memq
(memq 2 (list 1 2 3)) ;; ==> (2 3)
(memq 'b '(a b c)) ;; ==> (b c)
(memq (list 'a) '(b (a) c)) ;; ==> #f
memv
(memv 2 (list 1 2 3)) ;; ==> (2 3)
(memv 'b '(a b c)) ;; ==> (b c)
(memv (list 'a) '(b (a) c)) ;; ==> #f
min
(min -17 23 -102.5 9) ;; ==> -102.5
modulo
(modulo 13 4) ;; ==> 1
(modulo -13 4) ;; ==> 3
(modulo 13 -4) ;; ==> -3
(modulo -13 -4) ;; ==> -1
negative?
(negative 0) ;; ==> #f
(negative 1) ; ; ==> #f
(negative -1) ;; ==> #t
newline
(newline) ;; ==>
;; Just wrote a newline.
;; Suppose "foo" is an output port:
(newline foo) ;; ==> #t ;; Wrote a newline to foo
not
(not #f) ;; ==> #t
(not 42) ;; ==> #f
(not '()) ;; ==> #f
null-environment
=>
and
begin
c::begin
c::if
c::lambda
c::set!
case
cond
define
delay
do
else
if
lambda
let
let*
letrec
or
quasiquote
quote
set!
unquote
unquote-splicing
(eval '(if #t 2 3) (null-environment 5))
2
null?
(null? #f) ;; ==> #f
(null? 42) ;; ==> #f
(null? '()) ;; ==> #t
number->string
(number->string 10) ;; ==> "10"
(number->string 10 2) ;; ==> "1010"
(number->string 10 8) ;; ==> "12"
(number->string 10 16) ;; ==> "a"
number?
(number? 'foo) ;; ==> #f
(number? 1.234) ;; ==> #t
(number? 1e10000) ;; ==> #f ;; inf
(number? (/ 1e10000 1e10000) ;; ==> #f ;; nan
odd?
(odd? 42) ;; ==> #f
(odd? 137) ;; ==> #t
or
(and) ;; ==> #t
(or #t) ;; ==> #t
(or #f) ;; ==> #f
(or #t #t) ;; ==> #t
(or #f #t) ;; ==> #t
(or #f #f) ;; ==> #f
(define (foo) (begin (display "foo ") #f)) ;; ==> foo
(define (bar) (begin (display "bar ") #t)) ;; ==> bar
(or (bar) (foo)) ;; ==> bar #t
;; It didn't print "foo".
output-port?
(define foo (open-output-file "Some.output.file")) ;; ==> foo
(output-port? foo) ;; ==> #t
(close-output-port foo) ;; ==> #t
(output-port? foo) ;; ==> #f
(output-port? 42) ;; ==> #f
pair?
(pair? '(1 . 2)) ;; ==> #t
(pair? (list 1 2)) ;; ==> #t
(pair? '()) ;; ==> #f
(pair? 42) ;; ==> #f
peek-char
;; Suppose that foo is an input port just opened to
;; a text file containing just one character, "a":
(peek-char foo) ;; ==> #\a
(peek-char foo) ;; ==> #\a
(peek-char foo) ;; ==> #\a
(peek-char foo) ;; ==> #\a
(read-char foo) ;; ==> #\a
(peek-char foo) ;; ==> #<End of File>
port?
(define foo (open-output-file "Some.output.file")) ;; ==> foo
(define bar (open-input-file "Some.existing.input.file")) ;; ==> bar
(port? foo) ;; ==> #t
(port? bar) ;; ==> #t
(close-output-port foo) ;; ==> #t
(close-input-port bar) ;; ==> #t
(port? foo) ;; ==> #f
(port? bar) ;; ==> #f
(port? 42) ;; ==> #f
positive?
(positive 0) ;; ==> #f
(positive 1) ;; ==> #t
(positive -1) ;; ==> #f
procedure?
(procedure? +) ;; ==> #t
(procedure? (lambda (x) (+ x 1))) ;; ==> #t
(procedure? lambda) ;; ==> #f
(procedure? let) ;; ==> #f
quasiquote
(define foo "A string named foo") ;; ==> foo
(quasiquote foo) ;; ==> foo
`foo ;; ==> foo
(quasiquote ,foo) ;; ==> "A string named foo."
`,foo ;; ==> "A string named foo."
(define a 42) ;; ==> a
(quasiquote (+ 2 a)) ;; ==> (+ 2 a)
`(+ 2 a) ;; ==> (+ 2 a)
`(+ 2 ,a) ;; ==> (+ 2 42)
(define b (list 27 18 28)) ;; ==> b
`(+ 2 b) ;; ==> (+ 2 b)
`(+ 2 ,b) ;; ==> (+ 2 (27 18 28)) ;; Doesn't add up ....
`(+ 2 ,@b) ;; ==> (+ 2 27 18 2)
quote
(quote foo) ;; ==> foo
'foo ;; ==> foo
(quote (+ 2 2)) ;; ==> (+ 2 2)
'(+ 2 2) ;; ==> (+ 2 2)
quotient
(quotient 13 4) ;; ==> 3
(quotient -13 4) ;; ==> -3
(quotient 13 -4) ;; ==> -3
(quotient -13 -4) ;; ==> 3
rational?
(rational? #t) ;; ==> #f
(rational? 1) ;; ==> #t
(rational? 1.5) ;; ==> #t
(rational? (sqrt 2)) ;; ==> #t
;; Note that in Pixie Scheme III
(sqrt 2) ;; ==> 1.4142135623730951
;; which is 14142135623730951/10000000000000000
;; and thus is rational.
read
;; Suppose "foo" is a newly-opened input port to a file containing
;; the text "(+ 2 2) No more".
(read foo) ;; ==> (+ 2 2)
(read foo) ;; ==> No
(read foo) ;; ==> more
(read foo) ;; ==> <End of File>
read-char
;; Suppose that foo is an input port just opened to
;; a text file containing the text "abc":
(read-char foo) ;; ==> #\a
(read-char foo) ;; ==> #\b
(read-char foo) ;; ==> #\c
(read-char foo) ;; ==> #<End of File>
(read-char foo) ;; ==> #<End of File>
(read-char foo) ;; ==> #<End of File>
real-part
(real-part 1) ;; ==> 1
(real-part +i) ;; ==> 0
(real-part 1.+i) ;; ==> 1.
real?
(real? #t) ;; ==> #f
(real? 1) ;; ==> #t
(real? 1.5) ;; ==> #t
(real? (sqrt 2)) ;; ==> #t
remainder
(remainder 13 4) ;; ==> 1
(remainder -13 4) ;; ==> -1
(remainder 13 -4) ;; ==> 1
(remainder -13 -4) ;; ==> -1
reverse
(reverse '()) ;; ==> ()
(reverse (list 1 2 3)) ;; ==> (3 2 1)
round
(round 3.49) ;; ==> 3.
(round 3.51) ;; ==> 4.
(round 3.5) ;; ==> 4.
(round 2.5) ;; ==> 2.
scheme-report-environment
(eval '(+ 2 2) (scheme-report-environment 5))
4
set!
;; Suppose that "a" has never had a value or binding.
(set! a 42) ;; ==> <error> ;; No value to change.
(define a 23) ;; ==> a
a ;; ==> 23
(set! a 42) ;; ==> #t
a ;; ==> 42
set-car!
(define a (cons 1 2)) ;; ==> a
a ;; ==> (1 . 2)
(set-car! a 42) ;; ==> #t
a ;; ==> (42 . 2)
set-cdr!
(define a (cons 1 2)) ;; ==> a
a ;; ==> (1 . 2)
(set-cdr! a 42) ;; ==> #t
a ;; ==> (1 . 42)
sin
(sin 0) ;; ==> 0
(sin 1.5707963267948966) ;; ==> 1.
(sin 0.7853981633974483) ;; ==> 0.7071067811865475
(sin +i) ;; ==> 1.1752011936438014i
sqrt
(sqrt 0) ;; ==> 0
(sqrt 2.5) ;; ==> 1.5811388300841898
(sqrt 4) ;; ==> 2
(sqrt -1) ;; ==> +i
(sqrt +i) ;; ==> 0.7071067811865476+0.7071067811865475i
string
(string) ;; ==> ""
(string #\C #\a #\t) ;; ==> "Cat"
string->list
(string->list "Cat") ;; ==> (#\C #\a #\t)
string->number
(string->number "123") ;; ==> 123
(string->number "1001" 2) ;; ==> 9
(string->number "1001" 8) ;; ==> 513
(string->number "1001" 10) ;; ==> 1001
(string->number "1001") ;; ==> 1001
(string->number "1001" 16) ;; ==> 4097
(string->number "-#i123###.e23") ;; ==> -1.2300000000000001e28
string->symbol
(string->symbol "Cat") ;; ==> Cat ;; Note the capitalization.
string-append
(string-append "I " "see " "the " "cat.")
;; ==> "I see the cat."
string-ci<=?
(string-ci<=? "aa" "aardvark") ;; ==> #t
(string-ci<=? "Aa" "aardvark") ;; ==> #t
(string-ci<=? "aa" "Aardvark") ;; ==> #t
(string-ci<=? "aa" "pahoehoe") ;; ==> #t
(string-ci<=? "pahoehoe" "aa") ;; ==> #f
(string-ci<=? "aardvark" "aardvark") ;; ==> #t
string-ci<?
(string-ci<? "aa" "aardvark") ;; ==> #t
(string-ci<? "Aa" "aardvark") ;; ==> #t
(string-ci<? "aa" "Aardvark") ;; ==> #t
(string-ci<? "aa" "pahoehoe") ;; ==> #t
(string-ci<? "pahoehoe" "aa") ;; ==> #f
(string-ci<? "aardvark" "aardvark") ;; ==> #f
string-ci=?
(string-ci=? "aa" "aardvark") ;; ==> #f
(string-ci=? "Aa" "aardvark") ;; ==> #f
(string-ci=? "aa" "Aardvark") ;; ==> #f
(string-ci=? "aa" "pahoehoe") ;; ==> #f
(string-ci=? "aardvark" "aardvark") ;; ==> #t
(string-ci=? "aardvark" "AARDVARK") ;; ==> #t
string-ci>=?
(string-ci>=? "aa" "aardvark") ;; ==> #f
(string-ci>=? "Aa" "aardvark") ;; ==> #f
(string-ci>=? "aa" "Aardvark") ;; ==> #f
(string-ci>=? "aa" "pahoehoe") ;; ==> #f
(string-ci>=? "pahoehoe" "aa") ;; ==> #t
(string-ci>=? "aardvark" "aardvark") ;; ==> #t
string-ci>?
(string-ci>? "aa" "aardvark") ;; ==> #f
(string-ci>? "Aa" "aardvark") ;; ==> #f
(string-ci>? "aa" "Aardvark") ;; ==> #f
(string-ci>? "aa" "pahoehoe") ;; ==> #f
(string-ci>? "pahoehoe" "aa") ;; ==> #t
(string-ci>? "aardvark" "aardvark") ;; ==> #f
string-copy
(string-copy "Cat") ;; ==> "Cat"
string-fill!
(define a (make-string 2)) ;; ==> a
a ;; ==> " "
(string-fill! a #\x) ;; ==> #t
a ;; ==> "xx"
string-length
(string-length "Cat") ;; ==> 3
string-ref
(string-ref "Cat" 0) ;; ==> #\C
(string-ref "Cat" 1) ;; ==> #\a
(string-ref "Cat" 2) ;; ==> #\t
string-set!
(define a (make-string 3)) ;; ==> a
a ;; ==> " "
(string-set! a 0 #\C) ;; ==> #t
a ;; ==> "C "
(string-set! a 1 #\a) ;; ==> #t
a ;; ==> "Ca "
(string-set! a 2 #\t) ;; ==> #t
a ;; ==> "Cat"
string<=?
(string<=? "aa" "aardvark") ;; ==> #t
(string<=? "Aa" "aardvark") ;; ==> #t
(string<=? "aa" "Aardvark") ;; ==> #f
(string<=? "aa" "pahoehoe") ;; ==> #t
(string<=? "aardvark" "aardvark") ;; ==> #t
string<?
(string<? "aa" "aardvark") ;; ==> #t
(string<? "Aa" "aardvark") ;; ==> #t
(string<? "aa" "Aardvark") ;; ==> #f
(string<? "aa" "pahoehoe") ;; ==> #t
(string<? "aardvark" "aardvark") ;; ==> #f
string=?
(string=? "aa" "aardvark") ;; ==> #f
(string=? "Aa" "aardvark") ;; ==> #f
(string=? "aa" "Aardvark") ;; ==> #f
(string=? "aa" "pahoehoe") ;; ==> #f
(string=? "aardvark" "aardvark") ;; ==> #t
(string=? "aardvark" "AARDVARK") ;; ==> #f
string>=?
(string>=? "aa" "aardvark") ;; ==> #f
(string>=? "Aa" "aardvark") ;; ==> #f
(string>=? "aa" "Aardvark") ;; ==> #t
(string>=? "aa" "pahoehoe") ;; ==> #f
(string>=? "pahoehoe" "aa") ;; ==> #t
(string>=? "aardvark" "aardvark") ;; ==> #t
string>?
(string>? "aa" "aardvark") ;; ==> #f
(string>? "Aa" "aardvark") ;; ==> #f
(string>? "aa" "Aardvark") ;; ==> #t
(string>? "aa" "pahoehoe") ;; ==> #f
(string>? "pahoehoe" "aa") ;; ==> #t
(string>? "aardvark" "aardvark") ;; ==> #f
string?
(string? #t) ;; ==> #f
(string? 'Cat) ;; ==> #f
(string? "Cat") ;; ==> #t
substring
(substring "Cat" 0 0) ;; ==> ""
(substring "The cat sees me." 4 7) ;; ==> "cat"
symbol->string
(symbol->string 'foo) ;; ==> "foo"
symbol?
(symbol? #t) ;; ==> #f
(symbol? "foo") ;; ==> #f
(symbol? 'foo) ;; ==> #t
syntax-rules
(syntax-rules foo bar baz)
(syntax-rules foo bar baz) ;; ==>
00000003-15d458ac: Symbol -- Not a Car
Problem: Implementation: Tried to take the car of a non-pair.
Last lambda called (which may have returned) has never been named.
Recent names of non-tail-recursive stacked lambda expressions:
c::if-code
c::let-code
()
(Resetting)
Top-level loop ...
(syntax-rules foo bar baz)
(define-syntax foo (syntax-rules foo bar baz))
(define-syntax foo (syntax-rules foo bar baz))
"syntax-rules" used as shown, but the second argument is not a transformer specification.
The problems include:
Problem: The second item in that argument is not a list of identifiers. (Resetting)
Top-level loop ...
tan
(tan 0) ;; ==> 0
(tan 1.5707963267948966) ;; ==> 16331778728383844
(tan 3) ;; ==> -0.1425465430742778
(tan +i) ;; ==> 0.7615941559557649i
truncate
(truncate 1) ;; ==> 1
(truncate 1.00001) ;; ==> 1.
(truncate 1.9999) ;; ==> 1.
(truncate 0.9999) ;; ==> 0.
(truncate -1) ;; ==> -1
(truncate -1.00001) ;; ==> -1.
(truncate -1.9999) ;; ==> -1.
(truncate -0.9999) ;; ==> 0.
unquote
(define foo "A string named foo") ;; ==> foo
(quasiquote foo) ;; ==> foo
`foo ;; ==> foo
(quasiquote ,foo) ;; ==> "A string named foo."
`,foo ;; ==> "A string named foo."
(define a 42) ;; ==> a
(quasiquote (+ 2 a)) ;; ==> (+ 2 a)
`(+ 2 a) ;; ==> (+ 2 a)
`(+ 2 ,a) ;; ==> (+ 2 42)
(define b (list 27 18 28)) ;; ==> b
`(+ 2 b) ;; ==> (+ 2 b)
`(+ 2 ,b) ;; ==> (+ 2 (27 18 28)) ;; Doesn't add up ....
`(+ 2 ,@b) ;; ==> (+ 2 27 18 2)
unquote-splicing
(define foo "A string named foo") ;; ==> foo
(quasiquote foo) ;; ==> foo
`foo ;; ==> foo
(quasiquote ,foo) ;; ==> "A string named foo."
`,foo ;; ==> "A string named foo."
(define a 42) ;; ==> a
(quasiquote (+ 2 a)) ;; ==> (+ 2 a)
`(+ 2 a) ;; ==> (+ 2 a)
`(+ 2 ,a) ;; ==> (+ 2 42)
(define b (list 27 18 28)) ;; ==> b
`(+ 2 b) ;; ==> (+ 2 b)
`(+ 2 ,b) ;; ==> (+ 2 (27 18 28)) ;; Doesn't add up ....
`(+ 2 ,@b) ;; ==> (+ 2 27 18 2)
values
;; Here is a fancy way to add up the integers
;; from one through ten: This example passes
;; the list returned by "values" to "+", just
;; as if you had entered
;;
;; (+ 1 2 3 4 5 6 7 8 9 10)
(call-with-values
(lambda () (values 1 2 3 4 5 6 7 8 9 10))
+) ;; ==> 55
;; We could equally well just list the numbers:
(call-with-values
(lambda () (values 1 2 3 4 5 6 7 8 9 10))
list)
;; ==> (1 2 3 4 5 6 7 8 9 10)
;; In the top-level loop:
(values 1 2 3 4 5 6 7 8 9 10)
;; ==> #<Multiple Values Return>
vector
(vector) ;; ==> #()
(vector 1 2 3) ;; ==> #(1 2 3)
vector->list
(define a (make-vector 3)) ;; ==> a
a ;; ==> #(() () ())
(define b (vector->list a)) ;; ==> b
b ;; ==> (() () ())
(vector-set! a 2 4) ;; ==> #t
a ;; ==> #(() () 4)
b ;; ==> (() () ())
;; b does not share memory with a.
(vector->list a) ;; ==> (() () 4) ;; New copy of a.
vector-fill!
(define cat (make-vector 3)) ;; ==> cat
(vector-fill! cat 'meow) ;; ==> #t
cat ;; ==> #(meow meow meow)
vector-length
(vector-length '#()) ;; ==> 0
(vector-length '#(meow meow meow)) ;; ==> 3
vector-ref
(vector-ref '#(c a t) 0) ;; ==> #\c
(vector-ref '#(c a t) 1) ;; ==> #\a
(vector-ref '#(c a t) 2) ;; ==> #\t
vector-set!
(define a (make-vector 3)) ;; ==> a
a ;; ==> #(() () ())
(vector-set! a 0 'c) ;; ==> #t
a ;; ==> #(c () ())
(vector-set! a 1 'a) ;; ==> #t
a ;; ==> #(c a ())
(vector-set! a 2 't) ;; ==> #t
a ;; ==> #(c a t)
vector?
(vector? #t) ;; ==> #f
(vector? (make-vector 3)) ;; ==> #t
(vector? (list->vector (list 1 2 3))) ;; ==> #t
write
;; Suppose that "my-port" is an output port associated with
;; file "MyFile.s".
(write (list 1 2 3) my-port) ;; Writes (1 2 3)
;; to "MyFile.s".
;; ==> #t
write-char
(with-output-to-file "Foo"
(lambda ()
(write-char #\a)
(write-char #\b)
(write-char #\c))) ;; ==> ;; Writes the text
;; "abc" to file "Foo".
#t
zero?
(zero? 1) ;; ==> #f
(zero 0) ;; ==> #t
(zero #i0) ;; ==> #t
Enhancement Procedures:
For General Use
Pixie Scheme III procedures whose names begin with "e::" are enhancements
that have received generally the same level of testing as those required
by the "R5" standard, and that have been written with the same degree of
care to avoid Pixie Scheme III crashing or hanging if they are misused.
e::active-room
(e::active-room) ;; ==> 567328 ;; e.g.
e::active-store-size
(e::active-store-size) ;; ==> 1052672 ;; E.g.
e::aging-room
(e::aging-room) ;; ==> 42 ;; e.g.
e::all?
(apply and <list>)
(e::all? '(1 2 3)) ;; ==> #t
(e::all? '(1 #f 3)) ;; ==> #f
(e::all? '()) ;; ==> #t (The empty list contains no element that is #f.)
e::any?
(apply or <list>)
(e::any? '(#f 1 #f)) ;; ==> #t
(e::any? '(#f #f #f)) ;; ==> #f
(e::any? '()) ;; ==> #f (The empty list contains no element that is not #f.)
e::atom?
(e::atom? #f) ;; ==> #t
(e::atom? (cons 1 2)) ;; ==> #f
e::bit-and  
e::bit-not  
e::bit-or  
e::bit-shift-left  
e::bit-shift-right-arithmetic  
e::bit-shift-right-logical  
e::bit-xor  
(e::bit-and #b1011 #b1101) ;; ==> 9 ;; Binary 1001
(e::bit-or #b1011 #b1101) ;; ==> 15 ;; Binary 1111
(e::bit-xor #b1011 #b1101) ;; ==> 6 ;; Binary 0110
(e::bit-not #b1011) ;; ==> -12
;; Binary 1111111111111111111111111111111111111111111111111111111111110100
(e::bit-shift-left #b1011 3) ;; ==> 88 ;; Binary 1011000
(e::bit-shift-right-logical -1 48) ;; ==> 32767 ;; Binary 111111111111111
(e::bit-shift-right-arithmetic -1 16) ;; ==> -1
;; -1 shifted right and padded with 1's
;; is still -1
e::bound-instance?
(e::bound-instance '+) ;; ==> #t
(e::bound-instance 'cons) ;; ==> #t
(define a 3) ;; ==> a
(e::bound-instance? 'a) ;; ==> #t
(e::bound-instance 'xglerb) ;; ==> #f ;; Unless you have
;; defined xglerb.
e::c-boolean->scheme-boolean?
(e::c-boolean->scheme-boolean 0) ;; ==> #f
(e::c-boolean->scheme-boolean 1) ;; ==> #t
(e::c-boolean->scheme-boolean -1) ;; ==> #t
(e::c-boolean->scheme-boolean 42) ;; ==> #t
e::clear-compiler-on!
(e::clear-compiler-on!) ;; ==> #t
e::clear-permanent!
(e::clear-permanent! 'cons) ;; ==> #t ;; DANGER WILL ROBINSON
e::clear-show-full-precision!
(e::clear-show-full-precision!) ;; ==> #t
e::closed-port?
(define foo (open-output-file "Whatever")) ;; ==> foo
(e::closed-port? foo) ;; ==> #f
(close-output-port foo) ;; ==> #t
(e::closed-port? foo) ;; ==> #t
e::coerce-to-long-ratnum-if-possible
(e::coerce-to-long-ratnum-if-possible 42) ;; ==> 42/1
(e::coerce-to-long-ratnum-if-possible 42.5) ;; ==> #i85/2
(e::coerce-to-long-ratnum-if-possible 3/2) ;; ==> 3/2
(e::coerce-to-long-ratnum-if-possible 1.e30) ;; ==> #f
e::coercible-to-fixnum?
(e::coercible-to-fixnum? 42) ;; ==> #t
(e::coercible-to-fixnum? 42.5) ;; ==> #f
(e::coercible-to-fixnum? 1.e30) ;; ==> #f
(e::coercible-to-fixnum? '()) ;; ==> #f
e::coercible-to-long-ratnum?
(e::coercible-to-long-ratnum? 42) ;; ==> #t
(e::coercible-to-long-ratnum? 42.5) ;; ==> #t
(e::coercible-to-long-ratnum? 1.e30) ;; ==> #f
(e::coercible-to-long-ratnum? '()) ;; ==> #f
e::compiler-on?
(e::set-compiler-on!) ;; ==> #t
(e::compiler-on?) ;; ==> #t
(e::clear-compiler-on!) ;; ==> #t
(e::compiler-on?) ;; ==> #f
e::compile-form
;; With the "Compile Defines" menu item disabled:
(define (increment x) (+ x 1)) ;; ==> increment
(e::inspect increment) ;; ==> ;; The hex numbers will vary
0004-1b8484cc: Lambda Pair -- Not a Car
(lambda (x) (+ x 1))
Lambda's non-top-level environments are:
...
-------- End of Environment List --------
#<Interpreted lambda expression>
;; Now compile it, and inspect again:
(define increment (e::compile-form increment)) ;; ==> increment
(e::inspect increment) ;; ==>
;; The hex numbers will vary
0004-1b8417c4: Lambda Pair -- Not a Car
(lambda (x) (#<Built-in procedure "+">
#<Ref to var 0 in environment 0 down> 1))
Lambda's non-top-level environments are:
...
-------- End of Environment List --------
#<Interpreted lambda expression>
e::cons-with-continuation
(e::cons-with-continuation <whatever>)
(eval <whatever> (interaction-environment))
(let ((x 3)) (e::cons-with-continuation 'x))
;; ==> <error>
x
Problem: No lexically visible binding of this symbol.
((c::lambda (g23008) (e::cons-with-continuation (quote x))) 3)
(define form-to-be-evaled
(list
'begin
(list 'display "Hello from the continuation!")
(list 'newline))) ;; ==> form-to-be-evaled
form-to-be-evaled ;; ==>
(begin
(display "Hello from the continuation!")
(newline))
(e::cons-with-continuation form-to-be-evaled) ;; ==>
Hello from the continuation!
#t
e::continued-fraction-list->real
(e::continued-fraction-list->real '(1 2)) ;; ==> 3/2
(e::continued-fraction-list->real '(0 1 1)) ;; ==> 1/2
(e::continued-fraction-list->real '(1 1 1 1 1 1 1 1 1 1 1 1)) ;; ==> 233/144
e::debug
e::deep-copy
(define (e::deep-copy x)
(cond
((pair? x) (cons (e::deep-copy (car x)) (e::deep-copy (cdr x))))
((vector? x) (list->vector (map e::deep-copy (vector->list x))))
((string? x) (string-copy x))
(#t x)))
(e::deep-copy (list 1 2 3)) ;; ==> (1 2 3)
e::define-no-compile
(e::define-no-compile (increment x) (+ x 1))
(e::define-no-compile
increment
(lambda (x) (+ x 1))) ;; ==> increment
(e::inspect increment) ;; The hexadecimal numbers may differ
0004-1b7bb660: Lambda Pair -- Not a Car
(lambda (x) (+ x 1)) ;; No variable substitution --
;; not compiled.
Lambda's non-top-level environments are:
...
-------- End of Environment List --------
#<Interpreted lambda expression>
e::derationalize
(e::derationalize 1/3) ;; ==> 0.33333333333333331
(e::derationalize 3.) ;; ==> 3.
e::entropy-death
(e::make-forgettable (cons 1 2) e::entropy-death 0.5)
;; ==> #
e::error
(e::error "Oops!!") ;; ==>
Problem: Oops!! (Resetting)
Top-level loop ...
e::error-port
;; You can write a procedure that displays error messages
;; at the console when normal output is being sent elsewhere.
(define (my-procedure)
...
(if <disaster>
(begin
(display
"My-procedure is going down in flames!\n"
(e::error-port))
(e::reset)))
...
) ;; ==> my-procedure
;; If disaster strikes the message
;; "My-procedure is going down in flames!"
;; will appear in the Pixie Scheme III window,
;; even if normal output goes somewhere else.
e::exit
(e::exit) ;; ==> ;; Pixie Scheme III exits.
e::expand-macro
(e::expand-macro
'(cond (#f 1) (#f 4) (#t 42) (else 'foo))) ;; ==>
;; Formatted for clarity: Note that the expansion of
;; the macro is not recursive -- the returned form
;; contains another instance of the "cond" macro.
(c::if #f
(begin 1)
(cond (#f 4) (#t 42) (else (quote foo))))
e::expand-macros-recursively
(e::expand-macros-recursively
'(cond (#f 1) (#f 4) (#t 42) else 'foo))
(e::expand-macros-recursively
(e::deep-copy
'(cond (#f 1) (#f 4) (#t 42) (else 'foo)))) ;; ==>
;; Formatted for clarity:
(c::if #f
1
(c::if #f
4
(c::if #t
42
(quote foo))))
e::fixnum?
(e::fixnum? #t) ;; ==> #f
(e::fixnum? 1) ;; ==> #t
(e::fixnum? 1.000) ;; ==> #t
(e::fixnum? 1.001) ;; ==> #f
(e::fixnum? (sqrt 4) ;; ==> #f
;; But note that
(integer? (sqrt 4)) ;; ==> #t
(e::fixnum? 1000000000000) ;; ==> #f
(integer? 1000000000000) ;; ==> #t
e::float?
(e::float? #t) ;; ==> #f
(e::float? 1) ;; ==> #f
(e::float? 1.000) ;; ==> #f
(e::float? 1.001) ;; ==> #t
(e::float? (sqrt 4) ;; ==> #t
;; But note that
(integer? (sqrt 4)) ;; ==> #t
(e::float? 1000000000000) ;; ==> #t
(integer? 1000000000000) ;; ==> #t
e::forced?
(define a (delay (+ 2 2))) ;; ==> a
(e::forced? a) ;; ==> #f
(force a) ;; ==> 4
(e::forced? a) ;; ==> #t
e::forgettable?
(e::forgettable? (e::make-forgettable #t 0 0)) ;; ==> #t
(e::forgettable? #t) ;; ==> #f
e::forgettable-expiration-time
(e::forgettable-expiration-time (e::make-forgettable "foo" 5000000000 0.6)) ;; ==>
#
e::forgettable-forgotten?
(define foo (e::forgettable-forgotten? (e::make-forgettable #t 0 0))) ;; ==> foo
(e::forgettable-forgotten? foo) ;; ==> #f
;; The forgettable object is created in the "unexpired" state;
;; it has not yet been forgotten, even though it is past its
;; expiration time and the probability of remembering is zero.
(e::full-gc) ;; During garbage collection, foo becomes expired.
(e::forgettable-forgotten? foo) ;; ==> #t
(e::forgettable-forgotten? #t) ;; ==> #f
e::forgettable-object
(e::forgettable-object (e::make-forgettable "foo" 5000000000 0.6)) ;; ==>
#
e::forgettable-remembered?
(define foo (e::forgettable-remembered? (e::make-forgettable #t 0 0))) ;; ==> foo
(e::forgettable-remembered? foo) ;; ==> #f
;; The forgettable object is created in the "unexpired" state;
;; it has not yet been remembered, even though it is past its
;; expiration time and the probability of remembering is one.
(e::full-gc) ;; During garbage collection, foo becomes expired.
(e::forgettable-remembered? foo) ;; ==> #t
(e::forgettable-remembered? #t) ;; ==> #f
e::forgettable-remember-probability
(e::forgettable-remember-probability (e::make-forgettable "foo" 5000000000 0.6)) ;; ==>
#
e::forgettable-unexpired?
(define foo (e::forgettable-unexpired? (e::make-forgettable #t 1000000000000 0))) ;; ==> foo
(e::forgettable-unexpired? foo) ;; ==> #t
;; The forgettable object is created in the "unexpired" state.
(e::full-gc) ;; The object will not expire until the distant future;
;; it remains unexpired after garbage collection.
(e::forgettable-unexpired? foo) ;; ==> #t
(e::forgettable-unexpired? #t) ;; ==> #f
e::full-gc
(e::full-gc) ;; Pixie Scheme III garbage collects.
;; ==> #t
e::gensym
(e::gensym) ;; ==> g23000
e::get-tag
(e::get-tag 42) ;; ==> 57 ;; #b111001
e::hide-sense-lights!
(e::hide-sense-lights!) ;; ==> #t, and makes the sense lights invisible.
e::inf?
(e::inf? #t) ;; ==> #f
(e::inf? 3) ;; ==> #f
(e::inf? 1.e10000) ;; ==> #t
(e::inf? 1+1.e1000i) ;; ==> #t
e::inspect
;; Hexadecimal output will vary ...
(e::inspect 42) ;; ==>
0039-0000002a: Exact Short Fixnum -- Not a Car
42
(e::inspect define) ;; ==>
(e::inspect define)
000a-1b7bfe34: Macro -- Not a Car
(lambda (form)
(c::if (list? form) ;; ... lots more output.
#<Macro>
e::list-print-depth
e::list-print-length
e::set-list-print-depth!
e::set-list-print-length!
e::set-vector-print-depth!
e::set-vector-print-length!
e::vector-print-depth
e::vector-print-length
list-print-depth
list-print-length
vector-print-depth
vector-print-length
(foo bar baz frob quux mumble ...)
(((((((...)))))))
(e::list-print-length) ;; ==> 20 ;; The default.
(list 1 2 3 4) ;; ==> (1 2 3 4)
(e::set-list-print-length! 3) ;; ==> #t
(list 1 2 3 4) ;; ==> (1 2 3 ...)
e::logic-constant?
(e::logic-constant? #t) ;; ==> #f
(e::logic-constant? #u) ;; ==> #t
(e::logic-constant? #s) ;; ==> #t
e::long-complex?
(e::long-complex? 1+i) ;; ==> #t
(e::long-complex? 3) ;; ==> #f
(e::long-complex? #t) ;; ==> #f
e::long-ratnum?
(e::long-ratnum? 1/3) ;; ==> #t
(e::long-ratnum? 3.2) ;; ==> #f
(e::long-ratnum? #t) ;; ==> #f
e::macro
;; Suppose you are tired of writing "set!" and would
;; rather write things like "(assign 3 to foo)".
;; Define this macro:
(e::macro
assign ;; The macro "name".
(lambda (form) ;; form is, e.g., "(assign 3 to foo)"
;; We build up the returned value from
;; a quasiquoted "set!" ...
`(set!
,(cadddr form) ;; The cadddr is, e.g., "foo".
,(cadr form)))) ;; The cadr is, e.g., "3".
;; ==> assign
;; Let's expand a call and see if it works:
(e::expand-macro '(assign 3 to foo))
;; ==> (set! foo 3)
;; Looks promising, let's try it. The
;; "set!" won't work unless "foo" is already
;; defined, so ...
(define foo 0) ;; ==> foo
foo ;; ==> 0
(assign 3 to foo) ;; ==> #t
foo ;; ==> 3 ;; Yippee!!
e::macro-body
;; Suppose you are tired of writing "set!" and would
;; rather write things like "(assign 3 to foo)".
;; Define this macro:
(define assign ;; The macro "name".
(e::macro-body
(lambda (form) ;; form is, e.g., "(assign 3 to foo)"
;; We build up the returned value from
;; a quasiquoted "set!" ...
`(set!
,(cadddr form) ;; The cadddr is, e.g., "foo".
,(cadr form))))) ;; The cadr is, e.g., "3".
;; ==> assign
;; Let's expand a call and see if it works:
(e::expand-macro '(assign 3 to foo))
;; ==> (set! foo 3)
;; Looks promising, let's try it. The
;; "set!" won't work unless "foo" is already
;; defined, so ...
(define foo 0) ;; ==> foo
foo ;; ==> 0
(assign 3 to foo) ;; ==> #t
foo ;; ==> 3 ;; Yippee!!
e::macro?
(e::macro? define) ;; ==> #t
(e::macro? cons) ;; ==> #f
e::make-forgettable
(e::make-forgettable (cons 1 2) 1247692518 0.75)
;; ==> #
e::make-integer-range
(e::make-integer-range 0 10 1) ;; ==> (0 1 2 3 4 5 6 7 8 9)
(e::make-integer-range 0 -10 -1) ;; ==> (0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
(e::make-integer-range 3 10 3) ;; ==> (3 6 9)
(e::make-integer-range 0 0 1) ;; ==> ()
(e::make-integer-range 0 10 -1) ;; ==> ()
e::make-long-ratnum
(e::make-long-ratnum 1 3) ;; ==> 1/3
(e::make-long-ratnum 1. 3) ;; ==> #i1/3
(e::make-long-ratnum 1 -3) ;; ==> -1/3
e::make-simple-class
(define baz (e::make-simple-class 'baz `(,bar) '((c 1)) '((a 1) (b 2))))
;; ==> baz
e::merge
(e::merge (list 1 3 5) (list 2 4) <) ;;==> (1 2 3 4 5)
(e::merge (list '(a 1) '(b 3) '(c 5)) (list '(d 2) '(e 4)) < cadr)
;;==> ((a 1) (d 2) (b 3) (e 4) (c 5))
e::merge!
(e::merge! (list 1 3 5) (list 2 4) <) ;;==> (1 2 3 4 5)
(e::merge! (list '(a 1) '(b 3) '(c 5)) (list '(d 2) '(e 4)) < cadr)
;;==> ((a 1) (d 2) (b 3) (e 4) (c 5))
e::money->string
(e::money->string 29.95) ;; ==> "29.95"
e::multiple-values?
(e::multiple-values? (values 1 2 3)) ;; ==> #t
(e::multiple-values? #t) ;; ==> #f
(e::multiple-values? 42) ;; ==> #f
e::nan?
(e::nan? #t) ;; ==> #f
(e::nan? 3) ;; ==> #f
(e::nan? (- 1.e10000 1.e10000)) ;; ==> #t ;; Two infs.
(e::nan? (- 1.e10000i 1.e10000i)) ;; ==> #t ;; Two infs.
e::ninety-percent-used?
(e::ninety-percent-used?) ;; ==> #f
e::non-printing-object?
(e::non-printing-object? #t) ;; ==> #f
(e::non-printing-object? #n) ;; ==> #t
e::not-null?
(e::not-null? #t) ;; ==> #t
(e::not-null? #f) ;; ==> #t
(e::not-null? '()) ;; ==> #f
e::number->string-with-n-decimals
(e::number->string-with-n-decimals 1/3 3)
;; ==> "0.333"
(e::number->string-with-n-decimals (- (/ 1000 3)) 6)
;; ==> "333.333333"
e::original-cwcc
See call-with-current-continuation for details.
e::perform-applicative
set!
set-car!
set-cdr!
string-fill!
string-set!
vector-fill!
vector-set!
e::clear-permanent!
e::set-list-print-depth!
e::set-list-print-length!
e::set-permanent!
e::set-tag!
e::set-vector-print-depth!
e::set-vector-print-length!
(e::perform-applicative (lambda () (+ 2 2))) ;; ==> 4
(define a 3)
(e::perform-applicative (lambda () (set! a 42)))
In built-in routine "set!":
Problem: Attempt to use a non-applicative procedure or special form during applicative programming.
Last lambda called (which may have returned) was recently named:
thunk
Recent names of non-tail-recursive stacked lambda expressions:
e::perform-applicative
(Resetting)
Top-level loop ...
e::permanent?
(e::clear-permanent! 'cons) ;; ==> #t
(e::permanent? 'cons) ;; ==> #f
(e::set-permanent! 'cons) ;; ==> #t
(e::permanent? 'cons) ;; ==> #t
e::promise?
(e::promise? '()) ;; ==> #f
(define a (delay (+ 2 2))) ;; ==> a
(e::promise? a) ;; ==> #t
(force a) ;; ==> 4
(e::promise? a) ;; ==> #t
e::random
(e::random) ;; ==> 2110915871 ;; Or whatever ...
e::read-string-with-prompt
(e::read-string-with-prompt "Give me a string!")
e::reduce
(e::reduce + (list 2 3 4 5) 42) ;; ==> 56
(e::reduce string-append (list "I" " " "see" " " "the" " " "cat" "."))
;; ==> "I see the cat."
e::real->continued-fraction-list
(e::real->continued-fraction-list 3/16) ;; ==> (0 5 3)
(e::real->continued-fraction-list 42.) ;; ==> (42.)
(e::real->continued-fraction-list #e3.1415926535897931)
;; ==> (3 7 15 1 292 1 1 1 2 1 3 1 14 3 3 2 1 3 3 7 2 1 1 3 2 42 2)
e::reset
(e::reset) ;; ==> ;; Pixie Scheme III resets.
e::room
(e::room) ;; ==> 104716012 ;; e.g.
e::rotate-sense-lights!
(e::set-sense-lights-off!)
(e::show-sense-lights!) ;; ==> All sense lights are visible and off.
(e::set-sense-light-n-illumination! 3 6) ;; ==> Fourth sense light from left is magenta.
(e::rotate-sense-lights! 1) ;; ==> Third sense light from left is magenta.
e::select
(lambda (element) (first-argument (third-argument element)))
(e::select positive? (list 1 -1 2 -2 3 4 5 -42 -88)) ;; ==> (1 2 3 4 5)
(e::select negative? (list 1 -1 2 -2 3 4 5 -42 -88)) ;; ==> (-1 -2 -42 -88)
(e::select positive? '((a 1) (b -1) (c 0) (d 2) (e -2) (f 3) (g -3) ) cadr)
;; ==> ((a 1) (d 2) (f 3))
e::sense-light-number?
(e::sense-light-number? -1) ;; ==> #f
(e::sense-light-number? 3) ;; ==> #t
(e::sense-light-number? #t) ;; ==> #f
e::sense-light-illumination-number?
(e::sense-light-illumination-number? -1) ;; ==> #f
(e::sense-light-illumination-number? 3) ;; ==> #t
(e::sense-light-illumination-number? #t) ;; ==> #f
e::set-sense-light-illuminations!
(e::set-sense-light-illuminations! 4) ;; ==> #t, and makes the sense lights green.
e::set-sense-light-n-illumination!
(e::set-sense-light-n-illumination! 1 6) ;; ==> #t, and makes sense light 1 magenta.
e::set-sense-light-n-visibility!
(e::set-sense-light-n-visibility! 1 #t) ;; ==> #t, and makes sense light 1 visible.
(e::set-sense-light-n-visibility! 5 #f) ;; ==> #t, and makes sense light 5 invisible.
e::set-sense-lights-off!
(e::set-sense-lights-off!) ;; ==> #t, and turns all the sense lights off.
e::set-compiler-on!
(e::set-compiler-on!) ;; ==> #t
e::set-forgettable-expiration-time!
;; Suppose foo is an unexpired forgettable object, and
;; suppose bar is a forgettable object that has expired.
(e::set-forgettable-expiration-time! foo 10000000000) ;; ==> #t
(e::set-forgettable-expiration-time! bar 10000000000) ;; ==> #f
e::set-forgettable-remember-probability!
;; Suppose foo is an unexpired forgettable object, and
;; suppose bar is a forgettable object that has expired.
(e::set-forgettable-remember-probability! foo 10000000000) ;; ==> #t
(e::set-forgettable-remember-probability! bar 10000000000) ;; ==> #f
e::set-permanent!
(e::clear-permanent! 'cons) ;; ==> #t ;; DANGER WILL ROBINSON
(e::set-permanent! 'cons) ;; ==> #t ;; That was close ...
e::set-show-full-precision!
(e::set-show-full-precision!) ;; ==> #t
e::set-tag!
;; As I write these words, the tag for a 64-bit
;; fixnum is 57. Let's see what happens if we
;; set the tag for a character to that value.
(e::get-tag #\a) ;; ==> 35
(e::set-tag #\a 57) ;; ==> 97 ;; Which is the integer
;; for ASCII 'a'.
e::show-active-memory
(e::show-active-memory) ;; ==> ;; Lots of output.
e::show-aging-memory
(e::show-aging-memory) ;; ==> ;; Lots of output.
e::show-dynamic-environment-list
(let ((x 3))
(let ((y 5))
((lambda (z) (e::show-dynamic-environment-list))
42)))
;; ==>
-------- Environment 0 of Environment List --------
z <- 42
-------- Environment 1 of Environment List --------
y <- 5
-------- Environment 2 of Environment List --------
x <- 3
-------- Environment 3 of Environment List --------
...
-------- End of Environment List --------
#t
e::show-environment
(let ((x 42)) (e::show-environment))
;; ==>
Current environment -- first of 2:
x <- 42
#t
e::show-environment-list
;; In my Pixie Scheme III environment, at present ...
(let ((x 42)) (e::show-environment-list))
;; ==>
-------- Environment 0 of Environment List --------
x <- 42
-------- Environment 1 of Environment List --------
cdddr <- #<Built-in procedure "cdddr">
string-ref <- #<Built-in procedure "string-ref">
e::error <- #<Interpreted lambda expression>
;; ... and lots more text.
e::show-full-precision?
(e::set-show-full-precision!) ;; ==> #t
(e::show-full-precision?) ;; ==> #t
1/3 ;; ==> 0.33333333333333331
(e::clear-show-full-precision!) ;; ==> #t
(e::show-full-precision?) ;; ==> #f
1/3 ;; ==> 0.3333333
e::show-locks
(e::show-locks) ;; ==> ;; e.g.,
*** Memory space descriptor at 153cc000, 364624 of 11534336 (hex b00000) bytes used.
space --> 153cc018, free -> 15e72fc8, lowFree -> 153cc018, end -> 15ecc018, inUse -> 1
15e92868 : 13012041-15e83248: String -- Cdr Next
15ec2630 : 13002041-15e80674: String -- Cdr Next
No ObList hash bins locked.
No TLE hash bins locked.
#t
e::show-memory
(e::show-memory) ;; ==> ;; Lots of output.
e::show-room
(e::show-room) ;; ==>
13503296 bytes free out of 14647296 (1144000 used) in main memory
0 bytes free out of 1052672 (1052672 used) in the aging memory generation
389904 bytes free out of 1052672 (662768 used) in the active memory generation
#t
e::show-sense-lights!
(e::show-sense-lights!) ;; ==> #t, and makes the sense lights visible.
e::sort
(e::sort (vector 2 3 1) <) ;;==> #(1 2 3)
(e::sort (list '(a 2) '(b 3) '(c 1)) < cadr)
;;==> ((c 1) (a 2) (b 3))
e::sort!
(e::sort! (vector 2 3 1) <) ;;==> #(1 2 3)
(e::sort! (vector '(a 2) '(b 3) '(c 1)) < cadr)
;;==> #((c 1) (a 2) (b 3))
e::sorted?
(e::sorted? (vector 1 2 3) <) ;;==> #t
(e::sorted? (list (c 1) (a 2) (b 3)) ;;==> #t
e::srandom
(e::srandom 42) ;; ==> #t
e::stack-depth
;; From the top-level loop:
(e::stack-depth) ;; ==> 6
e::store-size
(e::store-size) ;; ==> 104857600 ;; E.g.
e::substitute-new-permanent-symbols
(define (foo x) (+ x my-global)) ;; ==> foo
(define my-global 42) ;; ==> my-global
(e::set-permanent! 'my-global) ;; ==> #t
(e::inspect foo) ;; ==>
...
(lambda (x) (#<Built-in procedure "+">
my-global #<Ref to var 0 in environment 0 down>))
...
(e::substitute-new-permanent-symbols foo) ;; ==> ...
(e::inspect foo)
...
(lambda (x) (#<Built-in procedure "+">
42 #<Ref to var 0 in environment 0 down>))
...
e::time
(e::time) ;; ==> 1171525209 ;; Once upon a time.
e::top-loop-code
;; Here we are in the top-level loop.
;; Let's see how deep the run-time stack is.
(e::stack-depth) ;; ==> 5
;; Now, let's try that business about
;; consing with the continuation ...
(e::cons-with-continuation e::top-loop-code)
;; Nothing happened! Or so it seems ...
(+ 2 2) ;; ==> 4
(display "Hello, world\n") ;; ==>
Hello, world
#t
;; We are running a top-level loop.
;; We can enter Scheme commands
;; as long as we like. But it's
;; not *the* top-level loop. Look:
(e::stack-depth) ;; ==> 29
;; The top-level loop we have created
;; is running as an infinite loop
;; Within the "real" top-level loop,
;; which is lurking on the stack,
;; set to resume on a moment's notice.
;; We can get back to the first one
;; either by making an error or by
(e::reset) ;; ==>
Top-level loop ...
;; Do we believe it?
(e::stack-depth) ;; ==> 5
;; Might be so ...
e::usleep
(e::usleep 1000000) ;; Nothing happens
;; for about a second ...
;; ==> #t
e::version
(e::version) ;; ==>
"Pixie Scheme III Feb 14 2007 14:54:20"
e::warning
(e::warning "Oops!!") ;; ==>
Warning: Oops!! (Continuing) ...
e::write-continuation
;; In the top-level loop, the
;; continuation will be empty.
(e::write-continuation) ;; ==> ()#t
e::write-stack
(e::write-stack) ;; ==>
;; Lots of output.
Enhancement Procedures:
Use with CAUTION
Pixie Scheme III procedures whose names begin with "c::" are in some way
more dangerous or more risky than others; improper use of them may
cause Pixie Scheme III to hang or crash.
c::compiling?
;; With the "Compile Defines" menu item set:
(c::compiling?) ;; ==> #t
c::define
(c::define a 42) ;; ==> a
a ;; ==> 42
c::down-in-flames!!!
(c::down-in-flames!!!) ;; ==>
<Pixie Scheme III crashes> ;; Wasn't that fun?
c::environment
;; Called at top level:
(c::environment) ;; ==> ;; Lots of printout. The
;; top-level environment is
;; large.
(let ((x 3))
(c::environment)) ;; ==>
(((3 . x)) ;; followed by the large printout for the
;; top-level environment.
;; As I write these words, the full result of
(let ((x 3)) (c::environment))
;; starts out this way (with reformatting to fit
;; here neatly):
(((3 . x))
#(()
((#<Built-in procedure "cdddr"> . cdddr)
(#<Built-in procedure "string-ref"> . string-ref))
()
((#<Interpreted lambda expression> . e::error))
...
c::hash-string
(c::hash-string "abcd") ;; ==> 4994
c::load-from-string
(c::load-from-string "(+ 2 2 )") ;; ==> #t, and then
;; Pixie Scheme III prints "4".
c::number->string-with-c-format
snprintf( scratch, 256, <your number coerced to double>, <your format string>)
(c::number->string-with-c-format 1 "%.3f")
;; ==> "1.000"
(c::number->string-with-c-format 29.95 "For the low, low price of only $%.2f!!")
;; ==> "For the low, low price of only $29.95!!"
c::release-locks
(c::release-locks) ;; ==> ;; e.g.,
*** Memory space descriptor at 153cc000, 364760 of 11534336 (hex b00000) bytes used.
space --> 153cc018, free -> 15e72f40, lowFree -> 153cc018, end -> 15ecc018, inUse -> 1
15e92868 : 13012041-15e83248: String -- Cdr Next
15ec2630 : 13002041-15e80674: String -- Cdr Next
No ObList hash bins locked.
No TLE hash bins locked.
Releasing locks ...
15e92868 : 13012041-15e83248: String -- Cdr Next
... was locked, unlocks to:
15e92868 : 00002001-15e83248: String -- Cdr Next
15ec2630 : 13002041-15e80674: String -- Cdr Next
... was locked, unlocks to:
15ec2630 : 00002001-15e80674: String -- Cdr Next
No ObList hash bins locked.
No TLE hash bins locked.
#t
c::symeval
(c::symeval 'cons) ;; ==> #<Built-in procedure "cons">
(c::symeval 'not-bound) ;; ==> ;; error message:
not-bound
Problem: No lexically visible binding
of this symbol. (Resetting)
Top-level loop ...
(define not-bound 42) ;; ==> not-bound
(c::symeval 'not-bound) ;; ==> 42
Glossary:
Applicative Programming:
Atom:
Byte Block
False Boolean
True Boolean
Character
Scheme Machine PC
Peculiar Leaf
Stack Reference
Environment Reference
Top Level Environment Reference
Empty List
Fail
Succeed
Scheme Machine PC Index
Port
Forgettable Forgotten
Binding:
(define my-pair (cons 1 2))
;; Make a cons cell and bind it to a variable:
(define my-pair (cons 1 2)) ;; ==> my-pair
my-pair ;; ==> (1 . 2)
;; Make a copy of the binding; that is, of the pointer:
(define another-pair my-pair) ;; ==> another-pair
another-pair ;; ==> (1 . 2)
;; Change "another-pair" -- actually, change the
;; data pointed to:
(set-car! another-pair 42) ;; ==> #t
another-pair ;; ==> (42 . 2)
;; But "my-pair" has been changed as well, since
;; its pointer points to the data we just changed:
my-pair ;; ==> (42 . 2)
Bitwise Operations:
Bug:
Clarus the DogCow&trade:
Common Lisp:
Compiler:
Consing:
Continuation:
Debugging:
Environment:
;; The first three definitions result in bindings
;; in the top-level environment.
(define a 'a-from-top-level) ;; ==> a
(define b 'b-from-top-level) ;; ==> b
(define c 'c-from-top-level) ;; ==> c
(begin
(let
((a 'a-from-let) ;; These bindings are in an
(b 'b-from-let)) ;; environment created by the let.
;; Within the let, they override
;; the top-level bindings to a and b.
((lambda (a) ;; The lambda's formal argument
;; creates a new instance of variable
;; a, in the lambda's environment
;; environment. Within the lambda,
;; that instance's value or binding
;; will override the values and
; bindings of a in the let and at
;; top level.
(set! a 'a-from-lambda) ;; Change a in the lambda.
(display "In the lambda: ") ;; Print some output.
(display (list a b c))
(newline)
)
a) ;; Pass the value of a as seen by
;; the let, to the lambda, which
;; will bind that value to its own
;; "a", and then change it!
(display "In the let: ") ;; Print some output.
(display (list a b c))
(newline)
)
(display "In the begin: ") ;; Print some output.
(display (list a b c))
(newline)
)
;; ==>
In the lambda: (a-from-lambda b-from-let c-from-top-level)
In the let: (a-from-let b-from-let c-from-top-level)
In the begin: (a-from-top-level b-from-top-level c-from-top-level)
#t
Environment List:
Evaluation:
(define my-expression '(+ 2 2)) ;; ==> my-expression
my-expression ;; ==> (+ 2 2)
my-expression ;; ==> (a b c)
(define a 'a-from-top-level) ;; ==> a
(define b 'b-from-top-level) ;; ==> b
(define c 'c-from-top-level) ;; ==> c
;; Start with empty lists -- set! their
;; values later ...
(define top-level-list '()) ;; ==> top-level-list
(define let-list '()) ;; ==> let-list
(define lambda-list '()) ;; ==> lambda-list
(let
((a 'a-from-let)
(b 'b-from-let))
((lambda (a)
(set! a 'a-from-lambda)
(set! lambda-list '(list a b c))
)
a)
(set! let-list '(list a b c))
) ;; ==> #t
(set! top-level-list '(list a b c)) ;; ==> #t
top-level-list ;; ==> (list a b c)
let-list ;; ==> (list a b c)
lambda-list ;; ==> (list a b c)
(define eval e::cons-with-continuation) ;; ==> eval
(eval top-level-list)
;; ==> (a-from-top-level b-from-top-level c-from-top-level)
(eval let-list)
;; ==> (a-from-top-level b-from-top-level c-from-top-level)
(eval lambda-list)
;; ==> (a-from-top-level b-from-top-level c-from-top-level)
Functional Programming:
Garbage:
Garbage Collection:
Gensym:
Global Variable:
Inf:
Inspecting Scheme Objects:
Internal Definition:
Lexical Scope:
;; "a", "b", and "c" have bindings in the top-level
;; domain, which includes this code and lots more.
(define a 'a-from-top-level) ;; ==> a
(define b 'b-from-top-level) ;; ==> b
(define c 'c-from-top-level) ;; ==> c
;; Here come two local domains: There is a "let"
;; nested within the top-level domain, and a "lambda"
;; nested within the "let".
(let
((a 'a-from-let) ;; Here are bindings of "a " and
(b 'b-from-let)) ;; "b" that are local to the "let".
((lambda (a) ;; Lambda uses the symbol "a" in
;; its own domain ...
(set! a 'a-from-lambda)
)
3) ;; Lambda has no way to initialize
;; its "a" other than by the parameter
;; passed during a procedure call.
)
Local Variable:
MacLisp:
Macro:
Metasyntactic Variable:
(define (frob-with foo) ...)
Nan:
Numerical Accuracy:
Numerical Precision:
Ob-List:
Permanence:
Pixie:
Pixie Scheme:
Pixie Scheme II:
Procedure Application:
(foo bar baz frob mumble)
the first thing it does is evaluate "foo" -- recursively if necessary, for
instead of "foo" we might have another list to be evaluated, something like
((foo quux grundoon) bar baz frob mumble)
Scheme then decides what to do with the rest of the original list -- the
arguments -- based on what kind of thing the first item turned out to be,
upon evaluation. If it is a procedure, then all the arguments are evaluated,
each in turn, and the evaluated arguments are passed to the evaluated first
item; that is a procedure application. If the first item turns out to be
some other kind of entity, such as a macro or a special form, Scheme decides
on a case-by-case basis what to do with the rest of the arguments.
Referential Transparency:
(define (increment x) (+ x 1))
(define next-number 1)
(define (get-next-number)
(let ((return-value next-number))
(set! next-number (+ next-number 1))
return-value))
char-read
Reset:
R5 Report:
, edited by Richard Kelsey, William Clinger and Jonathan
Rees. It is the definitive standard for "R5" Scheme. As the name may
suggest, there have been, are, and no doubt will be, "RN" reports for
other values of N. An "R6" report has been released, but
Pixie Scheme III does not presently implement R6 Scheme.
SECD Machine:
Shadow:
Special Form:
Tagged Aval:
Tagged-Object Lisp:
Tail Call Optimization:
Tail Recursion:
(define (lnth l)
(if (null? l)
0
(+ 1 (lnth (cdr l)))))
(define (foo n)
...
(bar (- n 1))
)
(define (foo n)
(foo (- n 1))
)
(define (lnth-aux l n)
(if (null? l)
n
(lnth-aux (cdr l) (+ n 1)))
)
(define (lnth l) (lnth-aux l 0))
Transcript File:
World File:
Wraith Scheme:
Wraith: