This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Copies of the source code for this software may be downloaded from http://JayReynoldsFreeman.com/My/Software.html. If you cannot find that site or have difficulty using it, contact me by EMail at Jay_Reynolds_Freeman@mac.com.
A copy of the GNU General Public License is available while running the program, via menu item "Warranty and Redistribution" of the Wraith Scheme menu. You may also find the license on line at http://www.gnu.org/licenses.
The Wraith Scheme executable program itself is shareware: You are welcome to use Wraith Scheme for free, forever, and to pass out free copies of it to anybody else. If you would like to make a shareware donation for it, that's fine, and there is information in the program about how to go about it, but in no sense do I request, insist, or expect that you do so. Furthermore, Wraith Scheme is intended to be complete and fully functional as downloaded. There is nothing to buy, there are no activation codes required, and there are no annoying reminders about shareware donations.
This document has two parts:
The best ways to locate things in this document are probably either to scroll haphazardly, or to use your HTML browser's "find" command to search for the term, concept or identifier that you are interested in, or for some other likely word.
This portion of the document is a command summary of the procedures, special forms, macros, and the like, that are provided as part of Wraith Scheme. It includes all of the standard Scheme stuff that Wraith Scheme 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 Wraith Scheme. Wraith Scheme 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 Wraith Scheme does. For example, the R5 report often does not define the return values of procedures that are called for side effects: Wraith Scheme 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.
Wraith Scheme 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 Wraith Scheme.
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) ;; ==> inf (/ 2 0) ;; ==> inf (/ 2 3 4 0 5) ;; ==> inf (/ 0 0) ;; ==> nan
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:
Variables, one for each kitten.
Operation:
The operation of Wraith Scheme sets or binds these variables to the third most recent quantity whose value was printed out by the "print" part of the top-level read-eval-print loop of the kitten in question. That is, in kitten 0 for example, 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. These quantities are updated after the print has taken place; they may be used while Wraith Scheme is evaluating an expression in the "read" part of the read-eval-print loop. They form part of a rudimentary command-history mechanism that is contained within Wraith Scheme.
Each of these variables may be read by any Wraith Scheme process, not just the one in whose top-level loop it is bound.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
;; In kitten 0: (+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >***< ;; has the value 1.
Type:
Variables, one for each kitten.
Operation:
The operation of Wraith Scheme sets or binds these variables to the next-to-last quantity whose value was printed out by the "print" part of the top-level read-eval-print loop of the kitten in question. That is, in kitten 0 for example, the variable is the previous value of >*<, which is the most recent quantity printed out by the read-eval-print loop. These quantities are updated after the print has taken place; they may be used while Wraith Scheme is evaluating an expression in the "read" part of the read-eval-print loop. They form part of a rudimentary command-history mechanism that is contained within Wraith Scheme.
Each of these variables may be read by any Wraith Scheme process, not just the one in whose top-level loop it is bound.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
;; In kitten 0: (+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >**< ;; has the value 2.
Type:
Variables, one for each kitten.
Operation:
The operation of Wraith Scheme sets or binds these variables to the last quantity whose value was printed out by the "print" part of the top-level read-eval-print loop of the kitten in question. These quantities are updated after the print has taken place; they may be used while Wraith Scheme is evaluating an expression in the "read" part of the read-eval-print loop. They form part of a rudimentary command-history mechanism that is contained within Wraith Scheme.
Each of these variables may be read by any Wraith Scheme process, not just the one in whose top-level loop it is bound.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
;; In kitten 0: (+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, and continuing through the ;; evaluation of the next Scheme expression, >*< ;; has the value 3.
Type:
Variables, one for each kitten.
Operation:
The operation of Wraith Scheme sets or binds these 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 of the kitten in question. That is, in kitten 0 for example, 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. These quantities are updated after the print has taken place; they may be used while Wraith Scheme is evaluating an expression in the "read" part of the read-eval-print loop. They form part of a rudimentary command-history mechanism that is contained within Wraith Scheme.
Each of these variables may be read by any Wraith Scheme process, not just the one in whose top-level loop it is bound.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
;; In kitten 0: (+ 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:
Variables, one for each kitten.
Operation:
The operation of Wraith Scheme sets or binds these 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 of the kitten in question. That is, in kitten 0 for example, the variable is the previous value of >+<, which is the most recent quantity provided as input to the read-eval-print loop. These quantities are updated after the print has taken place; they may be used while Wraith Scheme is evaluating an expression in the "read" part of the read-eval-print loop. They form part of a rudimentary command-history mechanism that is contained within Wraith Scheme.
Each of these variables may be read by any Wraith Scheme process, not just the one in whose top-level loop it is bound.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
;; In kitten 0: (+ 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:
Variables, one for each kitten.
Operation:
The operation of Wraith Scheme sets or binds these variables to the last Scheme expression that was passed as input to the "read" part of the top-level read-eval-print loop of the kitten in question. These quantities are updated after the print has taken place; they may be used while Wraith Scheme is evaluating an expression in the "read" part of the read-eval-print loop. They form part of a rudimentary command-history mechanism that is contained within Wraith Scheme.
Each of these variables may be read by any Wraith Scheme process, not just the one in whose top-level loop it is bound.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
;; In kitten 0: (+ 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:
Variables, one for each kitten.
Operation:
While Wraith Scheme is evaluating a Scheme expression that was provided as input to the "read" part of the top-level read-eval-print loop of kitten 0, for example, ">-<" is bound to that expression itself. This value will become the value of ">+<" after the expression has been evaluated and its result printed.
Each of these variables may be read by any Wraith Scheme process, not just the one in whose top-level loop it is bound.
Arguments:
(Does not apply.)
Side Effects:
(Does not apply.)
Returned Value:
(Does not apply.)
For Example:
;; In kitten 0: (+ 0 1) (+ 0 2) (+ 0 3) ;; At this point, the value of >-< is undefined. ;; But suppose you type (define a >-<) ;; and then type return. Then, while the "define" ;; is being evaluated, >-< will have the value ;; (define a >-<), so when you subsequently ;; enter a ;; Wraith Scheme will print (define a >-<) Note that if you had entered ">+<" before typing a, you would have found that at that time, it too would have had the value (define a >-<).
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:
(abs 3) ;; ==> 3 (abs -3) ;; ==> 3
Type:
Procedure.
Operation:
Mathematical inverse cosine, or arc-cosine, function.
Arguments:
One number.
Side Effects:
None.
Returned Value:
A number: A complex number whose cosine is the argument. For a real argument, the returned value will be in the range [0, pi].
For Example:
(acos 1) ;; ==> 0 (acos 0) ;; ==> 1.5707963267948966 (acos -1) ;; ==> 3.1415926535897931 (acos +i) ;; ==> 1.5707963267948966-0.8813735870195428i
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:
(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".
Type:
Procedure.
Operation:
Obtain the angle of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The angle of the number.
For Example:
(angle 1) ;; ==> 0 (angle -1) ;; ==> 3.1415926535897931 (angle +i) ;; ==> 1.5707963267948966 (angle -i) ;; ==> -1.5707963267948966
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:
(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.
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:
(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)
Type:
Procedure.
Operation:
Mathematical inverse sine, or arc-sine, function.
Arguments:
One number.
Side Effects:
None.
Returned Value:
A number: A number: A complex number whose sine is the argument. For a real argument, the returned value will be in the range [-pi/2, pi/2].
For Example:
(asin 1) ;; ==> 1.5707963267948966 (asin 0) ;; ==> 0 (asin -1) ;; ==> -1.5707963267948966 (asin +i) ;; ==> 0.8813735870195428i
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:
(assoc 1 '((1 2) (3 4))) ;; ==> (1 2) (assoc 3 '((1 2) (3 4))) ;; ==> (3 4) (assoc 42 '((1 2) (3 4))) ;; ==> #f
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:
(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.
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:
(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)
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 number or two real numbers.
Side Effects:
None.
Returned Value:
With one argument, the returned value is a complex number whose tangent is the argument.
If that argument is real, returns a number in the range [-pi/2, pi/2].
With two real arguments, 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:
(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
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:
(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
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:
(boolean? #t) ;; ==> #t (boolean? #f) ;; ==> #t (boolean? 'whatever) ;; ==> #f
Type:
Procedure.
Note that call/cc is a synonym for this 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.
(call-with-current-continuation procedure?) ;; ==> #t
The second example is from the "R5" report. Let's discuss it in detail.
(call-with-current-continuation (lambda (exit) (for-each (lambda (x) (if (negative? x) (exit x))) '(54 0 37 -3 245 19)) #t)) ;; ==> -3
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:
Open a port to an input file and call a procedure with that port as argument.
Arguments:
One or two arguments. The last should be a procedure that takes one argument. The first, if present, should be a string naming a file. If there is only one argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain the name of the file.
Side Effects:
None.
Returned Value:
Any Scheme object, or may not return: The called procedure need not return, but if it does, "call-with-input-file" will returns whatever the procedure returns.
For Example:
(call-with-input-file "foo" read-char) ;; ==> Read and returns one character from "foo". (call-with-input-file (lamdba(port) (read-char port))) ;; ==> Read and return one character from a file pathname obtained from the user via the Wraith Scheme Dialog Panel
Type:
Procedure.
Operation:
Open a port to an output file and call a procedure with that port as argument.
Arguments:
One or two arguments. The last should be a procedure that takes one argument. The first, if present, should be a string naming a file. If there is only one argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain the name of the file.
Side Effects:
None.
Returned Value:
Any Scheme object, or may not return: The called procedure need not return, but if it does, "call-with-output-file" will return whatever the procedure returns.
For Example:
(call-with-output-file "foo" (lambda(port) (write 1 port)) ;; ==> Write "1" to "foo" and return #t. (call-with-output-file (lambda(port) (write 1 port)) ;; ==> Write "1" to a file whose pathname will be obtained from the user via the Wraith Scheme Dialog Panel
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:
;; 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
Type:
Procedure.
This procedure is a synonym for call-with-current-continuation, which see.
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:
(car '(1 2)) ;; ==> 1 (car '(1 . 2)) ;; ==> 1 (car '(1)) ;; ==> 1 (car (list 1 2 3 4 5 6)) ;; ==> 1
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:
(cdr '(1 2)) ;; ==> (2) (cdr '(1 . 2)) ;; ==> 2 (cdr '(1)) ;; ==> () (cdr (list 1 2 3 4 5 6)) ;; ==> (2 3 4 5 6)
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
cadar
becomes
c a d a r
which becomes
a d a
which becomes
the car of the cdr of the car of
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:
(cadar x)
becomes
(c a d a r x)
which becomes
(a d a x)
which becomes
(car cdr car x)
which becomes
(car (cdr (car x)))
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:
(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
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:
(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
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:
(ceiling -6.5) ;; ==> -6. (ceiling 4) ;; ==> 4
Type:
Procedure.
Operation:
Convert a character to the integer that represents it; Wraith Scheme 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:
(char->integer #\C) ;; ==> 67 (char->integer #\newline) ;; ==> 10
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:
(char-alphabetic? #\a) ;; ==> #t (char-alphabetic? #\!) ;; ==> #f
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. Wraith Scheme 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:
(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
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is less than the integer representation of the second. Wraith Scheme 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:
(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
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is equal to the integer representation of the second. Wraith Scheme 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:
(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
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. Wraith Scheme 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:
(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
Type:
Procedure.
Operation:
Case-independently test the whether the integer representation of the first argument is greater than the integer representation of the second. Wraith Scheme 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:
(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
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:
(char-downcase #\A) ;; ==> #\a (char-downcase #\a) ;; ==> #\a (char-downcase #\!) ;; ==> #\!
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:
(char-lower-case? #\a) ;; ==> #t (char-lower-case? #\A) ;; ==> #f (char-lower-case? #\!) ;; ==> <error>
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:
(char-numeric? #\3) ;; ==> #t (char-numeric? #\a) ;; ==> #f
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:
;; From the console, at top-level: (char-ready?) ;; ==> #t ;; The character is the "return" ;; that sent the text ;; "(char-ready?)" ;; to Wraith Scheme. (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 Wraith Scheme ;; 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 ...
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:
(char-upcase #\A) ;; ==> #\A (char-upcase #\a) ;; ==> #\A (char-upcase #\!) ;; ==> #\!
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:
(char-upper-case? #\a) ;; ==> #f (char-upper-case? #\A) ;; ==> #t (char-upper-case? #\!) ;; ==> <error>
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:
(char-whitespace? #\a) ;; ==> #f (char-whitespace? #\space) ;; ==> #t
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:
(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
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:
(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
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:
(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
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:
(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
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:
(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
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:
(char? #\a) ;; ==> #t (char? #\!) ;; ==> #t (char? 42) ;; ==> #f
Type:
Procedure.
Operation:
Close an input port.
Arguments:
One input port.
Side Effects:
If the argument is an open port, closes it.
Returned Value:
#t
For Example:
;; Suppose "foo" is the path to a readable file (define foo-port (open-input-file "foo")) ;; ==> foo-port (close-input-port foo-port) ;; ==> #t
Type:
Procedure.
Operation:
Close an output port.
Arguments:
One output port.
Side Effects:
If the argument is an open port, closes it.
Returned Value:
#t
For Example:
(define foo-port (open-output-file "foo")) ;; ==> foo-port (close-output-port foo-port) ;; ==> #t
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. Many of Wraith Scheme's numbers lie on the real axis, but they are nonetheless in the complex plane.
For Example:
(complex? 0) ;; ==> #t (complex? (expt 10 1000000)) ;; ==> #f ;; It's an inf. (complex? #t) ;; ==> #f
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:
(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
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:
(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)
Type:
Procedure.
Operation:
Mathematical cosine.
Arguments:
One number. Real numbers are taken to be angles in radians.
Side Effects:
None.
Returned Value:
A number: The cosine of the argument.
For Example:
(cos 0) ;; ==> 1 (cos 1.5707963267948966) ;; ==> 6.123031769111886e-17 ;; Very nearly zero. (cos 0.7853981633974483) ;; ==> 0.7071067811865476 (cos +i) ;; ==> 1.5430806348152437
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:
;; When input is being taken from the keyboard: (current-input-port) ;; ==> #<Console Input Port>
Type:
Procedure.
Operation:
Returns the port to which output is presently being sent.
Arguments:
None.
Side Effects:
None.
Returned Value:
A port: The port to which output is presently being sent.
For Example:
;; When output is being sent to the Wraith Scheme window: (current-output-port) ;; ==> #<Console Output Port>
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
(define (name var1 var2 ... varN) expression1 expression2 ... expressionN )
is equivalent to
(define name (lambda (var1 var2 ... varN) expression1 expression2 ... expressionN ) )
Third Syntax: The third 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
(define (name var1 var2 ... varN-1 . varN) expression1 expression2 ... expressionN )
is equivalent to
(define name (lambda (var1 var2 ... varN-1 . varN) expression1 expression2 ... expressionN ) )and
(define (name . var) expression1 expression2 ... expressionN )
is equivalent to
(define name (lambda var expression1 expression2 ... expressionN ) )
Returned Value:
First syntax: the first argument.
Second and third syntaxes: the first element of the first argument.
For Example:
(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
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:
(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
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:
;; Note how Wraith Scheme displays a promise: (delay (display "Carpe diem\n")) ;; ==> #<Promise> (define foo (delay (begin (display "Carpe diem\n") 123))) ;; ==> foo foo ;; ==> #<Promise> (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 foo ;; ==> #<Promise>
Type:
Procedure.
Operation:
Obtain the denominator of a rational number, having first expressed the number as a fraction in lowest terms, with a positive denominator.
Arguments:
One rational number.
Side Effects:
None.
Returned Value:
The denominator of the argument, which is taken to be a fraction expressed in lowest terms, with a positive denominator. The denominator of zero is taken to be one.
For Example:
(denominator 2/3) ;; ==> 3 (denominator -4/6) ;; ==> 3 (denominator 0) ;; ==> 1 (denominator 0.1) ;; ==> 36028797018963968.
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:
(display "This string\nhas three\nembedded newlines.\n") ;; ==> This string has three embedded newlines. #t (display 5/7) ;; ==> 5/7 (let ((my-port (open-output-file "Foo"))) (display 5/7 my-port) (close-output-port my-port)) ;; ==> #t ;; And writes to "Foo".
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: Wraith Scheme's implementation of "do" is slow, and uses lots of memory.
Technical Note: Wraith Scheme 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 Wraith Scheme'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:
(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)
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:
(define (foo) (display "Entering - ")) ;; ==> foo (define (bar) (display "\"bar\"")) ;; ==> bar (define (baz) (display " - leaving\n")) ;; ==> baz (bar) ;; ==> "bar" (dynamic-wind foo bar baz) ;; ==> Entering - "bar" - leaving (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)
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:
See "cond".
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:
;; Suppose foo is an input port to a file containing ;; three characters, and that Wraith Scheme has already ;; read those characters. (eof-object? (read-char foo)) ;; ==> #t (eof-object? 42) ;; ==> #f
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 Wraith Scheme 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:
(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.
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:
(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.
Type:
Procedure.
Operation:
Test whether two Scheme objects should "normally be regarded as the same object" (according to the R5 report). What Wraith Scheme 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. Wraith Scheme 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:
(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
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-report-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:
(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
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:
(even? 42) ;; ==> #t (even? 137) ;; ==> #f
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:
(exact->inexact 1) ;; ==> 1. (exact->inexact #i1) ;; ==> 1. (exact->inexact +i) ;; ==> 1.i
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:
(exact? 1) ;; ==> #t (exact? 1.) ;; ==> #f
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:
(exp 0) ;; ==> 1 (exp 1) ;; ==> 2.7182818284590451 (exp -2.5) ;; ==> 0.0820849986238988 (exp 3.1415926535897931i) ;; ==> -1.+1.2246467991473532e-16i
Type:
Procedure.
Operation:
Raise a number to a power.
Arguments:
Two numbers.
Side Effects:
None.
Returned Value:
The first argument raised to the second argument.
For Example:
(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
Type:
Procedure.
Operation:
Arithmetic round down.
Arguments:
One real number.
Side Effects:
None.
Returned Value:
An integer: The greatest integer not greater than the argument.
For Example:
(floor -6.5) ;; ==> -7. (floor 4) ;; ==> 4
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:
(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
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:
;; Note how Wraith Scheme 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
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 arguments.
For Example:
(gcd 28 98) ;; ==> 14 (gcd 999999999999 209457) ;; ==> 333 (gcd 34 85 68) ;; ==> 17
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:
(if #t (+ 1 2) (+ 3 4)) ;; ==> 3 (if #f (+ 1 2) (+ 3 4)) ;; ==> 7 (if #f (+ 1 2)) ;; ==> #f
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:
(imag-part 1) ;; ==> 0 (imag-part +i) ;; ==> 1 (imag-part 1.+i) ;; ==> 1.
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:
(inexact->exact 1) ;; ==> 1 (inexact->exact #i1) ;; ==> 1 (inexact->exact 1.i) ;; ==> +i
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:
(inexact? 1) ;; ==> #f (inexact? 1.) ;; ==> #t
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:
(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
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:
(integer->char 65) ;; ==> #\A (integer->char 128) ;; ==> <error>
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:
(integer? 3) ;; ==> #t (integer? 3.1) ;; ==> #f ;; Technically, an integer is a real number with no fractional ;; part. The floating-point representations used by Wraith ;; Scheme 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 Wraith Scheme (/ 1.e100 3) ;; ==> 3.3333333333333332e99 ;; which is 33333333333333332 followed by lots of zeros -- ;; unarguably the external representation of an integer.
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 Wraith Scheme.
For Example:
(eval '(+ 2 2) (interaction-environment)) 4
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:
(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
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:
(lcm 24 60) ;; ==> 120 (lcm 99 88) ;; ==> 792 (lcm 4 5 6) ;; ==> 60
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:
(length (list 'a 'b 'c)) ;; ==> 3 (length '()) ;; ==> 0 (length '(1 2 . 3)) ;; ==> <error>
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:
(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.
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:
(let ((x 'outer)) (let-syntax ((m (syntax-rules () ((m) x)))) (let ((x 'inner)) (m)))) ;; ==> outer
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:
(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.
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*".
Wraith Scheme does NOT report an error if the local variables of a letrec are used in such a way that the initialization expressions are undefined or unbound: The R5 report merely states that such pre-initialization values are undefined. That may be confusing at times. Thus the example used for let and let* gives the following result for letrec:
(define a 'aa) ;; ==> a (define b 'bb) ;; ==> b (define c 'cc) ;; ==> c (letrec ((a c) ;; Local a wants to get the local value of c, which has no local binding. (b a) ;; Local b wants to get the local value of a, which has no local binding. (c b)) ;; Local c wants to get the local value of b, which has no local binding. (list a b c)) ;; ==> (c c c) ;; The "undefined" values turn out to be the symbols provided.
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:
(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
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".
Wraith Scheme 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: Wraith Scheme 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:
(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 ...))))))) (display (my-or #f #f #t)) (newline) (my-or)) ;; ==> #t ;; #f
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:
(list) ;; ==> () (list 1 2 3) ;; ==> (1 2 3)
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:
(list->string '()) ;; ==> "" (list->string '(#\C #\a #\t)) ;; ==> "Cat"
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:
(list->vector '()) ;; ==> #() (list->vector (list 1 (list 2 3 4) (* 6 7) "Foo")) ;; ==> #(1 (2 3 4) 42 "Foo")
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:
(list-ref '(1 2 3) 0) ;; ==> 1 (list-ref '(1 2 3) 1) ;; ==> 2 (list-ref '(1 2 3) 2) ;; ==> 3
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:
(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) ;; ==> ()
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:
(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
Type:
Procedure.
Operation:
Load a file, and process its contents as if they had been entered at the keyboard. Wraith Scheme prints the results of any such evaluation, but not the literal text of the file itself.
The operation of load is weird, almost by definition: The R5 report states that this procedure "reads expressions and definitions from the file and evaluates them sequentially", but it does not specify what environment they are to be evaluated in. It would be most natural and most straightforward to implement, if "load" evaluated what it read in the same environment in which the load procedure itself was called, which may be within a procedure. Unfortunately, the idea of loading code into the temporary environment for a particular procedure call is very odd; it amounts more or less to changing the source code of the procedure for just that one call.
Having that evaluation take place in the interaction environment is probably a great deal more useful; for then one may more easily use procedures for such purposes as building up the path to the file to be loaded. Such an interpretation does not quite fly in the face of lexical scoping, for there is already one Scheme function -- eval -- that is prepared to evaluate things in a different environment from the one in which it was called.
Wraith Scheme presently loads into the interaction environment.
Arguments:
At most one: If an argument is present, it must be a string containing a Unix-style path to the file to be loaded. If no argument is present, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain such a path from the user.
Side Effects:
Depends on the arguments.
Returned Value:
#t
For Example:
(load "/Users/MyName/MyFavoriteSchemeCode.s") ;; loads file ;; ==> #t (load) ;; Wraith Scheme Dialog Panel prompts for pathname.
Type:
Procedure.
Operation:
Mathematical natural logarithm.
Arguments:
One number.
Side Effects:
None.
Returned Value:
A number: Returns the natural logarithm of the argument.
For Example:
(log 1) ;; ==> 0 (log 2.7182818284590451) ;; ==> 1. (log (/ 2.7182818284590451)) ;; ==> -1. (log -1) ;; ==> 3.1415926535897931i
Type:
Procedure.
Operation:
Obtain the magnitude of a number.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The magnitude of the number.
For Example:
(magnitude 1) ;; ==> 1 (magnitude -1) ;; ==> 1 (magnitude +i) ;; ==> 1 (magnitude 1.+i) ;; ==> 1.4142135623730951
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:
(make-polar 1 0) ;; ==> 1 (make-polar -1 0) ;; ==> -1 (make-polar 1 1.5707963267948966) ;; ==> 6.123233995736766e-17+1.i
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:
(make-rectangular 1 1) ;; ==> 1+i (make-rectangular 0 1) ;; ==> +i (make-rectangular 1 0) ;; ==> 1
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 Wraith Scheme Dialog Panel. Enclosing double-quotes are not required in this case.
For Example:
(make-string 0) ;; ==> "" (make-string 3) ;; ==> " " (make-string 3 #\q) ;; ==> "qqq" (make-string) ;; Wraith Scheme prompts the user to ;; type in a string.
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:
(make-vector 0) ;; ==> #() (make-vector 3) ;; ==> #(() () ()) (make-vector 3 (list 1 2)) ;; ==> #((1 2) (1 2) (1 2))
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:
(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)
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:
(max -17 23 -102.5 9) ;; ==> 23
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:
(member 2 (list 1 2 3)) ;; ==> (2 3) (member 'b '(a b c)) ;; ==> (b c) (member (list 'a) '(b (a) c)) ;; ==> ((a) c)
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:
(memq 2 (list 1 2 3)) ;; ==> (2 3) (memq 'b '(a b c)) ;; ==> (b c) (memq (list 'a) '(b (a) c)) ;; ==> #f
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:
(memv 2 (list 1 2 3)) ;; ==> (2 3) (memv 'b '(a b c)) ;; ==> (b c) (memv (list 'a) '(b (a) c)) ;; ==> #f
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:
(min -17 23 -102.5 9) ;; ==> -102.5
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:
(modulo 13 4) ;; ==> 1 (modulo -13 4) ;; ==> 3 (modulo 13 -4) ;; ==> -3 (modulo -13 -4) ;; ==> -1
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:
(negative? 0) ;; ==> #f (negative? 1) ;; ==> #f (negative? -1) ;; ==> #t
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:
(newline) ;; ==> ;; Just wrote a newline. ;; Suppose "foo" is an output port: (newline foo) ;; ==> #t ;; Wrote a newline to foo
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:
(not #f) ;; ==> #t (not 42) ;; ==> #f (not '()) ;; ==> #f
Type:
Procedure.
Operation:
Return a Scheme environment which is supposed to contain only the syntactic keywords of Scheme, but which in Wraith Scheme contains a few more bindings.
Arguments:
One, which must be the exact integer 5.
Side Effects:
None.
Returned Value:
The null environment of Wraith Scheme, which contains bindings for the following symbols:
=> 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
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:
(eval '(if #t 2 3) (null-environment 5)) 2
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:
(null? #f) ;; ==> #f (null? 42) ;; ==> #f (null? '()) ;; ==> #t
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. This procedure cannot display a quantity that is not an exact integer with using radix other than 10. Thus rationals that are not exact integers as well as complex numbers with real or imaginary parts that are not exact integers, cannot be displayed using radices 2, 8 or 16.
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:
(number->string 10) ;; ==> "10" (number->string 10 2) ;; ==> "1010" (number->string 10 8) ;; ==> "12" (number->string 10 16) ;; ==> "a" (number->string 5/3) ;; ==> "5/3" (number->string 15+14i) ;; ==> "15+14i" (number->string 15+14i 8) ;; ==> "17+16i" (number->string 15+14i) ;; ==> "15+14i" (number->string 15.5+14i 8) ;; ==> <error>
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. Wraith Scheme considers nans and infs not to be numbers.
For Example:
(number? 'foo) ;; ==> #f (number? 1.234) ;; ==> #t (number? 1e10000) ;; ==> #f ;; inf (number? (/ 1e10000 1e10000)) ;; ==> #f ;; nan
Type:
Procedure.
Operation:
Obtain the numerator of a rational number, having first expressed the number as a fraction in lowest terms, with a positive denominator.
Arguments:
One rational number.
Side Effects:
None.
Returned Value:
The numerator of the argument, which is taken to be a fraction expressed in lowest terms, with a positive denominator.
For Example:
(numerator 2/3) ;; ==> 2 (numerator -4/6) ;; ==> -2 (numerator 0) ;; ==> 0 (numerator 0.1) ;; ==> 3602879701896397.
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:
(odd? 42) ;; ==> #f (odd? 137) ;; ==> #t
Type:
Procedure.
Operation:
Open a port to a file for input.
Arguments:
At most one: If present, a string containing a Unix-style path to the file to be opened. If there is no argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain a path from the user.
Side Effects:
Opens a port.
Returned Value:
An input port.
For Example:
(open-input-file "/Users/Me/MySourceFile.s") ;; ==> <Input Port ... > ;; The text will describe the port (open-input-file) ;; Wraith Scheme will use the Dialog Panel ;; to obtain the path to the file.
Type:
Procedure.
Operation:
Open a port to a file for output.
Arguments:
At most one: If present, a string containing a Unix-style path to the file to be opened. If there is no argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain a path from the user.
Side Effects:
Opens a port.
Returned Value:
An output port.
For Example:
(open-output-file "/Users/Me/MyOutputFile.text") ;; ==> <Output Port ... > ;; The text will describe the port (open-output-file) ;; Wraith Scheme will use the Dialog Panel ;; to obtain the path to the file.
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:
(or) ;; ==> #f (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".
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:
(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
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:
(pair? '(1 . 2)) ;; ==> #t (pair? (list 1 2)) ;; ==> #t (pair? '()) ;; ==> #f (pair? 42) ;; ==> #f
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:
;; 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>
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:
(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
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:
(positive? 0) ;; ==> #f (positive? 1) ;; ==> #t (positive? -1) ;; ==> #f
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:
(procedure? +) ;; ==> #t (procedure? (lambda (x) (+ x 1))) ;; ==> #t (procedure? lambda) ;; ==> #f (procedure? let) ;; ==> #f
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:
(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)
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:
(quote foo) ;; ==> foo 'foo ;; ==> foo (quote (+ 2 2)) ;; ==> (+ 2 2) '(+ 2 2) ;; ==> (+ 2 2)
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:
(quotient 13 4) ;; ==> 3 (quotient -13 4) ;; ==> -3 (quotient 13 -4) ;; ==> -3 (quotient -13 -4) ;; ==> 3
Type:
Procedure.
Operation:
Obtain the simplest rational number differing from the first argument by no more than the second argument. One rational is simpler than another if, when both are expressed in lowest terms, the absolute value of the numerator of the first is less than or equal to the absolute value of the numerator of the second and the absolute value of the denominator of the first is less than or equal to the absolute value of the denominator of the second, and at least one of the inequalities is strict.
Arguments:
Two real numbers.
Side Effects:
None.
Returned Value:
The simplest rational number differing from the first argument by no more than the second argument. Wraith Scheme may not be able to express the returned value as a fraction, because of the limited range of 64-bit integers.
For Example:
(rationalize .3 1/10) ;; ==> #i1/3 (rationalize .3 1/1000) ;; ==> #i3/10 (rationalize .3 0) ;; ==> #i5404319552844595/18014398509481984 (rationalize 3/10 0) ;; ==> 3/10 (rationalize .3e200 0) ;; ==> 3.0000000000000001e199
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:
(rational? #t) ;; ==> #f (rational? 1) ;; ==> #t (rational? 1.5) ;; ==> #t (rational? (sqrt 2)) ;; ==> #t (rational? +i) ;; ==> #f (rational? (/ 1 0)) ;; ==> #f (It's an inf.) (rational? (/ 0 0)) ;; ==> #f (It's a nan.) ;; Note that in Wraith Scheme (sqrt 2) ;; ==> 1.4142135623730951 ;; which is 14142135623730951/10000000000000000 ;; and thus is rational.
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:
;; 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>
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:
;; 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>
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:
(real-part 1) ;; ==> 1 (real-part +i) ;; ==> 0 (real-part 1.+i) ;; ==> 1.
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:
(real? #t) ;; ==> #f (real? 1) ;; ==> #t (real? 1.5) ;; ==> #t (real? (sqrt 2)) ;; ==> #t (real? +i) ;; ==> #f (real? (/ 1 0)) ;; ==> #f (It's an inf.) (real? (/ 0 0)) ;; ==> #f (It's a nan.)
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:
(remainder 13 4) ;; ==> 1 (remainder -13 4) ;; ==> -1 (remainder 13 -4) ;; ==> 1 (remainder -13 -4) ;; ==> -1
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:
(reverse '()) ;; ==> () (reverse (list 1 2 3)) ;; ==> (3 2 1)
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:
(round 3.49) ;; ==> 3. (round 3.51) ;; ==> 4. (round 3.5) ;; ==> 4. (round 2.5) ;; ==> 2.
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 Wraith Scheme.
Arguments:
One, which must be the exact integer 5.
Side Effects:
None.
Returned Value:
The Scheme-report environment of Wraith Scheme.
For Example:
(eval '(+ 2 2) (scheme-report-environment 5)) 4
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:
;; 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
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:
(define a (cons 1 2)) ;; ==> a a ;; ==> (1 . 2) (set-car! a 42) ;; ==> #t a ;; ==> (42 . 2)
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:
(define a (cons 1 2)) ;; ==> a a ;; ==> (1 . 2) (set-cdr! a 42) ;; ==> #t a ;; ==> (1 . 42)
Type:
Procedure.
Operation:
Mathematical sine.
Arguments:
One number. Real numbers are taken to be angles in radians.
Side Effects:
None.
Returned Value:
The sine of the argument.
For Example:
(sin 0) ;; ==> 0 (sin 1.5707963267948966) ;; ==> 1. (sin 0.7853981633974483) ;; ==> 0.7071067811865475 (sin +i) ;; ==> 1.1752011936438014i
Type:
Procedure.
Operation:
Mathematical square root.
Arguments:
One number.
Side Effects:
None.
Returned Value:
The square root of the argument.
For Example:
(sqrt 0) ;; ==> 0 (sqrt 2.5) ;; ==> 1.5811388300841898 (sqrt 4) ;; ==> 2 (sqrt -1) ;; ==> +i (sqrt +i) ;; ==> 0.7071067811865476+0.7071067811865475i
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:
(string) ;; ==> "" (string #\C #\a #\t) ;; ==> "Cat"
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:
(string->list "Cat") ;; ==> (#\C #\a #\t)
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.
Side Effects:
None.
Returned Value:
A number: Returns a number whose external representation in the given base is the given string.
For Example:
(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 "#i-123###.e23") ;; ==> -1.2300000000000001e28
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:
(string->symbol "Cat") ;; ==> Cat ;; Note the capitalization.
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:
(string-append "I " "see " "the " "cat.") ;; ==> "I see the cat."
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:
(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
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:
(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
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:
(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
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:
(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
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:
(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
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:
(string-copy "Cat") ;; ==> "Cat"
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:
(define a (make-string 2)) ;; ==> a a ;; ==> " " (string-fill! a #\x) ;; ==> #t a ;; ==> "xx"
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:
(string-length "Cat") ;; ==> 3
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:
(string-ref "Cat" 0) ;; ==> #\C (string-ref "Cat" 1) ;; ==> #\a (string-ref "Cat" 2) ;; ==> #\t
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:
(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"
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:
(string<=? "aa" "aardvark") ;; ==> #t (string<=? "Aa" "aardvark") ;; ==> #t (string<=? "aa" "Aardvark") ;; ==> #f (string<=? "aa" "pahoehoe") ;; ==> #t (string<=? "aardvark" "aardvark") ;; ==> #t
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:
(string<? "aa" "aardvark") ;; ==> #t (string<? "Aa" "aardvark") ;; ==> #t (string<? "aa" "Aardvark") ;; ==> #f (string<? "aa" "pahoehoe") ;; ==> #t (string<? "aardvark" "aardvark") ;; ==> #f
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:
(string=? "aa" "aardvark") ;; ==> #f (string=? "Aa" "aardvark") ;; ==> #f (string=? "aa" "Aardvark") ;; ==> #f (string=? "aa" "pahoehoe") ;; ==> #f (string=? "aardvark" "aardvark") ;; ==> #t (string=? "aardvark" "AARDVARK") ;; ==> #f
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:
(string>=? "aa" "aardvark") ;; ==> #f (string>=? "Aa" "aardvark") ;; ==> #f (string>=? "aa" "Aardvark") ;; ==> #t (string>=? "aa" "pahoehoe") ;; ==> #f (string>=? "pahoehoe" "aa") ;; ==> #t (string>=? "aardvark" "aardvark") ;; ==> #t
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:
(string>? "aa" "aardvark") ;; ==> #f (string>? "Aa" "aardvark") ;; ==> #f (string>? "aa" "Aardvark") ;; ==> #t (string>? "aa" "pahoehoe") ;; ==> #f (string>? "pahoehoe" "aa") ;; ==> #t (string>? "aardvark" "aardvark") ;; ==> #f
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:
(string? #t) ;; ==> #f (string? 'Cat) ;; ==> #f (string? "Cat") ;; ==> #t
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:
(substring "Cat" 0 0) ;; ==> "" (substring "The cat sees me." 4 7) ;; ==> "cat"
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:
(symbol->string 'foo) ;; ==> "foo"
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:
(symbol? #t) ;; ==> #f (symbol? "foo") ;; ==> #f (symbol? 'foo) ;; ==> #t
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
(syntax-rules foo bar baz)
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:
(syntax-rules foo bar baz) ;; ==> 0000000000000003-0000020002df8028: Symbol -- Not a Car (Kitten 0) Problem: Implementation error: Tried to take the car of a non-pair. Last lambda called (which may have returned) has never been named. (Resetting) Top-level loop ...
The reason for this behavior is an implementation detail of Wraith Scheme: In Wraith Scheme, "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:
(syntax-rules foo bar baz)
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 Wraith Scheme encounters the form:
(define-syntax foo (syntax-rules foo bar baz))
it produces a more useful error report:
(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 ...
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. Real numbers are taken angles in radians.
Side Effects:
None.
Returned Value:
The tangent of the argument.
For Example:
(tan 0) ;; ==> 0 (tan 1.5707963267948966) ;; ==> 16331239353195370. (tan 3) ;; ==> -0.1425465430742778 (tan +i) ;; ==> 0.7615941559557649i
Type:
Procedure.
Operation:
If a transcript file is in use, stop using it and close the port to the file. If no transcript is in use, "transcript-off" does nothing.
Arguments:
None.
Side Effects:
Closes any open transcript file.
Returned Value:
#t
For Example:
(transcript-off) ;; ==> #t
Type:
Procedure.
Also see the related enhancement procedure e::transcript-on-append.
Operation:
Open a transcript file and start using it.
Wraith Scheme allows only one transcript file to be open at a time. If a transcript file is already in use when "transcript-on" is called, Wraith Scheme will close the old transcript file before starting to use the new one. Any previous content of the transcript file will be lost; that is, the file is not opened for append.
Transcript files record everything that appeared in the Wraith Scheme Main Display Panel while the transcript file was in use, whether keyed in by the user or output by Wraith Scheme.
Procedure transcript-off closes any transcript file in use.
Arguments:
At most one: If present, a string containing a Unix-style pathname to a file to be used as a transcript file. If there is no argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain a pathname.
Side Effects:
Opens a new transcript file, and closes any transcript file that was already in use.
Returned Value:
#t
For Example:
(transcript-on "MyTranscript.text") ;; Opens the file ;; ==> #t (transcript-on) ;; Wraith Scheme uses the Dialog Panel ;; ==> #t
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:
(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.
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, 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:
(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)
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, 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:
(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)
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:
;; 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> ;; List of values: (1 2 3 4 5 6 7 8 9 10)
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:
(vector) ;; ==> #() (vector 1 2 3) ;; ==> #(1 2 3)
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:
(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.
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:
(define cat (make-vector 3)) ;; ==> cat (vector-fill! cat 'meow) ;; ==> #t cat ;; ==> #(meow meow meow)
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:
(vector-length '#()) ;; ==> 0 (vector-length '#(meow meow meow)) ;; ==> 3
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:
(vector-ref '#(c a t) 0) ;; ==> #\c (vector-ref '#(c a t) 1) ;; ==> #\a (vector-ref '#(c a t) 2) ;; ==> #\t
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:
(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)
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:
(vector? #t) ;; ==> #f (vector? (make-vector 3)) ;; ==> #t (vector? (list->vector (list 1 2 3))) ;; ==> #t
Type:
Procedure.
Operation:
Temporarily change the current input port to a port to a file, and do something while the change is in effect.
Arguments:
One or two: The last a procedure of no arguments, to be called while the changed current input port is in effect. If there are two arguments, the first is a string containing a Unix-style pathname to a file: Wraith Scheme will open an input port to this file and make that port the current input port while the procedure is run. If there is only one argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain a path to the file to be used.
Side Effects:
Temporarily changes the current input port, plus whatever side effects result from the call to the given procedure.
Returned Value:
#t
For Example:
;; Suppose "Foo" is a file containing the text "abc". (with-input-from-file "Foo" (lambda () (display (read-char)) (newline) (display (read-char)) (newline) (display (read-char)) (newline))) ;; ==> ;; a ;; b ;; c ;; #t
Type:
Procedure.
Operation:
Temporarily change the current output port to a port to a file, and do something while the change is in effect.
Arguments:
One or two: The last a procedure of no arguments, to be called while the changed current output port is in effect. If there are two arguments, the first is a string containing a Unix-style pathname to a file: Wraith Scheme will open an output port to this file and make that port the current output port while the procedure is run. If there is only one argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain a path to the file to be used.
Side Effects:
None.
Returned Value:
Temporarily changes the current output port, plus whatever side effects result from the call to the given procedure.
For Example:
(with-output-to-file "Foo" (lambda () (write-char #\a) (newline) (write-char #\b) (newline) (write-char #\c) (newline))) ;; Writes the text "abc" to file "Foo", ;; one character to a line. ;; ==> #t
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:
;; 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
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:
(with-output-to-file "Foo" (lambda () (write-char #\a) (write-char #\b) (write-char #\c))) ;; Writes the text "abc" to file "Foo". ;; ==> #t
Type:
Procedure.
Operation:
Test whether a number is zero.
Arguments:
One 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:
(zero? 1) ;; ==> #f (zero? 0) ;; ==> #t (zero? #i0) ;; ==> #t (zero? 0/42) ;; ==> #t (zero? 0i) ;; ==> #t
Type:
Procedure.
Operation:
Find the number of bytes free in the current Wraith Scheme 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 Wraith Scheme active memory generation.
For Example:
(e::active-room) ;; ==> 567328 ;; e.g.
Type:
Procedure.
Operation:
Find the size of the active generation in use by the Wraith Scheme generational garbage collector.
Rationale, Explanation, Excuses:
"e::active-store-size" is a basic memory-inspection function. Do not confuse it with "e::active-room": "e::active-store-size" shows how many bytes total are available for the use of the active generation has, "e::active-room" shows how many of those bytes remain unused.
NOTE that the store sizes of the active and aging memory generations are always the same.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: Returns the size, in bytes, of Wraith Scheme's active generation.
For Example:
(e::active-store-size) ;; ==> 1052672 ;; E.g.
Type:
Procedure.
Operation:
Find the number of bytes free in the current Wraith Scheme 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 in the current Wraith Scheme aging memory generation, that are not in use.
For Example:
(e::aging-room) ;; ==> 42 ;; e.g.
Type:
Wraith Scheme does not define a value for "e::alarm"; the intent is, that the symbol "e::alarm" may be bound to a lambda expression of your choice.
Operation:
Whatever you like.
Rationale, Explanation, Excuses:
The procedure "e::alarm" is not defined by Wraith Scheme; indeed, the symbol "e::alarm" does not even exist in the distributed version of Wraith Scheme! It is you who may, if you wish, define "e::alarm". You may make it be any lambda expression of no arguments that you like.
You may use the procedure "e::set-alarm!" to cause Wraith Scheme to interrupt itself at a time in the future; when that time occurs, the procedure "e::alarm" will run. You may also use the procedures "e::alarm?" and "e::alarm-time" respectively to tell whether an alarm is presently set and at what time (Unix time) it will occur.
You may also cause "e::alarm" to run by sending a "SIGALRM" signal to Wraith Scheme from some other program.
Use of these procedures makes it possible to start something happening automatically at a specified time in the future. These procedures provide a rather straightforward interface to the Unix "alarm" system call, which is the mechanism Wraith Scheme uses for implementing them
The alarm is made to go off by pushing the Scheme expression '(e::alarm) into the input queue of the Wraith Scheme process (kitten or MomCat) in which the alarm was set. If that process is busy doing something else, the alarm will not be processed until the process is no longer busy. Thus the alarm system does not provide a truly asynchronous interrupt; for an alarm to happen promptly you must run it in a kitten that is not busy, or in an un-busy MomCat.
NOTE that the fact that '(e::alarm) is pushed into an input queue means that the evaluation of (e::alarm) will always take place at top-level. Any definition of e::alarm in a local environment -- such as within a "let" -- will not be used.
If the symbol "e::alarm" is not bound to a value, or is not bound to a lambda expression, then no alarm will go off. Wraith Scheme will report an error if an alarm goes off while "e::alarm" is bound to a lambda expression that requires arguments.
Arguments:
None.
Side Effects:
Whatever you like.
Returned Value:
Whatever you like.
For Example:
(define (e::alarm) (display "Alarms and excursions!!\n")) ;; ==> e::alarm (e::set-alarm! 10) ;; ==> #t ;; Ten seconds later ... Alarms and excursions!!
Type:
Procedure.
Operation:
Tests whether an alarm is presently set.
Rationale, Explanation, Excuses:
The procedure "e::alarm" is not defined by Wraith Scheme; indeed, the symbol "e::alarm" does not even exist in the distributed version of Wraith Scheme! It is you who may, if you wish, define "e::alarm". You may make it be any lambda expression of no arguments that you like.
You may use the procedure "e::set-alarm!" to cause Wraith Scheme to interrupt itself at a time in the future; when that time occurs, the procedure "e::alarm" will run. You may also use the procedures "e::alarm?" and "e::alarm-time" respectively to tell whether an alarm is presently set and at what time (Unix time) it will occur.
You may also cause "e::alarm" to run by sending a "SIGALRM" signal to Wraith Scheme from some other program.
Use of these procedures makes it possible to start something happening automatically at a specified time in the future. These procedures provide a rather straightforward interface to the Unix "alarm" system call, which is the mechanism Wraith Scheme uses for implementing them
The alarm is made to go off by pushing the Scheme expression '(e::alarm) into the input queue of the Wraith Scheme process (kitten or MomCat) in which the alarm was set. If that process is busy doing something else, the alarm will not be processed until the process is no longer busy. Thus the alarm system does not provide a truly asynchronous interrupt; for an alarm to happen promptly you must run it in a kitten that is not busy, or in an un-busy MomCat.
NOTE that the fact that '(e::alarm) is pushed into an input queue means that the evaluation of (e::alarm) will always take place at top-level. Any definition of e::alarm in a local environment -- such as within a "let" -- will not be used.
If the symbol "e::alarm" is not bound to a value, or is not bound to a lambda expression, then no alarm will go off. Wraith Scheme will report an error if an alarm goes off while "e::alarm" is bound to a lambda expression that requires arguments.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, an alarm is set and has not yet occurred.
For Example:
(define (e::alarm) (display "Alarms and excursions!!\n")) ;; ==> e::alarm (e::alarm?) ;; ==> #f (e::set-alarm! 10) ;; ==> #t ;; Typed immediately: (e::alarm?) ;; ==> #t ;; Ten seconds later ... Alarms and excursions!! (e::alarm?) ;; ==> #f
Type:
Procedure.
Operation:
Tells when any presently set alarm will occur.
Rationale, Explanation, Excuses:
The procedure "e::alarm" is not defined by Wraith Scheme; indeed, the symbol "e::alarm" does not even exist in the distributed version of Wraith Scheme! It is you who may, if you wish, define "e::alarm". You may make it be any lambda expression of no arguments that you like.
You may use the procedure "e::set-alarm!" to cause Wraith Scheme to interrupt itself at a time in the future; when that time occurs, the procedure "e::alarm" will run. You may also use the procedures "e::alarm?" and "e::alarm-time" respectively to tell whether an alarm is presently set and at what time (Unix time) it will occur.
You may also cause "e::alarm" to run by sending a "SIGALRM" signal to Wraith Scheme from some other program.
Use of these procedures makes it possible to start something happening automatically at a specified time in the future. These procedures provide a rather straightforward interface to the Unix "alarm" system call, which is the mechanism Wraith Scheme uses for implementing them
The alarm is made to go off by pushing the Scheme expression '(e::alarm) into the input queue of the Wraith Scheme process (kitten or MomCat) in which the alarm was set. If that process is busy doing something else, the alarm will not be processed until the process is no longer busy. Thus the alarm system does not provide a truly asynchronous interrupt; for an alarm to happen promptly you must run it in a kitten that is not busy, or in an un-busy MomCat.
NOTE that the fact that '(e::alarm) is pushed into an input queue means that the evaluation of (e::alarm) will always take place at top-level. Any definition of e::alarm in a local environment -- such as within a "let" -- will not be used.
If the symbol "e::alarm" is not bound to a value, or is not bound to a lambda expression, then no alarm will go off. Wraith Scheme will report an error if an alarm goes off while "e::alarm" is bound to a lambda expression that requires arguments.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer. If an alarm is set, the returned value will be the Unix time at which the alarm occurs. If no alarm is set, the returned value will be -1.
The returned value is only accurate to approximately the nearest second.
For Example:
(define (e::alarm) (display "Alarms and excursions!!\n")) ;; ==> e::alarm (e::alarm-time) ;; ==> -1 (e::set-alarm! 10) ;; ==> #t ;; Typed immediately: (e::alarm-time) ;; ==> A large number, a Unix time. ;; Ten seconds later ... Alarms and excursions!! (e::alarm-time) ;; ==> -1
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
(apply and <list>)
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:
(e::all? '(1 2 3)) ;; ==> #t (e::all? '(1 #f 3)) ;; ==> #f (e::all? '()) ;; ==> #t (The empty list contains no element that is #f.)
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
(apply or <list>)
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:
(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.)
Type:
Procedure.
Operation:
Test whether a Wraith Scheme 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 Wraith Scheme 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:
(e::atom? #f) ;; ==> #t (e::atom? (cons 1 2)) ;; ==> #f
Type:
Procedure.
Operation:
Tests whether the big red button (in the Wraith Scheme Sensory Devices Drawer) is enabled. Affects only the big red button of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Required for checking the state of the big red button from Wraith Scheme.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the big red button is enabled. Otherwise, returns #f. Ignores the exactness of the arguments.
For Example:
(e::big-red-button-enabled?) ;; ==> #t -- The big red button is enabled.
Type:
Procedure.
Operation:
Return the interrupt number associated with the big red button of the Wraith Scheme process where the procedure was called. Reports an error if that button is not enabled.
Rationale, Explanation, Excuses:
Required for controlling the big red button (in the Wraith Scheme Sensory Devices Drawer) from Wraith Scheme.
Arguments:
None.
Side Effects:
None.
Returned Value:
An exact integer in the range [0..1023], that is the interrupt number presently associated with the big red button.
For Example:
(e::big-red-button-interrupt-number) ;; ==> 73 -- The big red button is set to trigger interrupt 73.
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:
(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) ;; ==> 65535 ;; Binary 1111111111111111 (e::bit-shift-right-arithmetic -1 16) ;; ==> -1 ;; -1 shifted right and padded with 1's ;; is still -1
Type:
Procedure.
Operation:
Block read and write access to the value of a Wraith Scheme that is the car of a pair (perhaps most usefully, that is the car of a list), by locking the pair itself.
This procedure is one of five that are particularly useful in dealing with critical sections that involve Wraith Scheme objects, notably symbols. The five procedures in question are
These procedures should be used with great caution: They are individually and collectively calamitous, for several reasons.
Technical Note: The problem indicated is a deadlock due to an attempt to access a locked object.
Rationale, Explanation, Excuses:
Useful low-level primitive for parallel programming.
Arguments:
One pair.
Side Effects:
Blocks read and write access to the pair. That is, any attempt to access the car or cdr of the pair, than by way of the first item in the list of returned values, will result in the process making the attempt stalling until the block is released, perhaps by "c::release-block".
Contrast this procedure with "e::block-symbol-binding" -- which follows -- in which the argument is a symbol.
Returned Value:
A list of two items. The first is the car of the pair immediately after the lock was applied. (Since access to the pair is now locked, there is no other way to obtain that value.) The second is a locked object suitable both for the first argument to a call to "c::set-blocked-binding!" (to change the bound value), and for the argument to "c::release-block" (to release the lock).
When "c::set-blocked-binding!" is applied to the locked object in the manner just described, it is the car of the pair that is modified.
For Example:
(define a (list 42)) ;; ==> a (define (blocked-increment-of-a) (let* ((the-block-list (e::block-any-binding a)) (the-value (car the-block-list)) (the-lock (cadr the-block-list)) ) (c::set-blocked-binding! the-lock (+ the-value 1)) (c::release-block the-lock))) ;; ==> blocked-increment-of=a a ;; ==> (42) (blocked-increment-of-a) ;; ==> #t a ;; ==> (43)
You might note in passing that the call to "e::block-any-binding" is of the form
(e::block-any-binding a) ;; Without quotenot
(e::block-any-binding 'a) ;; With quote
Type:
Procedure.
Operation:
Block read and write access to the value of a bound Wraith Scheme symbol, except via c::set-blocked-binding!, which see.
This procedure is one of five that are particularly useful in dealing with critical sections that involve Wraith Scheme objects, notably symbols. The five procedures in question are
These procedures should be used with great caution: They are individually and collectively calamitous, for several reasons.
Technical Note: The problem indicated is a deadlock due to an attempt to access a locked object.
Rationale, Explanation, Excuses:
Useful low-level primitive for parallel programming.
Arguments:
One symbol.
Side Effects:
Blocks read and write access to the value of its argument, except via c::set-blocked-binding!, which see. That is, any attempt to access the blocked value, other than by way of the first item in the list of returned values, will result in the process making the attempt stalling until the block is released, perhaps by "c::release-block".
Contrast this procedure with "e::block-any-binding" -- which precedes -- in which the argument is a pair.
Returned Value:
A list of two items. The first is the value bound to the symbol immediately after the lock was applied. (Since access to that binding is now locked, there is no other way to obtain that value.) The second is a locked object suitable both for the first argument to a call to "c::set-blocked-binding!" (to change the bound value), and for the argument to "c::release-block" (to release the lock).
For Example:
(define a 0) ;; ==> a (define (blocked-increment-of-a) (let* ((the-block-list (e::block-symbol-binding 'a)) (the-value (car the-block-list)) (the-lock (cadr the-block-list)) ) (c::set-blocked-binding! the-lock (+ the-value 1)) (c::release-block the-lock))) ;; ==> blocked-increment-of-a a ;; ==> 0 (blocked-increment-of-a) ;; ==> #t a ;; ==> 1
You might note in passing that the call to "e::block-symbol-binding" is of the form
(e::block-symbol-binding 'a) ;; With quotenot
(e::block-symbol-binding a) ;; No quote
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:
(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.
Type:
Procedure.
Operation:
Convert numbers, taken as C-style booleans, to #t or #f.
Rationale, Explanation, Excuses:
Useful with the Wraith Scheme 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:
(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
Type:
Procedure.
Operation:
Clear the internal flag that tells Wraith Scheme 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:
(e::clear-compiler-on!) ;; ==> #t
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 Wraith Scheme 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 a symbol's permanent flag, so you cannot change the value to which it is bound. Procedure "e::permanent?" tests whether that flag 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:
(e::clear-permanent! 'cons) ;; ==> #t ;; DANGER WILL ROBINSON
Type:
Procedure.
Operation:
Clear the internal flag that tells Wraith Scheme 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 Wraith Scheme's numeric display routines to use reduced precision.
Returned Value:
#t
For Example:
(e::clear-show-full-precision!) ;; ==> #t
Type:
Procedure.
Operation:
Test whether a port is closed.
Rationale, Explanation, Excuses:
The entities that Wraith Scheme 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:
(define foo (open-output-file "Whatever")) ;; ==> foo (e::closed-port? foo) ;; ==> #f (close-output-port foo) ;; ==> #t (e::closed-port? foo) ;; ==> #t
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 Wraith Scheme'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:
(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
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 Wraith Scheme'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:
(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
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 Wraith Scheme'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:
(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
Type:
Procedure.
Operation:
Return the value of the internal flag that controls whether Wraith Scheme compiles defines automatically.
Rationale, Explanation, Excuses:
Allow Scheme programs to examine important internal state of the Wraith Scheme interpreter.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns the (boolean) flag that controls whether Wraith Scheme compiles defines automatically. That flag is true if, and only if, defines are automatically compiled.
For Example:
(e::set-compiler-on!) ;; ==> #t (e::compiler-on?) ;; ==> #t (e::clear-compiler-on!) ;; ==> #t (e::compiler-on?) ;; ==> #f
Type:
Procedure.
Operation:
Invoke the Wraith Scheme compiler on a Scheme object.
Rationale, Explanation, Excuses:
Wraith Scheme 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:
;; 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>
Type:
Procedure.
Operation:
Cons the argument with the Wraith Scheme 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
(e::cons-with-continuation <whatever>)
is not equivalent to
(eval <whatever> (interaction-environment))
In Wraith Scheme, 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:
(let ((x 3)) (e::cons-with-continuation 'x)) ;; ==> <error> x Problem: No lexically visible binding of this symbol.
What is happening is that in Wraith Scheme, "let" is a macro, which in this case expands using a renamed lambda variable, into something like:
((c::lambda (g23008) (e::cons-with-continuation (quote x))) 3)
(The actual name used will vary depending on how many similar substitutions Wraith Scheme 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 instead is the result of evaluating the argument.
For Example:
(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
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 Wraith Scheme'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:
(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
Type:
Procedure.
Operation:
Find the current directory; the directory from which Unix relative paths begin.
Rationale, Explanation, Excuses: Making effective use of the MacIntosh's Unix file system from Wraith Scheme requires means to set and determine the current directory.
Arguments:
None.
Side Effects:
None.
Returned Value:
A string: Returns a string containing a Unix-style path to the current directory. The returned string will end in a '/'.
For Example:
(e::current-directory) ;; ==> "/" (When Wraith Scheme starts from the Dock.)
Type:
Procedure.
Operation:
Not built in to Wraith Scheme; to be defined by the user.
Rationale, Explanation, Excuses:
Wraith Scheme has no complicated built-in debugger; proper use of the symbol "e::debug" allows loading run at run-time, or at start-Wraith-Scheme 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 Wraith Scheme 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 Wraith Scheme program recognizes and uses for that purpose.
When a non-fatal error occurs, the Wraith Scheme 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, Wraith Scheme 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 Wraith Scheme error-handling mechanism, which will then proceed with its simple, built-in trace.
Any value returned by "e::debug" will be ignored.
Arguments:
When called by Wraith Scheme, "e::debug" is passed 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 Wraith Scheme, and thought it might be generally useful. The source code for "e::deep-copy" is:
(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)))
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:
(e::deep-copy (list 1 2 3)) ;; ==> (1 2 3)
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
(e::define-no-compile (increment x) (+ x 1))
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:
(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>
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 Wraith Scheme'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:
(e::derationalize 1/3) ;; ==> 0.33333333333333331 (e::derationalize 3.) ;; ==> 3.
Type:
Procedure.
Operation:
Disable the big red button of the Wraith Scheme Process where the procedure was called.
Rationale, Explanation, Excuses:
Required for controlling the big red button (in the Wraith Scheme Sensory Devices Drawer) from Wraith Scheme.
Arguments:
None.
Side Effects:
Disables the big red button, if it is enabled. Has no effect, and does not report an error, if the big red button is already disabled.
Returned Value:
#t
For Example:
(e::disable-big-red-button!) ;; Disables the big red button.
Type:
Procedure.
Operation:
Disable a pushbutton of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Required for controlling the pushbuttons (in the Wraith Scheme Sensory Devices Drawer) from Wraith Scheme.
Arguments:
One integer in the range [0..3].
Side Effects:
Disables the given pushbutton, if it is enabled. Has no effect, and does not report an error, if the pushbutton is already disabled.
Returned Value:
#t
For Example:
(e::disable-pushbutton! 1) ;; ==> Disables pushbutton 1.
Type:
Procedure.
Operation:
Assign an interrupt number to the big red button, and enable that button so that it will trigger the given interrupt when pushed. Affects only the big red button of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Required for controlling the big red button (in the Wraith Scheme Sensory Devices Drawer) from Wraith Scheme.
Arguments:
One exact integer in the range [0..1023]
Side Effects:
Enables the big red button to trigger the given interrupt when pushed.
Returned Value:
#t
For Example:
(e::enable-big-red-button! 88) ;; ==> Set the big red button ;; to trigger interrupt ;; 88 when pushed.
Type:
Procedure.
Operation:
Assign an interrupt number to a pushbutton of the Wraith Scheme process where the procedure was called, and enable that button so that it will trigger the given interrupt when pushed.
Rationale, Explanation, Excuses:
Required for controlling the pushbuttons (in the Wraith Scheme Sensory Devices) Drawer from Wraith Scheme.
Arguments:
Two: The first an integer in the range [0..3], the second an integer in the range [0..1023]
Side Effects:
Enables the pushbutton whose number is the first argument, to trigger the interrupt given as the second argument.
Returned Value:
#t
For Example:
(e::enable-pushbutton! 3 137) ;; ==> Set pushbutton 3 to ;; trigger interrupt 137 ;; when pushed.
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 Wraith Scheme program.
Rationale, Explanation, Excuses:
Adds clarity of purpose to code and saves typing large integers.
For Example:
(e::make-forgettable (cons 1 2) e::entropy-death 0.5) ;; ==> #<Forgettable Object Pointer, unexpired, expiration time 9223372036854775807>
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 Wraith Scheme to the top-level loop.
Returned Value:
Does not return.
For Example:
(e::error "Oops!!") ;; ==> Problem: Oops!! (Resetting) Top-level loop ...
Type:
Procedure.
Operation:
Return the default output port for error messages.
Rationale, Explanation, Excuses:
Wraith Scheme generally handles the output from error messages differently from normal output. For example, even when "current-output-port" returns a port to a file, error messages are usually sent to the console (and thereby also to any transcript file that may be open). "e::error-port" returns the port to which Wraith Scheme's 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:
;; 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 Wraith Scheme window, ;; even if normal output goes to a file, as in: (with-output-to-file "foo" my-procedure)
Type:
Procedure.
Operation:
Exit the Wraith Scheme program immediately, with no second chances and no confirmation dialog.
When invoked from the MomCat, this procedure also causes all other instances of Wraith Scheme that are running -- that is, all kittens -- to exit. When called from a kitten that is not the MomCat, only that kitten will exit.
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 Wraith Scheme program. When called from the MomCat, also causes any kittens present to exit.
Returned Value:
Does not apply.
For Example:
(e::exit) ;; ==> ;; Wraith Scheme exits.
Type:
Procedure.
Operation:
Rationale, Explanation, Excuses:
A "call" or invocation of a Wraith Scheme 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 Wraith Scheme, 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 Wraith Scheme, "if" is a macro. When Wraith Scheme encounters an expression like "(if #t 1 2)", Wraith Scheme
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 Wraith Scheme'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:
(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))))
Type:
Procedure.
Operation:
Recursively expand all the macros, in a Wraith Scheme 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
(e::expand-macros-recursively '(cond (#f 1) (#f 4) (#t 42) else 'foo))
will fail, because quoted expressions are supposed to be constants, and are not supposed to be modifiable, and Wraith Scheme 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:
(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))))
Type:
Procedure.
Operation:
Determine whether Unix-style pathname is a path to a file that can be opened for reading.
Rationale, Explanation, Excuses:
This procedure is useful for working with the Macintosh's Unix-based file system.
The name "e::file-exists?" is a little misleading: Strictly, the procedure returns a boolean indicating whether the Unix command "fopen" was able to open the indicated pathname for reading; the procedure may return #f if the file existed but had Unix permission settings inappropriate for reading by the current user of Wraith Scheme.
Arguments:
One string, presumably containing something that looks like a Unix-style pathname.
Side Effects:
None. Note in particular, that this procedure closes any file that it opens.
Returned Value:
A boolean: Returns #t if, and only if, Unix "fopen" could open the path contained within the argument for reading. Otherwise, returns #f.
For Example:
(e::file-exists? "/") ;; ==> #t (e::file-exists? "No.such.file") ;; ==> #f ;; If there is no such file.
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 Wraith Scheme's functions that deal with numbers. In the present version of Wraith Scheme, the only fixnums stored are 64-bit integers.
Note that it is possible to store integers as flonums: Wraith Scheme 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:
(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? 10000000000000000000) ;; ==> #f (integer? 10000000000000000000) ;; ==> #t
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 Wraith Scheme's functions that deal with numbers. In the present version of Wraith Scheme, 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:
(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? 10000000000000000000) ;; ==> #t (integer? 10000000000000000000) ;; ==> #t
Type:
Procedure.
Operation:
Determine whether two float matrices are numerically equal,
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two float matrices.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the two float matrices have the same numbers of rows and columns, and if their elements at positions (i, j) are numerically equal for all allowed row numbers i and column numbers j. Otherwise, returns #f.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::make-float-matrix-from-vector 3 2 '#(1 2 3 4 5 6))) ;; ==> b (define c (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 7))) ;; ==> c (e::float-matrix-= a a) ;; ==> #t (e::float-matrix-= a b) ;; ==> #f (e::float-matrix-= a c) ;; ==> #f
Type:
Procedure.
Operation:
Add two float matrices.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two float matrices.
Side Effects:
None.
Returned Value:
Returns a new float matrix which is the matrix sum of the two given matrices.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(2 4 6 8 10 12))) ;; ==> a (define b (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> b (e::float-matrix-add a b) ;; ==> ;; 3. 6. 9. ;; 12. 15. 18.
Type:
Procedure.
Operation:
Is the argument an antisymmetric float matrix?
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an antisymmetric float matrix. Returns #f otherwise.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::make-float-matrix-from-vector 3 3 '#(1 0 0 0 2 0 0 0 3))) ;; ==> b (define c (e::make-float-matrix-from-vector 3 3 '#(0 1 2 -1 0 3 -2 -3 0))) ;; ==> c (e::float-matrix-antisymmetric? #t) ;; ==> #f (e::float-matrix-antisymmetric? a) ;; ==> #f (e::float-matrix-antisymmetric? b) ;; ==> #f (e::float-matrix-antisymmetric? c) ;; ==> #t
Type:
Procedure.
Operation:
Copy a float matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
A new float matrix, which is a copy of the argument.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::float-matrix-copy a)) ;; ==> b a ;; ==> ;; 1. 2. 3. ;; 4. 5. 6. b ;; ==> ;; 1. 2. 3. ;; 4. 5. 6.
Type:
Procedure.
Operation:
Calculate the determinant of a matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One square float matrix.
Side Effects:
None.
Returned Value:
An inexact real: The determinant of the argument.
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> a (e::float-matrix-determinant a) ;; ==> -2.
Type:
Procedure.
Operation:
Is the argument a diagonal float matrix?
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a square float matrix, all of whose off-diagonal elements are zero. Returns #f otherwise.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::make-float-matrix-from-vector 3 3 '#(1 0 0 0 2 0 0 0 3))) ;; ==> b (define c (e::make-float-matrix-from-vector 3 3 '#(1 1 0 0 2 0 0 0 3))) ;; ==> c (e::float-matrix-diagonal? #t) ;; ==> #f (e::float-matrix-diagonal? a) ;; ==> #f (e::float-matrix-diagonal? b) ;; ==> #t (e::float-matrix-diagonal? c) ;; ==> #f
Type:
Procedure.
Operation:
Given two float matrices each of which has one row and three columns, and is thereby a three-vector, calculate a new one-by-three float matrix which is the vector cross product of the two given matrices. Specifically,
(e::float-matrix-cross-product A B)calculates the quantity more conventionally written as
A x B
Rationale, Explanation, Excuses:
Useful in mathematical physics and in engineering
Arguments:
Two float matrices, each with one row and three columns.
Side Effects:
None.
Returned Value:
A new float matrix with one row and three columns, which is the vector cross-product of the arguments in the order given. That is,
(e::float-matrix-cross-product A B)calculates the quantity more conventionally written as
A x B
For Example:
(define a (e::make-float-matrix-from-vector 1 3 '#(1 2 3))) ;; ==> a (define b (e::make-float-matrix-from-vector 1 3 '#(4 5 6))) ;; ==> b (e::float-matrix-cross-product a b) ;; ==> -3. 6. -3.
Type:
Procedure.
Operation:
Given two matrices which have the same number of rows and the same number of columns, calculate the sum over all positions ( i, j ) of the product of the first matrix element at ( i, j ) and the second matrix element at ( i, j ).
Rationale, Explanation, Excuses:
Useful in machine learning algorithms.
Arguments:
Two float matrices.
Side Effects:
None.
Returned Value:
The sum over all positions ( i, j ), of the product of the first matrix element at ( i, j ) and the second matrix element at ( i, j ).
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(2 4 6 8))) ;; ==> a (define b (e::make-float-matrix-from-vector 2 2 '#(1 3 5 7))) ;; ==> b (e::float-matrix-dot-product a b) ;; ==> 100.
Type:
Procedure.
Operation:
Export the elements of one row of a float matrix into a Scheme vector.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two: The first a float matrix, the second an integer indicating the row to be dumped.
Side Effects:
None.
Returned Value:
A vector containing all elements of the given row.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (e::float-matrix-dump-row-to-vector a 0) ;; ==> #(1. 2. 3.)
Type:
Procedure.
Operation:
Export the elements of a float matrix into a Scheme vector, in row-major order.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
A vector containing all elements of the given matrix, in row-major order.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (e::float-matrix-dump-to-vector a) ;; ==> #(1. 2. 3. 4. 5. 6.)
Type:
Procedure.
Operation:
Export the elements of one column of a float matrix into a Scheme vector.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two: The first a float matrix, the second an integer indicating the column to be dumped.
Side Effects:
None.
Returned Value:
A vector containing all elements of the given column.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (e::float-matrix-dump-column-to-vector a 0) ;; ==> #(1. 4.)
Type:
Procedure.
Operation:
Is the argument a float matrix?
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a float matrix. Otherwise, returns #f.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (e::float-matrix? #t) ;; ==> #f (e::float-matrix? a) ;; ==> #t
Type:
Procedure.
Operation:
Set the elements of the given row of the given float matrix to the values in the given vector.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Three: The first a float matrix, the second an integer indicating one of its rows (zero-based), and the third a Scheme vector containing data with which to fill the row.
Side Effects:
Overwrites all elements of the given row.
Returned Value:
The given matrix, with the new data loaded.
For Example:
(define a (e::make-float-matrix 2 3)) ;; ==> a a ;; ==> ;; 0. 0. 0. ;; 0. 0. 0. (e::float-matrix-fill-row-from-vector! a 0 '#(1 2 3)) ;; ==> ;; 1. 2. 3. ;; 0. 0. 0.
Type:
Procedure.
Operation:
Set the elements of the given float matrix to the values in the given vector, which are provided in row-major order.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two: The first a float matrix, the second a Scheme vector containing data with which to fill the matrix, in row-major order.
Side Effects:
Overwrites all elements of the given matrix.
Returned Value:
The given matrix, with the new data loaded.
For Example:
(define a (e::make-float-matrix 2 3)) ;; ==> a a ;; ==> ;; 0. 0. 0. ;; 0. 0. 0. (e::float-matrix-fill-from-vector! a '#(1 2 3 4 5 6)) ;; ==> ;; 1. 2. 3. ;; 4. 5. 6.
Type:
Procedure.
Operation:
Set the elements of the given column of the given float matrix to the values in the given vector.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Three: The first a float matrix, the second an integer indicating one of its columns (zero-based), and the third a Scheme vector containing data with which to fill the column.
Side Effects:
Overwrites all elements of the given column.
Returned Value:
The given matrix, with the new data loaded.
For Example:
(define a (e::make-float-matrix 2 3)) ;; ==> a a ;; ==> ;; 0. 0. 0. ;; 0. 0. 0. (e::float-matrix-fill-column-from-vector! a 0 '#(1 2)) ;; ==> ;; 1. 0. 0. ;; 2. 0. 0.
Type:
Procedure.
Operation:
Get the number of columns in the given matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
An exact integer: The number of columns in the matrix.
For Example:
(define a (e::make-float-matrix 2 3)) ;; ==> a (e::float-matrix-get-columns a) ;; ==> 3
Type:
Procedure.
Operation:
Get the matrix element at a specified row and column.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Three: The first, a float matrix. The second and third, respectively, the (zero-based) row and column of the matrix element whose value is sought.
Side Effects:
None.
Returned Value:
An inexact real: The matrix element at the given row and column.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (e::float-matrix-get-element a 1 2) ;; ==> 6.0
Type:
Procedure.
Operation:
Get the number of rows in the given matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
An exact integer: The number of rows in the matrix.
For Example:
(define a (e::make-float-matrix 2 3)) ;; ==> a (e::float-matrix-get-rows a) ;; ==> 2
Type:
Procedure.
Operation:
Calculate a new float matrix, each of whose values is the product of the values in the corresponding locations in the given matrices.
Rationale, Explanation, Excuses:
Useful for machine-learning algorithms.
Arguments:
Two float matrices.
Side Effects:
None.
Returned Value:
A float matrix, each of whose values is the product of the values in the corresponding locations in the given matrices.
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> a (define b (e::make-float-matrix-from-vector 2 2 '#(2 3 4 5))) ;; ==> b (e::float-matrix-hadamard-product a b) ;; ==> ;; 2. 6. ;; 12. 20.
Type:
Procedure.
Operation:
Is the argument an identity float matrix?
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if,the argument is an identity float matrix. Otherwise, returns #f.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::make-float-matrix-from-vector 3 3 '#(1 0 0 0 1 0 0 0 1))) ;; ==> b (define c (e::make-float-matrix-from-vector 3 3 '#(1 1 0 0 1 0 0 0 1))) ;; ==> c (e::float-matrix-identity? #t) ;; ==> #f (e::float-matrix-identity? a) ;; ==> #f (e::float-matrix-identity? b) ;; ==> #t (e::float-matrix-identity? c) ;; ==> #f
Type:
Procedure.
Operation:
Invert the given matrix, if possible. Report an error if its determinant is zero.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
The inverse of the given matrix.
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(2 2 1 2))) ;; ==> a (e::float-matrix-invert a) ;; ==> ;; 1. -1. ;; =0.5 1.
Type:
Procedure.
Operation:
Multiply the given matrices.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two float matrices.
Side Effects:
None.
Returned Value:
Returns a new float matrix which is the product of the given matrices.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::make-float-matrix-from-vector 3 2 '#(2 3 4 5 6 7))) ;; ==> b (e::float-matrix-multiply a b) ;; ==> ;; 28. 34. ;; 64. 79.
Type:
Procedure.
Operation:
Multiply the given matrix by the given scalar.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two: The first a float matrix, the second a real number.
Side Effects:
None.
Returned Value:
A new float matrix, which is the product of the given matrix and the given scalar.
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> a (e::float-matrix-multiply-by-scalar a 2) ;; ==> ;; 2. 4. ;; 6. 8.
Type:
Procedure.
Operation:
Calculate a new matrix, each of whose elements is the corresponding element of the given matrix divided by the root-sum-square of all elements in the given matrix.
Rationale, Explanation, Excuses:
Useful if the given matrix is a mathematical vector; that is, if either its row number or its column number is one.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
A new float matrix, each of whose elements is the corresponding element of the given matrix divided by the root-sum-square of all elements in the given matrix.
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> a (e::float-matrix-normalize a) ;; ==> 0.18257418583505536 0.36514837167011072 0.5477225575051661 0.7302967433402214
Type:
Procedure.
Operation:
Multiply together all the diagonal elements of the given matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
An inexact real: The product of the diagonal elements of the matrix.
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> a (e::float-matrix-product-of-diagonals a) ;; ==> 4.
Type:
Procedure.
Operation:
Change one element of the given matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Four: First, the float matrix whose element is to be changed; Second and third, the (zero-based) row and column of the element to be changed; Fourth, the new value of that element.
Side Effects:
Alters the given float matrix.
Returned Value:
#t
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> a a ;; ==> ;; 1. 2. ;; 3. 4. (e::float-matrix-set-element! a 1 1 42) ;; ==> a a ;; ==> ;; 1. 2. ;; 3. 42.
Type:
Procedure.
Operation:
Is the argument a square float matrix?
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a square float matrix. Returns #f otherwise.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::make-float-matrix-from-vector 3 3 '#(1 0 0 0 2 0 0 0 3))) ;; ==> b (define c (e::make-float-matrix-from-vector 3 3 '#(0 1 2 -1 0 3 -2 -3 0))) ;; ==> c (e::float-matrix-square? #t) ;; ==> #f (e::float-matrix-square? a) ;; ==> #f (e::float-matrix-square? b) ;; ==> #t (e::float-matrix-square? c) ;; ==> #t
Type:
Procedure.
Operation:
Subtract float matrices.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
Two float matrices.
Side Effects:
None.
Returned Value:
Returns a new float matrix which is the second argument subtracted from the first.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(3 6 9 12 15 18))) ;; ==> a (define b (e::make-float-matrix-from-vector 2 3 '#(2 4 6 8 10 12))) ;; ==> b (e::float-matrix-subtract a b) ;; ==> ;; 1. 2. 3. ;; 4. 5. 6.
Type:
Procedure.
Operation:
Is the argument a symmetric float matrix?
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a symmetric float matrix. Returns #f otherwise.
For Example:
(define a (e::make-float-matrix-from-vector 2 3 '#(1 2 3 4 5 6))) ;; ==> a (define b (e::make-float-matrix-from-vector 3 3 '#(5 2 2 1 8 3 2 3 13))) ;; ==> b (define c (e::make-float-matrix-from-vector 3 3 '#(5 1 2 1 8 3 2 3 13))) ;; ==> c (e::float-matrix-symmetric? #t) ;; ==> #f (e::float-matrix-symmetric? a) ;; ==> #f (e::float-matrix-symmetric? b) ;; ==> #f (e::float-matrix-symmetric? c) ;; ==> #t
Type:
Procedure.
Operation:
Calculate the trace of the given float matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
An inexact real: The trace of the matrix.
For Example:
(define a (e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> a (e::float-matrix-trace a) ;; ==> 5.
Type:
Procedure.
Operation:
Calculate the transpose of the given float matrix.
Rationale, Explanation, Excuses:
Generally useful.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
Returns a new float matrix which is the transpose of the argument.
For Example:
(define a (e::make-float-matrix-from-vector 3 3 '#(1 2 3 4 5 6 7 8 9))) ;; ==> a (e::float-matrix-transpose a) ;; ==> ;; 1. 4. 7. ;; 2. 5. 8. ;; 3. 6. 9.
Type:
Procedure.
Operation:
Transpose the given matrix.
Rationale, Explanation, Excuses:
Useful to reduce Scheme main memory use when the un-transposed matrix is no longer needed.
Arguments:
One square float matrix.
Side Effects:
Modifies the given float matrix: Turns it into its transpose.
Returned Value:
The given matrix, after being transposed.
For Example:
(define a (e::make-float-matrix-from-vector 3 3 '#(1 2 3 4 5 6 7 8 9))) ;; ==> a a ;; ==> ;; 1. 2. 3. ;; 4. 5. 6. ;; 7. 8. 9. (e::float-matrix-transpose-square-matrix! a) ;; ==> ;; 1. 4. 7. ;; 2. 5. 8. ;; 3. 6. 9.
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:
(define a (delay (+ 2 2))) ;; ==> a (e::forced? a) ;; ==> #f (force a) ;; ==> 4 (e::forced? a) ;; ==> #t
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:
(e::forgettable? (e::make-forgettable #t 0 0)) ;; ==> #t (e::forgettable? #t) ;; ==> #f
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:
(e::forgettable-expiration-time (e::make-forgettable "foo" 5000000000 0.6)) ;; ==> ;; #<Multiple Values Return> ;; List of values: (#t #e5.e9)
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:
(define foo (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
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.
Wraith Scheme provides the procedure e::atom? to determine what kinds of objects are atoms.
For Example:
(e::forgettable-object (e::make-forgettable "foo" 5000000000 0.6)) ;; ==> ;; #<Multiple Values Return> ;; List of values: (#t "foo")
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:
(define foo (e::make-forgettable #t 0 1)) ;; ==> 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
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:
(e::forgettable-remember-probability (e::make-forgettable "foo" 5000000000 0.6)) ;; ==> #<Multiple Values Return> List of values: (#t 0.6)
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:
(define foo (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
Type:
Procedure.
Operation:
Cause garbage collection.
Rationale, Explanation, Excuses:
Garbage collection happens automatically, when Wraith Scheme's 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 Wraith Scheme 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:
(e::full-gc) ;; Wraith Scheme garbage collects. ;; ==> #t
Type:
Procedure.
Operation:
Generate a symbol that has no value or binding.
This operation is atomic, in the sense that even if many Wraith Scheme 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 Wraith Scheme 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:
(e::gensym) ;; ==> g23000
Type:
Procedure.
Operation:
Obtain the 64-bit tag portion of the Wraith Scheme tagged aval associated with a Wraith Scheme object.
Rationale, Explanation, Excuses:
This procedure provides a low-level view of part of the structure of Wraith Scheme objects. I implemented it to aid in debugging Wraith Scheme.
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:
(e::get-tag 42) ;; ==> 57 ;; #b111001
Type:
Procedure.
Operation:
Hides the Wraith Scheme 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. Affects only the sense lights of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme sense lights.
Arguments:
None.
Side Effects:
Makes all of the Wraith Scheme sense lights invisible.
Returned Value:
#t
For Example:
(e::hide-sense-lights!) ;; ==> #t, and makes the sense lights invisible.
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:
Wraith Scheme 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:
(e::inf? #t) ;; ==> #f (e::inf? 3) ;; ==> #f (e::inf? 1.e10000) ;; ==> #t (e::inf? 1+1.e1000i) ;; ==> #t (e::inf? 1/0) ;; ==> #t
Type:
Procedure.
Operation:
Report a useful selection of information about the low-level structure of a Wraith Scheme object.
Rationale, Explanation, Excuses:
I installed this procedure primarily for debugging Wraith Scheme. It is also useful for satisfying one's curiosity about what Wraith Scheme 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 Wraith Scheme 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:
;; 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> ;; When there is more than one Wraith Scheme process active, e::inspect will ;; also print out the number of the kitten in which it was called. Thus, ;; assuming that someone somewhere has defined "foo" to be eleven, then ;; using e::inspect to investigate it on kitten two will yield ... (e::inspect foo) ;; ==> 0000000000000039-000000000000000b: Exact Short Fixnum -- Not a Car (Kitten 2) 11
Type:
Procedure.
Operation:
Provide a lengthy human-readable description of the contents of a Wraith Scheme world file.
Rationale, Explanation, Excuses:
I implemented this procedure for debugging Wraith Scheme's mechanisms for loading and storing worlds.
WARNING: Wraith Scheme does a poor job of identifying world files. Using "e::inspect-world" with a file that is not actually a Wraith Scheme world file may cause Wraith Scheme to crash.
Caution: A very large world file may cause this procedure to produce hundreds of GBytes of text output -- or at least to try to do so -- and there is no way to preselect just part of it: When I use "e::inspect-world" for debugging, I use small world files.
Arguments:
At most one: If there is an argument, it should be a string containing a Unix-style path to a Wraith Scheme world file; if there is no argument, Wraith Scheme will use the Dialog Panel to obtain a path.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::inspect-world "<the default Wraith Scheme world>") ;; ==> ;; Lots of output ;; If you would like to see what a world file dump ;; looks like, use the Wraith Scheme Instrument Panel ;; to obtain the path to the standard Wraith Scheme world ;; -- the default one that gets loaded when Wraith Scheme ;; is launched, and try "e::inspect-world" with that one. (e::inspect-world) ;; Wraith Scheme uses Dialog Panel ;; to obtain a path to the file ;; to be inspected. ;; ==> #t
Type:
Procedure.
Operation:
Obtain the pathname for the file used to memory-map Wraith Scheme's interrupt flags and Unix process identifications, and its size.
Rationale, Explanation, Excuses:
Part of the mechanism for allowing Wraith Scheme to deal with to "SIGUSR1" Unix software interrupts.
Arguments:
None.
Side Effects:
None.
Returned Value:
Multiple-values return: The first item is a string containing the full absolute pathname of the file used to memory-map Wraith Scheme's interrupt flags and Unix process identifications, the second item is the size of that file in bytes.
For Example:
(e::interrupt-file-information) ;; ==> #<Multiple Values Return> ;; List of values: ("/Users/JayFreeman/Library/Application Support/WraithScheme/Wraith Scheme Interrupt Information" 1088)
Type:
Procedure.
Operation:
Return the kitten number of the Wraith Scheme process where called.
Rationale, Explanation, Excuses:
Provides elementary information about parallel instances of Wraith Scheme.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: The kitten number of the process in which the procedure was called.
For Example:
(e::kitten-number) ;; ==> 0 ;; In MomCat (e::kitten-number) ;; ==> 7 ;; In kitten 7
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, report the color currently in use for drawing in the kitten graphics window of the kitten where the procedure was called.
Rationale, Explanation, Excuses:
Useful for kitten graphics procedures.
Arguments:
None.
Side Effects:
None.
Returned Value:
An exact integer representing the color used for drawing in the kitten graphics window of the kitten where the procedure was called.
For Example:
(e::kitty-color) ;; ==> 1, perhaps, which would be red.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, report whether or not the argument is a number representing a kitty pen color.
Rationale, Explanation, Excuses:
Useful for kitten graphics procedures.
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 for kitty pen colors; that is, in the range [0..9]. Otherwise, returns #f.
For Example:
(e::kitty-color? 3) ;; ==> #t (e::kitty-color? 10) ;; ==> #f (e::kitty-color? #t) ;; ==> #f
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, reposition the kitty to her home position and orientation, which is in the middle of the drawing area of the Wraith Scheme Kitten Graphics Window, facing upward.
This operation may also be performed by pressing the "Kitty Come Home" button, located near the lower right corner of the Wraith Scheme Kitten Graphics Window.
If you perform this operation by pushing the button, and the kitty is in motion when you do so, the motion will not stop: It is possible that the kitty will move away immediately. To stop the kitty, you must reset Wraith Scheme to top level.
This operation works whether the kitty is visible or not, and does not change the visibility of the kitty, only her location.
The kitty does not draw anything during her journey homeward.
Rationale, Explanation, Excuses:
Repositions and reorients the pen of the drawing system to a known state. This operation is particularly useful if the kitty has somehow escaped from the drawing area of the Wraith Scheme Kitten Graphics Window.
Arguments:
None.
Side Effects:
Repositions the kitty.
Returned Value:
#t
For Example:
(e::kitty-come-home) ;; ==> Moves the kitty to the center of the drawing area, facing up.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, erase the entire drawing.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
None.
Side Effects:
Erases the drawing.
Returned Value:
#t
For Example:
(e::kitty-erase-drawing) ;; ==> Erases the drawing.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, move the kitty forward the number of points (Macintosh screen coordinates) that is the argument. With an argument that is a negative number, move the kitty backward.
The kitty will draw a line during this operation if, and only if, the pen is down.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
One real number, taken to be the number of points for the kitty to move. Positive numbers cause the kitty to move forward; negative numbers cause the kitty to back up.
Side Effects:
Moves the kitty. If the pen is down, draws a line.
Returned Value:
#t
For Example:
(e::kitty-forward 40) ;; ==> Moves the kitty forward 50 points. ;; If the pen is down, draws a line.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, retrieve the kitty's heading -- the direction in which she is facing. Headings are measured in degrees, in the range [0 .. 360). A heading of 0 corresponds to the kitty facing straight up. Headings increase clockwise; thus for example, a heading of 90 corresponds to the kitty facing to the right.
Rationale, Explanation, Excuses:
Basic drawing instrumentation.
Arguments:
None.
Side Effects:
None.
Returned Value:
A real number: The kitty heading, in degrees.
For Example:
(e::kitty-heading) ;; ==> The kitty heading, e.g., "45" ...
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, make the kitty invisible.
This operation may also be performed by pressing the "Hide Kitty" button, located near the lower right corner of the Wraith Scheme Kitten Graphics Window. That button has the title "Hide Kitty" when the kitty is visible, and "Show Kitty" when the kitty is invisible.
The kitty's ability to draw has nothing to do with whether she is visible or not. The kitty will draw whenever the pen is down, without regard to her visibility.
Rationale, Explanation, Excuses:
Useful for seeing the drawing without the kitty getting in the way.
Arguments:
None.
Side Effects:
Hides the kitty.
Returned Value:
#t
For Example:
(e::kitty-hide) ;; ==> Hides the kitty.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, make the kitty turn left by the number of degrees which is its argument. Negative numbers make the kitty turn right.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
A real number, taken to be the number of degrees to the left that the kitty is to turn.
Side Effects:
Changes kitty orientation.
Returned Value:
#t
For Example:
(e::kitty-left 90) ;; ==> Kitty makes a ninety-degree turn to the left.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, report the line width currently in use for drawing.
Rationale, Explanation, Excuses:
Useful for kitten graphics procedures.
Arguments:
None.
Side Effects:
None.
Returned Value:
A real number: The current width of lines that will be drawn, in points (Macintosh screen coordinate units).
For Example:
(e::kitty-line-width) ;; ==> 1, e.g. (which is the default).
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, report whether or not the argument is a number representing a line width permitted for drawing.
Rationale, Explanation, Excuses:
Useful for kitten graphics procedures.
Arguments:
One scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is an exact real in the range allowed for kitty line widths; that is, in the range [0..10]. Otherwise, returns #f.
For Example:
(e::kitty-line-width? 3) ;; ==> #t (e::kitty-line-width? 10) ;; ==> #f (e::kitty-line-width? #t) ;; ==> #f
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, tell the kitty to start drawing. The kitty will continue drawing until advised otherwise, except when she is being brought home by the "e::kitty-come-home" operation.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
None.
Side Effects:
Puts the kitty in a state in which lines will be drawn when she moves.
Returned Value:
#t
For Example:
(e::kitty-pen-down) ;; ==> Kitty starts drawing.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, report whether or not the kitty is drawing; that is, whether or not the pen is down.
Rationale, Explanation, Excuses:
Useful for kitten graphics procedures.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the pen is down. Otherwise, returns #f.
For Example:
(e::kitty-pen-down?) ;; ==> Kitty starts drawing.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, tell the kitty to stop drawing. The kitty will do no further drawing until advised otherwise.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
None.
Side Effects:
Puts the kitty in a state in which nothing will be drawn when she moves.
Returned Value:
#t
For Example:
(e::kitty-pen-up) ;; ==> Kitty stops drawing.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, make the kitty turn right by the number of degrees which is its argument. Negative numbers make the kitty turn left.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
A real number, taken to be the number of degrees to the right that the kitty is to turn.
Side Effects:
Changes kitty orientation.
Returned Value:
#t
For Example:
(e::kitty-right 45) ;; ==> Kitty turns forty-five degrees to the right.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, change the color with which lines will be drawn. This operation does not change whether the pen is up or down, and does not change the color of any lines that have already been drawn.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
One exact integer, representing the line color to be used.
Line colors are represented by exact integers, as follows:
The reason for the rather odd order of colors is so that the same numbers may be used for sense light colors as for line colors, with similar result. Wraith Scheme sense lights predate Wraith Scheme kitten graphics, and only the integers [0..7] are used for sense light colors.
Side Effects:
Changes the color of subsequent lines.
Returned Value:
#t
For Example:
(e::kitty-set-color 6) ;; ==> Future lines will be drawn in magenta.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, change the width of lines to be drawn. This operation does not change whether the pen is up or down, and does not change the width of any lines that have already been drawn.
Rationale, Explanation, Excuses:
Basic drawing primitive.
Arguments:
One exact real number not less than zero and not greater than ten, representing the line width in points (Macintosh screen coordinates) to use for drawing.
Side Effects:
Changes the width of subsequent lines.
Returned Value:
#t
For Example:
(e::kitty-set-line-width #e6.5) ;; ==> Future lines will have a width of 6.5 points.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, make the kitty visible.
This operation may also be performed by pressing the "Show Kitty" button, located near the lower right corner of the Wraith Scheme Kitten Graphics Window. That button has the title "Show Kitty" when the kitty is invisible, and "Hide Kitty" when the kitty is visible.
The kitty's ability to draw has nothing to do with whether she is visible or not. The kitty will draw whenever the pen is down, without regard to her visibility.
Rationale, Explanation, Excuses:
Useful as a visual cue of pen location and orientation.
Arguments:
None.
Side Effects:
Shows the kitty.
Returned Value:
#t
For Example:
(e::kitty-show) ;; ==> Shows the kitty.
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, retrieve the x coordinate of the kitty's position, measured in points (Macintosh screen coordinates). The x coordinate axis is horizontal. The x coordinate increases to the right, and is zero at the lower left corner of the drawing area of the Wraith Scheme Kitten Graphics Window.
Rationale, Explanation, Excuses:
Basic drawing instrumentation.
Arguments:
None.
Side Effects:
None.
Returned Value:
A real number: The kitty x coordinate, in points.
For Example:
(e::kitty-x) ;; ==> The kitty x coordinate, e.g., "25.0617".
Type:
Procedure.
Operation:
In the Wraith Scheme Kitten Graphics system, in the kitten graphics window of the kitten where the procedure was called, retrieve the y coordinate of the kitty's position, measured in points (Macintosh screen coordinates). The y coordinate axis is vertical. The y coordinate increases upward, and is zero at the lower left corner of the drawing area of the Wraith Scheme Kitten Graphics Window.
Rationale, Explanation, Excuses:
Basic drawing instrumentation.
Arguments:
None.
Side Effects:
None.
Returned Value:
A real number: The kitty y coordinate, in points.
For Example:
(e::kitty-y) ;; ==> The kitty y coordinate, e.g., "42.137".
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, Wraith Scheme 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:
list-print-depth list-print-length vector-print-depth vector-print-length
Current values of all these variables are displayed in the Wraith Scheme 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:
(foo bar baz frob quux mumble ...)
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:
(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 ...)
Type:
Procedure.
Operation:
Load a "package" and export some of its definitions into the calling environment. The package is represented by a file of Scheme code: Any file which could be loaded in the regular manner, by the regular “load” command, will do. All bindings that it creates (e.g., by the use of define) are hidden in a special environment, and are not visible at top level, or in the calling environment, or in any other environment, except for those that are explicitly exported. If procedures in the file being loaded call one another, the relevant bindings are resolved in the hidden environment, so that those procedures work together properly.
Bindings created in the file may be exported with their original names, or with any name you choose to give them.
Rationale, Explanation, Excuses:
A package system is handy, both for keeping the top-level namespace uncluttered and for resolving conflicts between instances of the same name used in different blocks of code.
Arguments:
Two: The first a string providing the path to a file to be loaded, the second a list of "export descriptors" indicating which bindings are to be exported, and under what names.
An export descriptor is either
Side Effects:
Depends on the content of the file, and on the arguments to the procedure.
Returned Value:
#t
For Example:
;; Suppose the file "PackageCode.s" contains the following: (define (foo123) (bar456 1)) (define (bar456 x) (baz789 x)) (define (baz789 x) (display "This is baz789\n") (display x)(newline)) ;; Then the top-level command sequence (define foo123 #t) (define bar456 #t) (define baz789 #t) ((lambda () (e::load-and-export-to-calling-environment "PackageCode.s" '(foo123 (bar456 bar))) (foo123) (bar 1))) foo123 bar456 baz789 ;; will produce the following (showing the output separate from the input for clarity): ;; (Note that the procedure itself produces several lines of output messages.) ;; These from the original defines of foo123, bar456, and baz789: foo123 bar456 baz789 ;; These from e::load-and-export-to-calling-environment: Loading from file "PackageCode.s" ... foo123 bar456 baz789 Starting to process and export symbols ... Exporting foo123. Exporting bar456 as bar. Exported: (foo123 bar) #t ;; These from evaluating (foo123) and (baz) in the calling environment: This is baz789 1 #t This is baz789 1 #t ;; These from evaluating the symbols foo123, bar456 and baz789 in the top-level environment: ;; (Note that the original top-level definitions have not been overwritten.) #t #t #t
Type:
Procedure.
Operation:
Load a "package" and export some of its definitions into the top-level environment. The package is represented by a file of Scheme code: Any file which could be loaded in the regular manner, by the regular “load” command, will do. All bindings that it creates (e.g., by the use of define) are hidden in a special environment, and are not visible at top level or in any other environment, except for those that are explicitly exported. If procedures in the file being loaded call one another, the relevant bindings are resolved in the hidden environment, so that those procedures work together properly.
Bindings created in the file may be exported with their original names, or with any name you choose to give them.
Rationale, Explanation, Excuses:
A package system is handy, both for keeping the top-level namespace uncluttered and for resolving conflicts between instances of the same name used in different blocks of code.
Arguments:
Two: The first a string providing the path to a file to be loaded, the second a list of "export descriptors" indicating which bindings are to be exported, and under what names.
An export descriptor is either
Side Effects:
Depends on the content of the file, and on the arguments to the procedure.
Returned Value:
#t
For Example:
;; Suppose the file "PackageCode.s" contains the following: (define (foo123) (bar456 1)) (define (bar456 x) (baz789 x)) (define (baz789 x) (display "This is baz789\n") (display x)(newline)) ;; Then the top-level command sequence (define foo123 #t) (define bar456 #t) (define baz789 #t) (e::load-and-export-to-top-level "PackageCode.s" '(foo123 (bar456 bar))) (foo123) (bar 1) foo123 bar456 baz789 ;; will produce the following (showing the output separate from the input for clarity): ;; (Note that the procedure itself produces several lines of output messages.) ;; These from the original defines of foo123, bar456, and baz789: foo123 bar456 baz789 ;; These from e::load-and-export-to-top-level: Loading from file "PackageCode.s" ... foo123 bar456 baz789 Starting to process and export symbols ... Exporting foo123. Exporting bar456 as bar. Exported: (foo123 bar) #t ;; These from evaluating (foo123) and (baz) in the top-level environment: This is baz789 1 #t This is baz789 1 #t ;; These from evaluating foo123, bar456 and baz789 in the top-level environment: ;; (Note that the original top-level definitions of bar456 and baz789 ;; have not been overwritten.) #<Interpreted lambda expression, possibly named "foo123"> #t #t
Type:
Procedure.
Operation:
Load a Wraith Scheme world file.
Only the MomCat may perform this procedure; calling this procedure in any other Wraith Scheme process will cause an error.
Rationale, Explanation, Excuses:
A world file is a machine-readable image of the entire content of Wraith Scheme main memory. Storing one saves the what you were working on in Wraith Scheme so that you may resume work in another session. Loading one restores that saved work.
Arguments:
At most one: If there is an argument, it should be a string containing a Unix-style path to a Wraith Scheme world file; if there is no argument, Wraith Scheme will use the Dialog Panel to obtain a path.
Side Effects:
Overwrites all of Wraith Scheme's main memory.
Returned Value:
Does not apply; after a world load, Wraith Scheme will reset to the top-level loop.
For Example:
(e::load-world! "MyFavoriteWorld") ;; ==> ;; Load world and reset. (e::load-world) ;; Wraith Scheme uses Dialog Panel ;; to obtain a path to the file ;; to be used. ;; ==> #t
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. Wraith Scheme 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:
(e::logic-constant? #t) ;; ==> #f (e::logic-constant? #u) ;; ==> #t (e::logic-constant? #s) ;; ==> #t
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 Wraith Scheme'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:
(e::long-complex? 1+i) ;; ==> #t (e::long-complex? 3) ;; ==> #f (e::long-complex? #t) ;; ==> #f
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 Wraith Scheme'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:
(e::long-ratnum? 1/3) ;; ==> #t (e::long-ratnum? 3.2) ;; ==> #f (e::long-ratnum? #t) ;; ==> #f
Type:
Operation:
Create a Wraith Scheme low-level macro, and make it be the value of a symbol.
Rationale, Explanation, Excuses:
The macros referred to are Wraith Scheme's low-level internal implementation, not the hygienic macros defined in the R5 report.
A "call" or invocation of a Wraith Scheme 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 Wraith Scheme, to produce the result of the macro "call".
"e::macro" creates the procedure in question, makes it part of a Wraith Scheme low-level macro object, and binds that object to a symbol -- the symbol being what we might informally call the macro's "name".
The Wraith Scheme 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 Wraith Scheme 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:
;; 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!!
Type:
Operation:
Create a Wraith Scheme low-level macro, but do not bind it to a symbol.
Rationale, Explanation, Excuses:
The macros referred to are Wraith Scheme's low-level internal implementation, not the macros defined in the R5 report.
A "call" or invocation of a Wraith Scheme 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 Wraith Scheme, to produce the result of the macro "call".
"e::macro-body" creates the procedure in question and makes it part of a Wraith Scheme low-level macro object, but does not bind that object to a symbol -- less formally, the object is not given a "name".
The Wraith Scheme 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 Wraith Scheme 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:
;; 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!!
Type:
Procedure.
Operation:
Test whether a Scheme object is a Wraith Scheme low-level macro.
Rationale, Explanation, Excuses:
The macros referred to are Wraith Scheme'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 Wraith Scheme low-level macro. Otherwise, returns #f.
For Example:
(e::macro? define) ;; ==> #t (e::macro? cons) ;; ==> #f
Type:
Wraith Scheme does not define a value for "e::main"; the intent is, that the symbol "e::main" may be bound to a lambda expression of your choice.
Operation:
Whatever you like.
Rationale, Explanation, Excuses:
The procedure "e::main" is not defined by Wraith Scheme; indeed, the symbol "e::main" does not even exist in the distributed version of Wraith Scheme! It is you who may, if you wish, define "e::main". You may make it be any lambda expression of no arguments that you like.
If you save a world in which "e::main" is a lambda expression of no arguments, then whenever that world is loaded into a Wraith Scheme process, "e::main" will be executed immediately after the world has loaded. If you are running parallel Wraith Scheme processes -- more than one kitten -- only the MomCat will execute "e::main".
Use of "e::main" makes it possible to start something happening automatically in a newly-loaded world.
If Wraith Scheme loads a world in which "e::main" is bound to a Wraith Scheme object that is not a lambda expression, it will do nothing with the bound value; in particular, it will not evaluate or print out that value. The world load will then be ready for use.
Arguments:
None. Wraith Scheme will report an error if it loads a world in which "e::main" is bound to a lambda expression that requires one or more arguments. The error will be reported after the world load has completed, and the loaded world will then be ready for use.
Side Effects:
Whatever you like.
Returned Value:
Whatever you like.
For Example:
(define (e::main) (display "Hello, world!\n")) ;; ==> e::main ;; If you now save a world, and then reload it at some other ;; time, the Wraith Scheme Momcat will run "e::main" ;; immediately after loading the world, and will print ;; "Hello, world!" in the Wraith Scheme Main Display Panel.
Type:
Procedure.
Operation:
Create a new float matrix, optionally with all elements set to a given value.
Rationale, Explanation, Excuses:
Constructor for float matrices.
Arguments:
Two or three: The first two, exact integers which are respectively the number of rows and the number of columns in the desired float matrix; The optional third, a real number to be used as the value of all elements of the matrix created. If there is no third argument, all matrix elements will be zero.
Side Effects:
Creates a new float matrix, optionally with all elements set to a given value.
Returned Value:
A new instance of float matrix, optionally with all elements set to a given value.
For Example:
(e::make-float-matrix 2 2) ;; ==> ;; 0. 0. ;; 0. 0. (e::make-float-matrix 2 2 42) ;; ==> ;; 42. 42. ;; 42. 42.
Type:
Procedure.
Operation:
Create a new float matrix with elements loaded in row-major order from the given Scheme vector.
Rationale, Explanation, Excuses:
Useful constructor for float matrices.
Arguments:
One Scheme vector.
Side Effects:
Creates a new float matrix.
Returned Value:
A new instance of float matrix, with elements loaded in row-major order from the given Scheme vector.
For Example:
(e::make-float-matrix-from-vector 2 2 '#(1 2 3 4))) ;; ==> ;; 1. 2. ;; 3. 4.
Type:
Procedure.
Operation:
Create a new identity float matrix.
Rationale, Explanation, Excuses:
Useful constructor for float matrices.
Arguments:
One exact integer: The side of the matrix to be created.
Side Effects:
Creates a new identity float matrix of the specified side.
Returned Value:
A new instance of an identity float matrix.
For Example:
(e::make-float-matrix-identity 4) ;; ==> ;; 1. 0. 0. 0. ;; 0. 1. 0. 0. ;; 0. 0. 1. 0. ;; 0. 0. 0. 1.
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:
(e::make-forgettable (cons 1 2) 1247692518 0.75) ;; ==> #<Forgettable Object Pointer, unexpired, expiration time 1247692518 (GMT 2009.07.15 21:15:18)>
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:
(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) ;; ==> ()
Type:
Procedure.
Operation:
Create a rational number in which the numerator and denominator are stored separately.
Rationale, Explanation, Excuses:
Useful for dealing with Wraith Scheme'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:
(e::make-long-ratnum 1 3) ;; ==> 1/3 (e::make-long-ratnum 1. 3) ;; ==> #i1/3 (e::make-long-ratnum 1 -3) ;; ==> -1/3
Type:
Procedure.
Operation:
Allocate a memory-mapped area of memory to share with other processes, mapped into the address space of the Wraith Scheme process in which this procedure is executed. Create a file and associate it with that area. (Unlinks any preexisting file at the same path.) Fill the file with zeros. Return a Wraith Scheme object encapsulating details of the memory-mapped area, and containing a pointer to it.
Rationale, Explanation, Excuses:
Constructor for memory-mapped blocks.
Arguments:
Two: The first, a nonnegative integer representing the desired size in bytes of the memory-mapped block, the second a string containing the path -- relative or absolute -- to the file to be created and associated with the block.
Side Effects:
Creates a new memory-mapped area and also creates a file associated with it.
Returned Value:
A Wraith Scheme "memory-mapped block" object describing and locating the new memory-mapped area.
For Example:
;; Executed in the MomCat (e::make-memory-mapped-block 1000 "/tmp/foo") ;; ==> #<Memory-Mapped Block, size 1000, path "/tmp/foo", memory mapped for kitten 0>
Type:
Procedure.
Operation:
Assist in defining variables which are the offsets within a memory-mapped-block of particular variables stored in that block.
Rationale, Explanation, Excuses:
Useful for dealing systematically with the locations of variables in a memory-mapped block; Subsumes some of the uses of a C or C++ structure definition.
Arguments:
Two: The first, an integer representing the offset of the first variable whose offset is to be calculated, the second a list of lists of variable names and sizes.
Side Effects:
For each variable in the second argument -- e.g., "my-variable" -- defines a new variable whose name is created by appending "-offset" to the name of the given variable (e.g., "my-variable-offset"), and whose value is the running total of the first argument plus the sizes of all previous variables in the second argument.
Technical Note: C and C++ structure definitions often insert padding between variables, to maintain correct alignment for memory access. This procedure offers no ability to insert padding in the offset definitions: You will have to create and use your own dummy variables where necessary, or locate your variables in such a way that padding is not necessary, or both.
The procedure actually executes "define" statements; the new variables thereby created will thereby be local to the environment in which "e::make-offsets" is executed. It is perhaps most useful if that environment is the top-level environment.
Note that executing this procedure does not create any memory-mapped area, or attempt to dereference any of the pointers thereby created. Rather, "e::make-offsets" merely sets up and names pointers for subsequent use.
Returned Value:
The sum of all the variable sizes in the second argument; that is, the total size of the block of variables declared.
For Example:
(define size-of-long-long 8) ;; ==> size-of-long-long (define size-of-char 1) ;; ==> size-of-char (define size-of-word 4) ;; ==> size-of-word (define initial-offset 42) ;; ==> initial-offset (define size-of-block (e::make-offsets initial-offset `( (my-first-char ,size-of-char) (my-second-char ,size-of-char) (my-first-word ,size-of-word) (my-first-long-long ,size-of-long-long) (my-second-word ,size-of-word) ))) ;; ==> size-of-block size-of-block ;; ==> 18 (18 is in fact the sum of the byte ;; lengths of two 8-bit chars, two ;; 32-bit words, and a 64-bit long long) ;; Executing "e::make-offsets" has created some ;; brand new variables that show where in the ;; block the given variables are located (byte ;; offsets), as follows: my-first-char-offset ;; ==> 42 my-second-char-offset ;; ==> 43 my-first-word-offset ;; ==> 44 my-first-long-long-offset ;; ==> 48 my-second-word-offset ;; ==> 56
Type:
Procedure.
Operation:
Create a class in the Wraith Scheme class system. See the section of the Wraith Scheme 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 Wraith Scheme 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 Wraith Scheme class system.
For Example:
(define bar (e::make-simple-class 'bar '() '() '())) ;; ==> bar (define baz (e::make-simple-class 'baz `(,bar) '((c 1)) '((a 1) (b 2)))) ;; ==> baz
Type:
Procedure.
Operation:
Use the details of a memory-mapped block representing an area of memory that has already been memory-mapped into the address space of one or more Wraith Scheme processes, to map the same area -- same address and associated file -- into the address space of an additional Wraith Scheme process, which thereby gains access to the shared memory. Does not alter the associated file. Has no effect if the block has already been mapped by that Wraith Scheme process.
Rationale, Explanation, Excuses:
Allows more than one Wraith Scheme process to share the same memory-mapped area.
Arguments:
A Wraith Scheme memory-mapped block object.
Side Effects:
Memory-maps the given block -- same address and same associated file -- into the address space of the Wraith Scheme process that executes this procedure. Has no effect if the block has already been mapped by that Wraith Scheme process.
Returned Value:
#t
For Example:
;; Executed in the MomCat: (define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a ;; Executed in kitten 1: (e::memory-map-block-in-current-kitten a) #t
Type:
Procedure.
Operation:
At startup, Wraith Scheme reserves a region of memory for memory-mapped blocks; this procedure returns the size in bytes of the portion of that area that is yet unused.
Rationale, Explanation, Excuses:
Provide administrative information for dealing with memory-mapped blocks.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer, representing the size in bytes of the portion of Wraith Scheme's address space reserved for memory-mapped blocks, that is yet unused.
For Example:
(e::memory-mappable-space-size) ;; ==> 15663104
Type:
Procedure.
Operation:
Test whether a Scheme object is a memory-mapped block.
Rationale, Explanation, Excuses:
Predicate to identify objects of this type.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the argument is a memory-mapped block. Otherwise, returns #f.
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::memory-mapped-block? a) ;; ==> #t (e::memory-mapped-block? 42) ;; ==> #f
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:
(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))
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:
(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))
Type:
Procedure.
Operation:
Returns whether or not the Wraith Scheme process in which it was called is the MomCat.
Rationale, Explanation, Excuses:
Provides elementary information about parallel instances of Wraith Scheme.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean. Returns #t if, and only if, called in the MomCat. Otherwise, returns #f
For Example:
(e::momcat?) ;; ==> #t ;; In MomCat (e::momcat?) ;; ==> #f ;; In kittens 1 through 7
Type:
Procedure.
Operation:
Construct a Wraith Scheme 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:
(e::money->string 29.95) ;; ==> "29.95"
Type:
Procedure.
Operation:
Test whether a Scheme object is a "multiple-values return" -- a special type of Scheme object used by Wraith Scheme as an intermediary between "values" and "call-with-values".
Rationale, Explanation, Excuses:
"Multiple-values returns" are a class of object peculiar to Wraith Scheme, 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:
(e::multiple-values? (values 1 2 3)) ;; ==> #t (e::multiple-values? #t) ;; ==> #f (e::multiple-values? 42) ;; ==> #f
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. If the object in question is a complex number, returns #t if one or both of its real and imaginary parts are nans. Also returns #t if the object is a rational whose numerator and denominator are stored separately and are both zero.
Rationale, Explanation, Excuses:
Wraith Scheme 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:
(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::nan? (make-rectangular 1 (/ 0 0))) ;; ==> #t (e::nan? 0/0) ;; ==> #t
Type:
Procedure.
Operation:
Test whether the amount of Wraith Scheme main memory in use equals or exceeds ninety percent of the amount available.
Rationale, Explanation, Excuses:
It may occasionally be useful to know when Wraith Scheme 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 Wraith Scheme main memory in use equals or exceeds ninety percent of the amount available. Otherwise, returns #f
For Example:
(e::ninety-percent-used?) ;; ==> #f
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:
(e::non-printing-object? #t) ;; ==> #f (e::non-printing-object? #n) ;; ==> #t
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:
(e::not-null? #t) ;; ==> #t (e::not-null? #f) ;; ==> #t (e::not-null? '()) ;; ==> #f
Type:
Procedure.
Operation:
Return the number of kittens running in parallel that were present when the current group of parallel Wraith Scheme processes was started. That is, this number does not change if a kitten exits for some reason, or if you cause it to exit -- for example, by means of the "Quit" command.
The MomCat is not included in this count.
Rationale, Explanation, Excuses:
Provides elementary information about parallel instances of Wraith Scheme.
Arguments:
None.
Side Effects:
None.
Returned Value:
For Example:
(e::number-of-kittens) ;; ==> 0 ;; If just the MomCat. (e::number-of-kittens) ;; ==> 7 ;; With the MomCat and 7 kittens.
Type:
Procedure.
Operation:
Construct a Wraith Scheme string containing a real 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:
(e::number->string-with-n-decimals 1/3 3) ;; ==> "0.333" (e::number->string-with-n-decimals (- (/ 1000 3)) 6) ;; ==> "333.333333"
Type:
Procedure.
Operation:
A version of call-with-current-continuation that does not support dynamic-wind.
Rationale, Explanation, Excuses:
Wraith Scheme 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 an atomic test-and-set (with memory barrier) of the least-significant bit of a given 64-bit integer in a memory-mapped block, and return whether the bit was originally zero.
The operation performed is a "locked" bit-test-and-set operation, accomplished by assembly language embedded within Wraith Scheme's C++ code.
Rationale, Explanation, Excuses:
Provide for critical-section locking in memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Two: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the datum that is to be the subject of the atomic test-and-set operation, within that area of memory. The offset must be an integral multiple of eight, and must indicate an area within the range of the memory-mapped block.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the bit tested-and-set was originally 0. Otherwise, returns #f.
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::peek64 a 120) ;; ==> 0 (e::peek-poke-atomic a 120) ;; ==> #t (e::peek-poke-atomic a 120) ;; ==> #f (e::peek64 a 120) ;; ==> 1
Type:
Procedure. (All of them)
Operation:
Read from a memory-mapped area of memory represented by a memory-mapped block. The four procedures allow reads of quantities that are respectively 8, 16, 32 and 64 bits long; that is, one, two, four and eight bytes long.
Note that there is no requirement that the content addressed actually be an integer; Wraith Scheme has no idea of what other programs may have stored at the location indicated. Furthermore, even if the quantities are integers, Wraith Scheme has no idea of whether they are supposed to be exact or not. Wraith scheme resolves this ambiguity by returning exact integers.
Rationale, Explanation, Excuses:
Provide read access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Two: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the datum to be read within that area of memory. The offset must be an integral multiple of the size of the datum in bytes, and must indicate an area within the range of the memory-mapped block.
Side Effects:
None.
Returned Value:
A Wraith Scheme exact signed integer representing the data read. The returned values are not sign-extended; thus for example, a peek8 of a byte with all bits set would return the 64-bit signed integer 255.
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke8 a 0 1) ;; ==> #t (e::poke16 a 2 2) ;; ==> #t (e::poke32 a 4 3) ;; ==> #t (e::poke64 a 8 4) ;; ==> #t (e::peek8 a 0) ;; ==> 1 (e::peek16 a 2) ;; ==> 2 (e::peek32 a 4) ;; ==> 3 (e::peek64 a 8) ;; ==> 4
Type:
Procedure.
Operation:
Read a floating-point number from a memory-mapped area of memory represented by a memory-mapped block.
Rationale, Explanation, Excuses:
Provide read access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Two: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the datum to be read within that area of memory. The offset must be a multiple of eight, and must indicate an area within the range of the memory-mapped block.
Side Effects:
None.
Returned Value:
A Wraith Scheme inexact floating-point number that is numerically equal to the floating point number just read. If the remotely-stored value is not a floating-point number in IEEE 64-bit floating-point format, the returned value is undefined and almost certainly nonsense.
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke64-float a 0 1.25) ;; ==> #t (e::peek64-float a 0) ;; ==> 1.25
Type:
Procedure.
Operation:
Read a vector of floating-point numbers from a memory-mapped area of memory represented by a memory-mapped block.
Rationale, Explanation, Excuses:
Provide read access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the first datum to be read from that area of memory. The offset must be a multiple of eight, and must indicate an area within the range of the memory-mapped block. The third, a vector into which the data read are to be loaded. The length of the vector is the number of data elements to be read.
Side Effects:
Writes data to the given Scheme vector.
Returned Value:
Returns the vector provided as the third argument, as modified. The values loaded into the vector are Wraith Scheme inexact floating-point numbers that are numerically equal to the floating point numbers just read. If any remotely-stored value is not a floating-point number in IEEE 64-bit floating-point format, the corresponding returned value is undefined and almost certainly nonsense.
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (define b '#(1 1.25 1.5)) ;; ==> b (define c (make-vector 3)) ;; ==> c (e::poke64-float-vector a 0 b) ;; ==> #t (e::peek64-float-set-vector! a 0 c) ;; ==> #(1 1.25 1.5) c ;; ==> #(1 1.25 1.5)
Type:
Procedure. (All of them)
Operation:
Load a vector from a memory-mapped area of memory represented by a memory-mapped block. The area of the block from which the data are taken is assumed to be a one-dimensional array of data elements that are all the same length. The four procedures allow loads of quantities that are respectively 8, 16, 32 and 64 bits long; that is, one, two, four and eight bytes long.
Note that there is no requirement that the content addressed actually be integers; Wraith Scheme has no idea of what other programs may have stored at the locations indicated. Furthermore, even if the quantities are integers, Wraith Scheme has no idea of whether they are supposed to be exact or not. Wraith scheme resolves this ambiguity by returning exact integers.
Rationale, Explanation, Excuses:
Provide read access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the first datum to be read within that area of memory. The offset must be an integral multiple of the size of the data in bytes, and must indicate an area within the range of the memory-mapped block. The third a vector, whose length indicates the number of consecutive data elements to be retrieved from the memory-mapped block.
Side Effects:
Writes data to the given Scheme vector.
Returned Value:
Returns the vector provided as the third argument, as modified.
Returned Value:
Each of these procedures returns the vector which is passed in as its third argument, after modification. The contents of the vector will be Wraith Scheme exact signed integers representing the data read. The returned values are not sign-extended; thus for example, a peek8-set-vector! that encountered a byte with all bits set would load the exact 64-bit signed integer 255 into the appropriate place in its vector.
For Example:
(define z (make-vector 4)) ;; ==> z (define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke8 a 0 1) ;; ==> #t (e::poke8 a 1 2) ;; ==> #t (e::poke8 a 2 4) ;; ==> #t (e::poke8 a 3 8) ;; ==> #t (e::peek8-set-vector! a 0 z) ;; ==> #(1 2 4 8) z ;; ==> #(1 2 4 8)
Type:
Procedure. (All of them)
Operation:
Load a vector from a memory-mapped area of memory represented by a memory-mapped block. The area of the block from which the data are taken is assumed to be a one-dimensional array of data elements that are all the same length. The four procedures allow loads of quantities that are respectively 8, 16, 32 and 64 bits long; that is, one, two, four and eight bytes long.
Note that there is no requirement that the content addressed actually be integers; Wraith Scheme has no idea of what other programs may have stored at the locations indicated. Furthermore, even if the quantities are integers, Wraith Scheme has no idea of whether they are supposed to be exact or not. Wraith scheme resolves this ambiguity by returning exact integers.
Rationale, Explanation, Excuses:
Provide read access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the first datum to be read within that area of memory. The offset must be an integral multiple of the size of the data in bytes, and must indicate an area within the range of the memory-mapped block. The third a vector, whose length indicates the number of consecutive data elements to be retrieved from the memory-mapped block.
Side Effects:
Writes data to the given Scheme vector.
Returned Value:
Returns the vector provided as the third argument, as modified.
Returned Value:
Each of these procedures returns the vector which is passed in as its third argument, after modification. The contents of the vector will be Wraith Scheme exact 64-bit signed integers representing the data read. The returned values are sign-extended; thus for example, a peek8-set-vector-sign-extend! that encountered a byte with all bits set would load the exact 64-bit signed integer -1 into the appropriate place in its vector.
For Example:
(define z (make-vector 4)) ;; ==> z (define y (e::make-memory-mapped-block 1000 "/tmp/bar")) ;; ==> y (e::poke16 y 0 #xffff) ;; ==> #t (e::poke16 y 2 2) ;; ==> #t (e::poke16 y 4 4) ;; ==> #t (e::poke16 y 6 #x8000) ;; ==> #t (e::peek16-set-vector-sign-extend! y 0 z) ;; ==> #(-1 2 4 -32768) z ;; ==> #(-1 2 4 -32768)
Type:
Procedure. (All of them)
Operation:
Read and sign-extend from a memory-mapped area of memory represented by a memory-mapped block. The three procedures allow reads of quantities that are respectively 8, 16 and 32 bits long; that is, one, two and four bytes long.
Note that there is no requirement that the content addressed actually be integers; Wraith Scheme has no idea of what other programs may have stored at the locations indicated. Furthermore, even if the quantities are integers, Wraith Scheme has no idea of whether they are supposed to be exact or not. Wraith scheme resolves this ambiguity by returning exact integers.
Rationale, Explanation, Excuses:
Provide read access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Two: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the datum to be read within that area of memory. The offset must be an integral multiple of the size of the datum in bytes, and must indicate an area within the range of the memory-mapped block.
Side Effects:
None.
Returned Value:
A Wraith Scheme exact 64-bit signed integer representing the data read. The returned values are sign-extended; thus for example, a peek8-sign-extend of a byte with all bits set would return the Wraith Scheme exact 64-bit signed integer -1.
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke8 a 0 #xff) ;; ==> #t (e::poke16 a 2 #xffff) ;; ==> #t (e::poke32 a 4 #xffffffff) ;; ==> #t (e::peek8-sign-extend a 0) ;; ==> -1 (e::peek16-sign-extend a 2) ;; ==> -1 (e::peek32-sign-extend a 4) ;; ==> -1 ;; But ... (e::peek8 a 0) ;; ==> 255 (e::peek16 a 2) ;; ==> 65535 (e::peek32 a 4) ;; ==> 4294967295
Type:
Procedure.
Operation:
Read a null-terminated series of bytes -- a "C string" -- from a memory-mapped area of memory represented by a memory-mapped block, and return what was read in the form of a Scheme string.
Rationale, Explanation, Excuses:
Provide read access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Two: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the start location of the string to be read, within that area of memory. The offset must indicate an area within the range of the memory-mapped block.
Side Effects:
None.
Returned Value:
A copy of the string read, in the form of a Scheme string. If no null occurs between the given offset and the end of the memory-mapped block, Wraith Scheme will report an error.
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke-c-string a 23 "Hello, world\n") ;; ==> #t (e::peek-c-string a 23) ;; ==> "Hello, world\n" (display (e::peek-c-string a 23)) ;; Wraith Scheme displays the following: Hello, world #t
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, and to access memory-mapped blocks, which many may consider as allowing side effects, but that block is not allowed to use public Wraith Scheme procedures that change Wraith Scheme internal state; any attempt to use them is treated as an error. The procedures so treated are:
set! set-car! set-cdr! string-fill! string-set! vector-fill! vector-set! e::clear-permanent! e::disable-big-red-button! e::disable-pushbutton! e::enable-big-red-button! e::enable-pushbutton! e::load-world! e::set-current-directory! e::set-input-port! e::set-level-indicator! 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! c::set-blocked-binding!
Returned Value:
Whatever is returned by the block of code that is the passed argument.
For Example:
(e::perform-applicative (lambda () (+ 2 2))) ;; ==> 4
but
(define a 3) (e::perform-applicative (lambda () (set! a 42)))
produces the error message:
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 ...
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 Wraith Scheme 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 a symbol's permanent flag, so you cannot change the value to which it is bound. Procedure "e::permanent?" tests whether that flag 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:
(e::clear-permanent! 'cons) ;; ==> #t (e::permanent? 'cons) ;; ==> #f (e::set-permanent! 'cons) ;; ==> #t (e::permanent? 'cons) ;; ==> #t
Type:
Procedure. (All of them)
Operation:
Write to a memory-mapped area of memory represented by a memory-mapped block. The four procedures allow writes of quantities that are respectively 8, 16, 32 and 64 bits long; that is, one, two, four and eight bytes long.
If any datum provided should happen to be stored in the internal format that Wraith Scheme uses for floating-point numbers, but is nevertheless an integer in the appropriate range, Wraith Scheme will write that quantity in the format appropriate to an integer.
Rationale, Explanation, Excuses:
Provide write access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the location of the write within that area of memory. The offset must be an integral multiple of the size of the datum in bytes, and must indicate an area within the range of the memory-mapped block. The third argument is the datum to be written, which must be an integer in the range appropriate for a 64-bit fixnum. That datum will silently have sufficient high-order bits excised that what remains fits in the space available.
Side Effects:
Writes data in a memory-mapped area of memory.
Returned Value:
#t
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke8 a 0 1) ;; ==> #t (e::poke16 a 2 2) ;; ==> #t (e::poke32 a 4 3) ;; ==> #t (e::poke64 a 8 4) ;; ==> #t (e::peek8 a 0) ;; ==> 1 (e::peek16 a 2) ;; ==> 2 (e::peek32 a 4) ;; ==> 3 (e::peek64 a 8) ;; ==> 4
Type:
Procedure.
Operation:
Store a floating-point number into a memory-mapped area of memory represented by a memory-mapped block.
If any datum provided should happen to be stored in the internal format that Wraith Scheme uses for fixnums, Wraith Scheme will write that datum as an IEEE 64-bit floating-point number. That conversion may result in loss of precision of the number in question.
Rationale, Explanation, Excuses:
Provide write access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the location of the write within that area of memory. The offset must be a multiple of eight, and must indicate an area within the range of the memory-mapped block. The third, a real number, which Wraith Scheme will convert to a floating point format -- if necessary -- before performing the store.
Side Effects:
Writes data in a memory-mapped area of memory.
Returned Value:
#t
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke64-float a 0 1.25) ;; ==> #t (e::peek64-float a 0) ;; ==> 1.25
Type:
Procedure.
Operation:
Store a vector of floating-point numbers into a memory-mapped area of memory represented by a memory-mapped block.
If any datum provided should happen to be stored in the internal format that Wraith Scheme uses for fixnums, Wraith Scheme will write that datum as an IEEE 64-bit floating-point number. That conversion may result in loss of precision of the number in question.
Rationale, Explanation, Excuses:
Provide write access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the location where the write is to begin, within that area of memory. The offset must be a multiple of eight, and must indicate an area within the range of the memory-mapped block. The third, a vector from which the real numbers to be stored are taken. The length of the vector is the number of data elements to be written. If necessary, Wraith Scheme will convert numbers to floating-point format before storing them.
Side Effects:
Writes data in a memory-mapped area of memory.
Returned Value:
#t
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (define b '#(1 1.25 1.5)) ;; ==> b (define c (make-vector 3)) ;; ==> c (e::poke64-float-vector a 0 b) ;; ==> #t (e::peek64-float-set-vector! a 0 c) ;; ==> #(1 1.25 1.5) c ;; ==> #(1 1.25 1.5)
Type:
Procedure. (All of them)
Operation:
Write the contents of a vector to a memory-mapped area of memory represented by a memory-mapped block. The four procedures allow writes of quantities that are respectively 8, 16, 32 and 64 bits long; that is, one, two, four and eight bytes long.
If any datum provided should happen to be stored in the internal format that Wraith Scheme uses for fixnums, Wraith Scheme will write that datum as an IEEE 64-bit floating-point number. That conversion may result in loss of precision of the number in question. These conversions do not change the Scheme vector provided as an argument, they are entirely internal to the procedure itself.
Rationale, Explanation, Excuses:
Provide write access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the location where the write is to begin, within that area of memory. The offset must be an integral multiple of the size of the datum in bytes, and must indicate an area within the range of the memory-mapped block. The third argument is a vector containing the data to be written. Each data element must be an integer in the range appropriate for a 64-bit fixnum. That datum will silently have sufficient high-order bits excised that what remains fits in the space available. The length of the vector is the number of data elements to be written.
Side Effects:
Writes data in a memory-mapped area of memory.
Returned Value:
#t
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (define b '#(1 2 3 4)) ;; ==> b (define c (make-vector 4)) ;; ==> c (e::poke8-vector a 0 b) ;; ==> #t (e::peek8-set-vector! a 0 c) ;; ==> #(1 2 3 4) c ;; ==> #(1 2 3 4)
Type:
Procedure.
Operation:
Write the content of a Scheme string into a memory-mapped area of memory represented by a memory-mapped block, in the form of a null-terminated string of ASCII characters -- a "C string".
Rationale, Explanation, Excuses:
Provide write access to memory-mapped areas of memory represented by memory-mapped blocks.
Arguments:
Three: The first a Wraith Scheme memory-mapped block object, the second a nonnegative integer representing the offset of the location where the write is to begin, within that area of memory, and the third a string. The offset must indicate an area within the range of the memory-mapped block. There must be sufficient room in the given memory-mapped block, beyond the given offset, for the string to fit, including the final null.
Side Effects:
Writes data in a memory-mapped area of memory.
Returned Value:
#t
For Example:
(define a (e::make-memory-mapped-block 1000 "/tmp/foo")) ;; ==> a (e::poke-c-string a 23 "Hello, world\n") ;; ==> #t (e::peek-c-string a 23) ;; ==> "Hello, world\n" (display (e::peek-c-string a 23)) ;; Wraith Scheme displays the following: Hello, world #t
Type:
Procedure.
Operation:
Return the Unix process identification number of the process in which the procedure was called.
Note that the procedure e::show-kittens provides (among other things) the process ids of all members of a group of cooperating Wraith Scheme processes.
Rationale, Explanation, Excuses:
Unix process identification numbers are valuable for examining and controlling Wraith Scheme processes from the Unix command line -- perhaps from the Macintosh "Terminal" application. For example, they might be useful in interpreting output from the Unix "ps" program, or as arguments to the Unix "kill" program.
Arguments:
None.
Side Effects:
None.
Returned Value:
An integer: The Unix process identification number of the Wraith Scheme process in which the procedure was called.
For Example:
;; Process ids are nonnegative integers of up to five digits. (e::process-id) ;; ==> 22316 ;; e.g.,
Type:
Procedure.
Operation:
Find the Wraith Scheme application's directory; that is, the directory of "Wraith Scheme.app".
Rationale, Explanation, Excuses:
Users often organize directories so that files related to a program are in directories only a short pathname from the program itself. Thus a simple means to find the program's directory seems useful.
Arguments:
None.
Side Effects:
None.
Returned Value:
A string: Returns a string containing the absolute Unix path to the directory containing "Wraith Scheme.app". The returned string will end in a '/'.
For Example:
;; Perhaps (e::program-directory) ;; ==> "/Users/JayFreeman/Scheme"
Type:
Procedure.
Operation:
Test whether a Scheme object is a promise.
Rationale, Explanation, Excuses:
In Wraith Scheme, 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:
(e::promise? '()) ;; ==> #f (define a (delay (+ 2 2))) ;; ==> a (e::promise? a) ;; ==> #t (force a) ;; ==> 4 (e::promise? a) ;; ==> #t
Type:
Procedure.
Operation:
Push the elements of the proper list which is its argument, into the Wraith Scheme continuation, cdr end first. Those elements will thus be evaluated, in the same order as they appear in the given list, as soon as "e::push-list-into-continuation" has returned, in the environment in which "e::push-list-into-continuation" was called.
Rationale, Explanation, Excuses:
This procedure is useful in low-level manipulation of the Wraith Scheme continuation.
Arguments:
One proper list.
Side Effects:
Evaluates the items of the list, in the order in which they appear in that list, as soon as "e::push-list-into-continuation" has returned, in the environment in which "e::cons-with-continuation" is called.
Returned Value:
Any Scheme object or objects. Strictly, "e::push-list-into-continuation" does not return: Where you would have expected a return value to appear, what appears instead is the result of evaluating the elements of its argument.
For Example:
(define form-to-be-pushed (list '(display "Hello from the continuation!\n") '(display "Hello again from the continuation!\n") '(display "Hello a third time from the continuation!\n") ) ) (e::push-list-into-continuation form-to-be-pushed) ;; ==> ;; Hello from the continuation! ;; Hello again from the continuation! ;; Hello a third time from the continuation! ;; #t
Type:
Procedure.
Operation:
Tests whether a pushbutton (in the Wraith Scheme Sensory Devices Drawer) is enabled. Applies only to pushbuttons of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Required for checking pushbutton state from Wraith Scheme.
Arguments:
One integer in the range [0..3].
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the given pushbutton is enabled. Otherwise, returns #f. Ignores the exactness of the arguments.
For Example:
(e::pushbutton-enabled? 0) ;; ==> #t -- Pushbutton 0 is enabled.
Type:
Procedure.
Operation:
Return the interrupt number associated with a given pushbutton (in the Wraith Scheme Sensory Devices Drawer). Reports an error if that pushbutton is not enabled. Applies only to pushbuttons of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Required for checking pushbutton state from Wraith Scheme.
Arguments:
One integer in the range [0..3].
Side Effects:
None.
Returned Value:
An exact integer in the range [0..1023], that is the interrupt number presently associated with the pushbutton whose number is passed as the argument.
For Example:
(e::pushbutton-interrupt-number 3) :: ==> 42 -- Means that pushbutton 3 ;; is set to trigger interrupt 42.
Type:
Procedure.
Operation:
Advise Weasel Scheme of the location in the Raspberry Pi hardware memory map, of the registers used to control the Raspberry Pi general-purpose input/output pins (gpio pins), and initialize Weasel Scheme to use those registers.
This procedure neither reads nor writes any of the control registers: It does not "touch hardware", it merely sets up for other procedures subsequently to do so.
Rationale, Explanation, Excuses:
Required to enable access of Raspberry Pi general-purpose input/output pins from Weasel Scheme.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::rpi-gpio-connect) ;; ==> #t
Type:
Procedure.
Operation:
Display a human-readable display of the content of all of the general-purpose input/output (gpio) control registers that the Raspberry Pi uses. (The processor of the Raspberry Pi has the ability to address more gpio pins than the Raspberry Pi uses, so not all of the control registers are shown in the display.)
For interpretation of the display, see (e.g.) this link.
Rationale, Explanation, Excuses:
provide
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::rpi-gpio-display-control-registers) ;; ==> (e.g.) ;; Base address is 0x7e200000, registers are four bytes wide. ;; gpfsel0: 0x0 ;; gpfsel1: 0x0 ;; gpfsel2: 0x12000000 ;; gpset0: 0x6770696f ;; gpclr0: 0x6770696f ;; gplev0: 0x1000c1ff ;; gpeds0: 0x0 ;; gpren0: 0x0 ;; gpfen0: 0x0 ;; gphen0: 0x0 ;; gplen0: 0x0 ;; gparen0: 0x0 ;; gpafen0: 0x0 ;; gpio_pup_pdn_cntrl_reg0: 0x4aa95555 ;; gpio_pup_pdn_cntrl_reg1: 0x19aaaaaa ;; #t
Type:
Procedure.
Operation:
Display the value and function-select field of a given Raspberry Pi general-purpose I/O pin (gpio pin). If the pin to be displayed is pin n, then the value displayed is bit n of control register gplev0. The least-significant bit of that register is bit zero, and so on.
Rationale, Explanation, Excuses:
Basic primitive for displaying logic-level data read by input gpio pins of the Raspberry Pi, and which also returns the most recent value written to any output gpio pin.
Arguments:
One gpio pin number; that is, an integer in the range [0..26].
Side Effects:
None.
Returned Value:
#t
For Example:
(e::rpi-gpio-display-pin 25) ;; ==> Raspberry Pi GPIO pin 25 has value 0, function select field 0x1 ;; (or whatever)
Type:
Procedure.
Operation:
Display the value and function-select field of all Raspberry Pi general-purpose I/O pins (gpio pins). In the display for pin n, the value displayed is bit n of control register gplev0. The least-significant bit of that register is bit zero, and so on.
Rationale, Explanation, Excuses:
Basic primitive for displaying logic-level data read by input gpio pins of the Raspberry Pi, and which also returns the most recent values written to output gpio pins.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::rpi-gpio-display-pins) ;; ==> ;; Raspberry Pi GPIO pin 0 has value 1, function select field 0x0 ;; Raspberry Pi GPIO pin 1 has value 1, function select field 0x0 ;; Raspberry Pi GPIO pin 2 has value 1, function select field 0x0 ;; ;; [ ... ] ;; ;; Raspberry Pi GPIO pin 24 has value 0, function select field 0x0 ;; Raspberry Pi GPIO pin 25 has value 0, function select field 0x0 ;; Raspberry Pi GPIO pin 26 has value 0, function select field 0x0
Type:
Procedure.
Operation:
Returns the three-bit content of the select-field setting of a specified Raspberry Pi general-purpose input/output pin (gpio pin). That value indicates the configuration of the indicated gpio pin; that is, the purpose for which it is configured. Configurations include, but are not limited to, use as a logic-level input, which is indicated by a zero, and use as a logic-level output, which is indicated by a one.
Rationale, Explanation, Excuses:
Determine the purpose for which a given Raspberry Pi gpio pin is intended to be used.
Arguments:
One gpio pin number; that is, an integer in the range [0..26].
Side Effects:
None.
Returned Value:
A three-bit integer indicating the hardware configuration of the specified Raspberry Pi gpio pin; that is, indicating the purpose for which the pin is set up.
For Example:
(e::rpi-gpio-pin-select-field 25) ;; ==> 5 ;; or whatever
Type:
Procedure.
Operation:
Reads the logic level from a specified Raspberry Pi general-purpose input/output pin (gpio pin), provided that the direction of that pin has been set to "input", perhaps by procedure e::rpi-gpio-set-pin-for-output.
Rationale, Explanation, Excuses:
Read logic-level data from a Raspberry Pi gpio pin.
Arguments:
One gpio pin number; that is, an integer in the range [0..26].
Side Effects:
None.
Returned Value:
An integer, either zero or one, corresponding to the logic level of the specified pin.
For Example:
(e::rpi-gpio-read-pin 25) ;; ==> 0 ;; or whatever
Type:
Procedure.
Operation:
Set the direction of a given Raspberry Pi general-purpose input/output pin (gpio pin) to either "input" or "output". As the procedure name may suggest, the "output" direction is specified by an argument of #t, and the "input" direction by #f.
Rationale, Explanation, Excuses:
Fundamental routine for operation of Raspberry Pi gpio pins.
Arguments:
Two: The first a gpio pin number -- that is, an integer in the range [0..26], and the second a boolean -- #t indicating that the direction is indeed to be set to output, and #f indicating that it is not; that is, that the direction is to be set to input.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::rpi-gpio-set-pin-for-output 25 #f) ;; ==> #t ;; Sets the direction to "input".
Type:
Procedure.
Operation:
Sets the logic level of a specified Raspberry Pi general-purpose input/output pin (gpio pin), provided that the direction of that pin has been set to "output", perhaps by procedure e::rpi-gpio-set-pin-for-output.
Rationale, Explanation, Excuses:
Write logic-level data to a Raspberry Pi gpio pin.
Arguments:
Two: The first a gpio pin number -- that is, an integer in the range [0..26], and the second a logic level -- an integer that is either zero or one.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::rpi-gpio-write-pin 25 #f) ;; ==> #t ;; Sets the logic level to low (zero).
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. Wraith Scheme provides a simple interface to these procedures.
Wraith Scheme seeds the Unix "random" mechanism with the Unix time every time Wraith Scheme 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:
(e::random) ;; ==> 2110915871 ;; Or whatever ...
Type:
Procedure.
Operation:
Present a prompt in the Wraith Scheme 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 Wraith Scheme Dialog Panel, as a prompt.
Side Effects:
None.
Returned Value:
The string typed by the user in the Wraith Scheme Dialog Panel. Enclosing double-quotes are not required when that string is typed.
For Example:
(e::read-string-with-prompt "Give me a string!")
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, used as the "start value" just described.
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:
(e::reduce + (list 2 3 4 5) 42) ;; ==> 56 (e::reduce string-append (list "I" " " "see" " " "the" " " "cat" ".")) ;; ==> "I see the cat."
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 Wraith Scheme'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:
(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)
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:
(e::reset) ;; ==> ;; Wraith Scheme resets.
Type:
Procedure.
Operation:
Find the number of bytes free in Wraith Scheme 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 Wraith Scheme main memory.
For Example:
(e::room) ;; ==> 104716012 ;; e.g.
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. Affects only the sense lights of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme sense lights.
Arguments:
One integer.
Side Effects:
Changes the pattern of the Wraith Scheme sense lights.
Returned Value:
#t
For Example:
(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.
Type:
Procedure.
Operation:
Save the content of Wraith Scheme main memory to a Wraith Scheme world file.
Only the MomCat may perform this procedure; calling this procedure in any other Wraith Scheme process will cause an error.
Rationale, Explanation, Excuses:
A world file is a machine-readable image of the entire content of Wraith Scheme main memory. Storing one saves the what you were working on in Wraith Scheme so that you may resume work in another session. Loading one restores that saved work.
Arguments:
At most one: If there is an argument, it should be a string containing a Unix-style path to the file to be used for saving the world. if there is no argument, Wraith Scheme will use the Dialog Panel to obtain a path.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::save-world "MyBackup.world") ;; Saves world ;; ==> #t (e::save-world) ;; Wraith Scheme uses Dialog Panel ;; to obtain a path to the file ;; to be used. ;; ==> #t
Type:
Procedure.
Operation:
Convert Scheme objects to the C-style booleans, taken to be the numbers 1 and 0, respectively.
Rationale, Explanation, Excuses:
Useful with the Wraith Scheme foreign-function interface, for dealing with foreign booleans.
Arguments:
One Scheme object.
Side Effects:
None.
Returned Value:
A number: Returns 0 if, and only if, the argument is #f. Otherwise, returns #1.
For Example:
(e::scheme-boolean->c-boolean #f) ;; ==> 0 (e::scheme-boolean->c-boolean #t) ;; ==> 1 (e::scheme-boolean->c-boolean 'foo) ;; ==> 1 (e::scheme-boolean->c-boolean 42) ;; ==> 1
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
(lambda (element) (first-argument (third-argument element)))
would return true.
For Example:
(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))
Type:
Procedure.
Operation:
Determine whether its argument is suitable for identifying a Wraith Scheme sense light; that is, whether it is an exact integer in the range [0..7].
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme 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:
(e::sense-light-number? -1) ;; ==> #f (e::sense-light-number? 3) ;; ==> #t (e::sense-light-number? #t) ;; ==> #f
Type:
Procedure.
Operation:
Determine whether its argument is suitable for identifying a Wraith Scheme sense-light illumination-state; that is, whether it is an exact integer in the range [0..7].
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme 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:
(e::sense-light-illumination-number? -1) ;; ==> #f (e::sense-light-illumination-number? 3) ;; ==> #t (e::sense-light-illumination-number? #t) ;; ==> #f
Type:
Procedure.
Operation:
Returns the values of the Wraith Scheme sense switches of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Required to read the sense switches (in the Wraith Scheme Sensory Devices Drawer).
Arguments:
None.
Side Effects:
None.
Returned Value:
An exact integer: Bits [0..7] therein respectively indicate whether sense switch [0..7] is on (if the bit is 1) or off (if the bit is 0). The other bits will all be zero.
For Example:
(e::sense-switches) ;; ==> 133 -- Means that only sense ;; switches 0, 2 and 7 are on. ;; (133 is binary 10000101)
Type:
Procedure.
Operation:
Sets an alarm that will go off at a specified future time.
Rationale, Explanation, Excuses:
The procedure "e::alarm" is not defined by Wraith Scheme; indeed, the symbol "e::alarm" does not even exist in the distributed version of Wraith Scheme! It is you who may, if you wish, define "e::alarm". You may make it be any lambda expression of no arguments that you like.
You may use the procedure "e::set-alarm!" to cause Wraith Scheme to interrupt itself at a time in the future; when that time occurs, the procedure "e::alarm" will run. You may also use the procedures "e::alarm?" and "e::alarm-time" respectively to tell whether an alarm is presently set and at what time (Unix time) it will occur.
You may also cause "e::alarm" to run by sending a "SIGALRM" signal to Wraith Scheme from some other program.
Use of these procedures makes it possible to start something happening automatically at a specified time in the future. These procedures provide a rather straightforward interface to the Unix "alarm" system call, which is the mechanism Wraith Scheme uses for implementing them
The alarm is made to go off by pushing the Scheme expression '(e::alarm) into the input queue of the Wraith Scheme process (kitten or MomCat) in which the alarm was set. If that process is busy doing something else, the alarm will not be processed until the process is no longer busy. Thus the alarm system does not provide a truly asynchronous interrupt; for an alarm to happen promptly you must run it in a kitten that is not busy, or in an un-busy MomCat.
NOTE that the fact that '(e::alarm) is pushed into an input queue means that the evaluation of (e::alarm) will always take place at top-level. Any definition of e::alarm in a local environment -- such as within a "let" -- will not be used.
If the symbol "e::alarm" is not bound to a value, or is not bound to a lambda expression, then no alarm will go off. Wraith Scheme will report an error if an alarm goes off while "e::alarm" is bound to a lambda expression that requires arguments.
Arguments:
One nonnegative integer. If the integer is nonzero, it is the number of seconds from now when the alarm will occur. If the integer is zero, the procedure turns off any pending alarm, and the procedures "e::alarm?" and "e::alarm-time" will report accordingly.
Side Effects:
Records whether an alarm is set or not, and when it will occur.
Returned Value:
A boolean. Returns #t if, and only if, the alarm was successfully set or cleared. If not, returns #f. (There are several reasons why the underlying Unix system calls used to implement "e::set-alarm!" may fail, if any of them does, "e::set-alarm!" will return #f.)
The time set for the alarm is only accurate to approximately the nearest second.
For Example:
(define (e::alarm) (display "Alarms and excursions!!\n")) ;; ==> e::alarm (e::set-alarm! 10) ;; ==> #t ;; Ten seconds later ... Alarms and excursions!! (e::set-alarm! 10) ;; ==> #t (e::set-alarm! 0) ;; ==> #t ;; No "Alarms and excursions!!" message is printed.
Type:
Procedure.
Operation:
Set the internal flag that tells Wraith Scheme 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:
(e::set-compiler-on!) ;; ==> #t
Type:
Procedure.
Operation:
Set the directory from which Unix relative paths are referenced.
Rationale, Explanation, Excuses:
Making effective use of the Macintosh's Unix file system from Wraith Scheme requires means to set and determine the current directory.
Arguments:
One string, containing a Unix-style path to a directory. If the string does not end in a '/', this procedure will append one.
Side Effects:
Sets the current directory
Returned Value:
#t
For Example:
(e::set-current-directory! "/Applications") ;; ==> ;; Wraith Scheme sets current directory #t
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,g 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:
;; 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
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:
;; Suppose foo is an unexpired forgettable object, and ;; suppose bar is a forgettable object that has expired. (e::set-forgettable-remember-probability! foo 0.75) ;; ==> #t (e::set-forgettable-remember-probability! bar 0.75) ;; ==> #f
Type:
Procedure.
Operation:
Change the input default port, which Wraith Scheme reconnects to every time it resets to the top-level loop.
Rationale, Explanation, Excuses:
I installed this procedure as a development aid for testing error messages: By default, Wraith Scheme expects input from the keyboard, and sets the current input port to the keyboard on startup, and on every occasion when there is a reset to the top-level loop, without regard to whether that reset was deliberately caused by the user or whether it was in consequence of an error.
There are plenty of standard Scheme procedures to change the default input port while error-free code is running; however, resetting to the top-level loop always restores things so that input comes from the keyboard, or at least, that is what it would do if it weren't for "e::set-input-port!". This procedure changes the default value, to which Wraith Scheme resets the current input port, to a port obtained by opening a file. If you like, it makes Wraith Scheme think that the keyboard is in a file somewhere.
That allows me to test Wraith Scheme's error messages by taking input from a file. I fill the file with Scheme expressions that will cause an error and use "e::set-input-port!" to make the default input come from that file. I log the error messages on a transcript file. Wraith Scheme encounters the first erroneous expression -- from the file -- prints an error message, resets to the top-level loop, then takes the next erroneous expression from the file. All I have to do is check the transcript file to make sure the error messages were all proper and sensible.
Arguments:
At most one: If present, a string containing a Unix-style path to the file from which to take input. If there is no argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain a path.
Side Effects:
Changes the default source of input to Wraith Scheme.
Returned Value:
#t.
For Example:
(e::set-input-port! "MyErrorTests") ;; ==> #t ;; And default input from the file.
Type:
Procedure.
Operation:
Set the value of a level indicator of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Required to control the level indicators (in the Wraith Scheme Instrument Panel).
Arguments:
Two: The first an integer in the range [0..3], the second an integer in the range [0..1024]
Side Effects:
Sets the value of the level indicator whose number is given as the first argument, to the second argument.
Returned Value:
#t
For Example:
(e::set-level-indicator! 2 998) ;; ==> Sets level indicator 2 to 998.
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 Wraith Scheme 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 a symbol's permanent flag, so you cannot change the value to which it is bound. Procedure "e::permanent?" tests whether that flag 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:
(e::clear-permanent! 'cons) ;; ==> #t ;; DANGER WILL ROBINSON (e::set-permanent! 'cons) ;; ==> #t ;; That was close ...
Type:
Procedure.
Operation:
Set all of the Wraith Scheme sense lights to the same illumination state. Does not change the visibility of any sense light. Affects only the sense lights of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme 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 Wraith Scheme sense lights.
Returned Value:
#t
For Example:
(e::set-sense-light-illuminations! 4) ;; ==> #t, and makes the sense lights green.
Type:
Procedure.
Operation:
Set a particular Wraith Scheme sense lights to a particular illumination state. Does not change the visibility of the sense light. Affects only the sense lights of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme 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].
Sense light illumination states are represented by exact integers, as follows:
0: sense light is off
1: sense light is red
2: sense light is orange
3: sense light is yellow
4: sense light is green
5: sense light is cyan
6: sense light is magenta
7: sense light is black
Side Effects:
Changes the illumination state of the given sense light to the given value.
Returned Value:
#t
For Example:
(e::set-sense-light-n-illumination! 1 6) ;; ==> #t, and makes sense light 1 magenta.
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. Affects only the sense lights of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme 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:
(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.
Type:
Procedure.
Operation:
Turns all of the Wraith Scheme sense lights off; that is, sets their illumination state to zero. Does not change the visibility of any sense light. Affects only the sense lights of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme sense lights.
Arguments:
None.
Side Effects:
Turns off all sense lights.
Returned Value:
#t
For Example:
(e::set-sense-lights-off!) ;; ==> #t, and turns all the sense lights off.
Type:
Procedure.
Operation:
Set the internal flag that tells Wraith Scheme 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 Wraith Scheme's numeric display routines to use full precision.
Returned Value:
#t
For Example:
(e::set-show-full-precision!) ;; ==> #t
Type:
Procedure.
Operation:
Change the 64-bit tag portion of the Wraith Scheme tagged aval associated with a Wraith Scheme object.
Rationale, Explanation, Excuses:
This procedure provides detailed and destructive low-level control of part of the structure of Wraith Scheme objects. I implemented it to aid in debugging Wraith Scheme.
ALMOST ANY USE OF THIS PROCEDURE WILL CAUSE WRAITH SCHEME TO CRASH!!
Proper operation of Wraith Scheme depends on tags accurately characterizing the structure of the objects with which they are associated. On the basis of an incorrect tag, Wraith Scheme 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:
;; 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. (define a #\a) ;; ==> a (e::get-tag a) ;; ==> 35 (define new-a (e::set-tag! a 57)) ;; ==> new-a new-a ;; ==> 97 ;; Which is the integer ;; for ASCII 'a'. (e::get-tag new-a) ;; ==> 57
Type:
Procedure.
Operation:
Provide a lengthy printout describing that part of the Wraith Scheme 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:
(e::show-active-memory) ;; ==> ;; Lots of output.
Type:
Procedure.
Operation:
Provide a lengthy printout describing that part of the Wraith Scheme 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:
(e::show-aging-memory) ;; ==> ;; Lots of output.
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 Wraith Scheme 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 Wraith Scheme 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:
(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
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 Wraith Scheme 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 Wraith Scheme 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:
(let ((x 42)) (e::show-environment)) ;; ==> Current environment -- first of 4: g23352 <- 42 #t
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 Wraith Scheme 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 Wraith Scheme 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.
Caution: This procedure can produce a lot of output.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
;; In my Wraith Scheme 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.
Type:
Procedure.
Operation:
Return the value of the internal flag that controls whether Wraith Scheme displays numbers with the full precision available.
Rationale, Explanation, Excuses:
Allows Scheme programs to examine important internal state of the Wraith Scheme interpreter.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns the (boolean) flag that controls whether Wraith Scheme 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:
(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
Type:
Procedure.
Operation:
Show information about the Wraith Scheme processes running, in human-readable form. Some of this information will be useful only for development and maintenance of Wraith Scheme itself, and since I expect to change that information regularly based on my own needs, I shall not document it all here. Notwithstanding:
The process id numbers of the MomCat and the kittens are their Unix process identification numbers. They might be useful, for example, in examining the output of the Unix "ps" command, or as arguments to the Unix "kill" command.
Note that the procedure e::process-id returns the process id of the Wraith Scheme process in which it was called.
Rationale, Explanation, Excuses:
Provides elementary information about parallel instances of Wraith Scheme.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::show-kittens) ;; ==> ;; With three kittens running, but not busy, might print: Who State ObList Message Message Block Process In Reg From From Number ID Mom Kitten Number Mom: 4 0 0 0 0 75758 Kit 1: 4 0 0 0 0 75762 Kit 2: 4 0 0 0 0 75764 Kit 3: 4 0 0 0 0 75766 ;; Note that the specific process id numbers will vary.
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 Wraith Scheme's oblist and top-level environment.
Rationale, Explanation, Excuses:
For use in debugging.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
(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
Type:
Procedure.
Operation:
Provide an extremely lengthy printout describing that part of Wraith Scheme main memory that is presently in use.
Rationale, Explanation, Excuses:
For use in debugging.
Caution: Wraith Scheme 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:
(e::show-memory) ;; ==> ;; Lots of output.
Type:
Procedure.
Operation:
Describe current Wraith Scheme 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 Wraith Scheme main memory.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
(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
Type:
Procedure.
Operation:
Shows the Wraith Scheme sense lights, without changing their illumination state; that is, they will now become visible and will look the way you last set them. Affects only the sense lights of the Wraith Scheme process where the procedure was called.
Rationale, Explanation, Excuses:
Useful for controlling the Wraith Scheme sense lights.
Arguments:
None.
Side Effects:
Makes all of the Wraith Scheme sense lights visible.
Returned Value:
#t
For Example:
(e::show-sense-lights!) ;; ==> #t, and makes the sense lights visible.
Type:
Procedure.
Operation:
Returns the value associated with the slider whose number is passed as an argument.
Rationale, Explanation, Excuses:
Required to read the values of the sliders (in the Wraith Scheme Sensory Devices Drawer).
Arguments:
One integer in the range [0..3].
Side Effects:
None.
Returned Value:
An exact integer in the range [0..255], that is the value of the slider whose number is passed as the argument.
For Example:
(e::slider 2) ;; ==> 47 -- Means that the value ;; of slider number 2 is 47.
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:
(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))
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:
(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))
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:
(e::sorted? (vector 1 2 3) <) ;; ==> #t (e::sorted? (list '(c 1) '(a 2) '(b 3)) < cadr) ;; ==> #t
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. Wraith Scheme provides a simple interface to these procedures.
Wraith Scheme seeds the Unix "random" mechanism with the Unix time every time Wraith Scheme 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:
(e::srandom 42) ;; ==> #t
Type:
Procedure.
Operation:
Determine the number of items on Wraith Scheme's run-time stack.
Rationale, Explanation, Excuses:
The Scheme engine that underlies Wraith Scheme 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.
(Wraith Scheme'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, Wraith Scheme's predecessor. Got all that?)
(Just think of Wraith Scheme 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 Wraith Scheme's main memories. To show how deep it is -- how many Wraith Scheme 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 Wraith Scheme's Scheme engine.
For Example:
;; From the top-level loop: (e::stack-depth) ;; ==> 6
Type:
Procedure.
Operation:
Return what the home directory was when Wraith Scheme was launched.
Rationale, Explanation, Excuses:
Use this procedure when you or your Scheme program gets lost in a maze of twisty little inodes, all alike.
Arguments:
None.
Side Effects:
None.
Returned Value:
A string: Returns a string containing the absolute Unix path to the home directory as it was when Wraith Scheme was launched. The returned string will end in a '/'.
For Example:
;; When Wraith Scheme is launched from the dock: (e::startup-directory) ;; ==> "/"
Type:
Procedure.
Operation:
Find the size of each of Wraith Scheme'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 Wraith Scheme's main memories.
For Example:
(e::store-size) ;; ==> 104857600 ;; E.g.
Type:
Procedure.
Operation:
Speaks its argument, using the voice and voice settings (such as speed and volume) specified in the Macintosh System Preferences. If the procedure is called while speech is in progress, Wraith Scheme will wait until the first utterance has finished before starting the second one.
Rationale, Explanation, Excuses:
The world needs more talking computers; also, more talking cats.
NOTE that this procedure was formerly named "e::string-speak". I renamed it for consistency with procedures like "string->number".
Arguments:
One string.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::string->speech "There is no food in my supper dish!") ;; ==> Speaks the text.
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:
(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>)) ...
Type:
Procedure.
Operation:
Pass a string to the Unix "system" function.
Rationale, Explanation, Excuses:
The Unix "system" function makes it possible for any Unix program to run any other Unix program, just as if it had been typed into a Unix shell as a command line. Wraith Scheme's "e::system" procedure provides an easy interface to this capability from within Scheme. Give your command string to "e::system" and it will pass it through to the Unix "system" function, unchanged.
One problem with "e::system" is figuring out what happened: Unix commands generally print output to a console somewhere, and when the Unix "system" command is used from within a stand-alone application like Wraith Scheme, there is no obvious console handy ...
One way to get output from "e::system" into Wraith Scheme is to write it to a scratch file. That is, make all your Unix commands redirect their output to a file, in this manner:
(e::system "SomeCommand -flags args >& Scratch.text")
Then you can have Wraith Scheme use "read" or "read-char" to get hold of the contents of the file you have written.
You should always remember that "e::system" makes the full power of Apple's Unix operating system available to Wraith Scheme programs. Unix is powerful, and with great power goes the ability to make great mistakes. Abuse of "e::system" can mess up Wraith Scheme, your file system, your Internet connection, and possibly anything anywhere on the Internet. The "e::system" procedure is thereby properly considered dangerous. You have been warned. Don't say I didn't tell you.
Have fun.
Arguments:
One: A string, typically containing something intended to be a Unix command.
Side Effects:
Almost certainly.
Returned Value:
An integer. Returns whatever the encapsulated Unix "system" function returns.
For Example:
(e::system "cal > /tmp/cal") ;; ==> 0 ;; And go look in ;; /tmp/cal.
Type:
Procedure.
Operation:
Each kitten, including the MomCat, has an input queue of expressions to be evaluated (in first-in, first-out order) by its top-level loop. This adds items to the input queue of the kitten whose kitten number is its first argument.
Items in a kitten's input queue have priority over expressions typed in at the keyboard. As long as there is anything in the queue, the kitten will deal with it first, before looking to see whether the user has typed anything. (Note, however, that the kitten will not evaluate any new items from either the input queue or the keyboard until it has finished evaluating any previous item it may have encountered.)
Resetting a kitten clears its input queue, whether the reset is performed explicitly by the user or whether it occurs as the result of an error.
Rationale, Explanation, Excuses:
This procedure provides the basic mechanism whereby one kitten may get another to do something.
Arguments:
Two: The first, an integer no less than zero and no greater than the number of kittens last launched in parallel; the second, any Scheme object.
Side Effects:
Adds an item to the input queue of the indicated kitten. The eventual evaluation of that item may have side effects of its own.
Returned Value:
#t
For Example:
;; In kitten 1. (e::tell-kitten 3 '(+ 2 2)) ;; The expression '(+ 2 2) is evaluated, yielding (+ 2 2), ;; and this value is placed in the input queue for kitten 3. ;; Kitten 3 eventually evaluates (+ 2 2), and thereupon ;; prints the result -- 4 -- in its Wraith Scheme window. (e::tell-kitten 3 (+ 2 2)) ;; Note -- no quotation mark. ;; The expression (+ 2 2) is evaluated, yielding 4 ;; and this value is placed in the input queue for kitten 3. ;; Kitten 3 eventually evaluates 4, and thereupon ;; prints the result -- 4 -- in its Wraith Scheme window. ;; Note that in the first example, kitten 3 performs the ;; addition, whereas in the second example, it does not. ;; Thus if you enter the following commands into the MomCat (e::tell-kitten 3 '(display "Hello!\n")) ;; causes kitten 3 to print Hello! #t (e::tell-kitten 3 (display "Hello!\n")) ;; causes the MomCat to display Hello! ;; since "(display "Hello!\n") was evaluated by the MomCat. ;; Only the result of that evaluation -- #t -- is passed to kitten 3, ;; which prints it without any "Hello!".A discussion of error-handling may also be useful: If Wraith Scheme is launched with N kittens, then this procedure will report an error if its first argument is less than zero or greater than N. If for some reason one of those kittens should quit or exit, then, depending on what caused the exit, this procedure may not be able to detect that the kitten is no longer active. If it cannot do so, it will have no basis to report an error if that kitten's number is subsequently used as the procedure's first argument: It will put the second argument into the appropriate input queue, which will still exist in Wraith Scheme memory, even though the kitten that was handing items in that input queue has itself exited.
Type:
Procedures.
Operation:
Atomically test and set or test and clear a number stored as the car of a pair in Wraith Scheme memory, and return the previous value of that number. That is, "e::test-and-clear!" sets the value of the number to zero, and returns its previous value, while "e::test-and-set!" sets the value of the number to one and returns its previous value.
Rationale, Explanation, Excuses:
These procedures are said to "succeed" if, and only if, they change the value of the number. Thus, "e::test-and-clear!" succeeds if, and only if, the previous value was nonzero, while "e::test-and-set!" succeeds if, and only if, the previous value was zero.
The procedures are atomic in the sense that if many kittens are trying to use "e::test-and-clear!" on the same pair at the same time, only one will succeed, and similarly for "e::test-and-set!". They are thereby useful for lockless coding in Wraith Scheme, provided that the programmer uses them correctly and consistently, and does not modify the number within the pair by means of other procedures.
Arguments:
One argument, which must be a pair whose car is a fixnum (a 64-bit signed integer).
Side Effects:
May change the value of the fixnum referenced.
Returned Value:
An integer: The previous value of the number referenced, as a fixnum.
For Example:
(define a (list 1)) ;; ==> a a ;; ==> (1) (e::test-and-clear! a) ;; ==> 1 a ;; ==> (0) (e::test-and-clear! a) ;; ==> 0 a ;; ==> (0) (e::test-and-set! a) ;; ==> 0 a ;; ==> (1) (e::test-and-set! a) ;; ==> 1 a ;; ==> (1)
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:
(e::time) ;; ==> 1171525209 ;; Once upon a time.
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 Wraith Scheme. When this list is pushed into the continuation, a top-level loop runs, and if that push is performed when Wraith Scheme is either starting or resetting, 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:
;; Here we are in the top-level loop. ;; Let's see how deep the run-time stack is. (e::stack-depth) ;; ==> 6 ;; Now, let's try that business about ;; pushing into the continuation ... (e::push-list-into-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) ;; ==> 12 ;; 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) ;; ==> 6 ;; Might be so ...
Type:
Procedure.
Operation:
Open a transcript file and start using it.
This procedure works like transcript-on (which see), except that it opens the transcript file for append, which means:
Wraith Scheme allows only one transcript file to be open at a time. If a transcript file is already in use when "transcript-on" is called, Wraith Scheme will close the old transcript file before starting to use the new one.
Transcript files record everything that appeared in the Wraith Scheme Main Display Panel while the transcript file was in use, whether keyed in by the user or output by Wraith Scheme.
Procedure transcript-off closes any transcript file in use.
Arguments:
At most one: If present, a string containing a Unix-style pathname to a file to be used as a transcript file. If there is no argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain a pathname.
Side Effects:
Opens a new transcript file, and closes any transcript file that was already in use.
Returned Value:
#t
For Example:
(e::transcript-on-append "MyTranscript.text") ;; Opens the file. ;; ==> #t (e::transcript-on-append) ;; Wraith Scheme uses the Dialog Panel ;; ==> #t
Type:
Procedure.
Operation:
Invoke the Unix "usleep" function on the thread of the Wraith Scheme application that is running the Wraith Scheme engine.
Rationale, Explanation, Excuses:
This procedure provides a convenient way for Wraith Scheme 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.
Wraith Scheme will do no processing while asleep. The "Reset to Top-Level Loop" command will not work. (Actually, it will work eventually, but not till Wraith Scheme wakes up.) "Quit", and several of the commands that affect the appearance of the Wraith Scheme window, will work.
Arguments:
One integer, taken as the number of microseconds to sleep.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::usleep 1000000) ;; Nothing happens ;; for about a second ... ;; ==> #t
Type:
Procedure.
Operation:
Return a string telling when the current version of Wraith Scheme was built.
Rationale, Explanation, Excuses:
Useful for version identification.
Arguments:
None.
Side Effects:
None.
Returned Value:
#t
For Example:
(e::version) ;; ==> "Wraith Scheme Feb 14 2007 14:54:20"
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:
(e::warning "Oops!!") ;; ==> Warning: Oops!! (Continuing) ...
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:
;; In the top-level loop, the ;; continuation will be empty. (e::write-continuation) ;; ==> ()#t (define (foo) (e::write-continuation) (+ 2 2)) ;; ==> foo (foo) ;; ==> Something like this, after formatting. The Scheme machine PC indexes ;; have to do with restarting the top-level read-eval-print loop after ;; the procedure application "(#2 2)" has run. ;; The final '4' is what foo itself returned. ((#<Built-in procedure "+"> 2 2) #<Scheme machine PC index #320, corresponds to code at 0x0000000102c199f0> #<Scheme machine PC index #406, corresponds to code at 0x0000000102c32bf0> #<Scheme machine PC index #514, corresponds to code at 0x0000000102c1a140> #\newline #<Scheme machine PC index #140, corresponds to code at 0x0000000102c2de80> #<Scheme machine PC index #23, corresponds to code at 0x0000000102c1a100> #<Scheme machine PC index #387, corresponds to code at 0x0000000102bd22c0> ) 4
Type:
Procedure.
Operation:
Write out the contents of the Wraith Scheme 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 Wraith Scheme 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:
(e::write-stack) ;; ==> ;; Lots of output.
Type:
Procedure.
Operation:
Establish a lock on its argument, such that any Wraith Scheme procedure except c::release-block, that attempts to return or modify that argument, will loop without doing so until the lock has been released (by c::release-block).
This procedure is one of five that are particularly useful in dealing with critical sections that involve Wraith Scheme objects, notably symbols. The five procedures in question are
These procedures should be used with great caution: They are individually and collectively calamitous, for several reasons.
Technical Note: The problem indicated is a deadlock due to an attempt to access a locked object.
Rationale, Explanation, Excuses:
Fundamental low-level primitive for parallel programming.
Arguments:
One Wraith Scheme object which is stored in Wraith Scheme main memory. (The procedure will report an error if called with an inappropriate argument.)
Side Effects:
Locks its argument in such a way that any Wraith Scheme procedure except c::release-block, that attempts to return or modify that argument, will loop without doing so until the lock has been released (by c::release-block).
Returned Value:
The argument, as locked.
Failure to call c::release-block with the returned value will leave the original argument to "c::block" locked, and any subsequent attempt to use or modify that argument will cause a deadlock. In particular, any operation that prints or displays that argument will cause a deadlock.
For Example:
(c::block 'foo) ;; ==> Something you should not try to print.
For a more realistic example, suppose you had some data that in principle might be modified by any of several different Wraith Scheme processes, and the nature of the data and modification was such that two Wraith Scheme processes could get in each other's way if they tried to modify the data at the same time. Thus the data might be a global counter, whose value was supposed to be incremented by various processes at various times, and it might be important that the total number of increments be recorded accurately.
Here is a way to do that using "c::block" and "c::release-block". First, make a list whose car is the actual counter -- initialized to zero -- and whose cadr is arbitrary: That is, the list must *have* a cadr -- we couldn't just initialize it to (list 0) -- but we don't care what value its cadr is.
(define the-counter-wrapper (list 0 42))
Now write an increment function that locks the cdr of our list, then modifies the car of the list and finally releases the lock.
(What is going on here is that we can only lock things that are in Wraith Scheme main memory, and a non-null list -- like the cdr of (list 0 42) -- is a handy way to get one. Many others are possible, this is just an illustration.)
(define (increment-the-counter) (let* ((the-block (c::block (cdr the-counter-wrapper))) (the-current-value (car the-counter-wrapper)) ) (set-car! the-counter-wrapper (+ the-current-value 1)) (c::release-block the-block)))
There is an implicit assumption here, that all the Wraith Scheme processes are cooperating. That is presumably the case, because they are all doing what you, the user, told them to do, and you will presumably respect the convention of paying attention to the block. Yet there is nothing to prevent you from evaluating
(set-car! the-counter-wrapper (+ (car the-counter-wrapper) 1))
any time you wish: Wraith Scheme does not try to keep you from shooting yourself in the foot, it only provides tools with which you may endeavor to protect yourself, if you should choose to do so.
Type:
Procedure.
Operation:
Make Wraith Scheme ignore a particular interrupt by setting its handler to the empty list.
Rationale, Explanation, Excuses:
Part of the mechanism for allowing Wraith Scheme to deal with to "SIGUSR1" Unix software interrupts.
Arguments:
An integer in the range [0..1023], representing the interrupt whose handler is to be set to the empty list.
Side Effects:
Clears the given interrupt handler, in Wraith Scheme's master list of interrupt handlers. Clears the flag showing whether the given interrupt has been requested.
Returned Value:
#t
For Example:
(c::clear-interrupt-handler! 42) ;; ==> #t
Type:
Procedure.
Operation:
Clear the interrupt-requested flag for the given interrupt.
Rationale, Explanation, Excuses:
For debugging or error handling, in case the interrupt-requested flag has become set accidentally.
Arguments:
An integer in the range [0..1023], representing the interrupt whose interrupt-requested flag is to be cleared.
Side Effects:
Clears the flag showing whether the given interrupt has been requested.
Returned Value:
#t
For Example:
(c::clear-interrupt-requested! 42) ;; ==> #t
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.
This procedure actually duplicates e::compiler-on?.
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 Wraith Scheme is automatically compiling definitions. Otherwise, returns #f.
For Example:
;; With the "Compile Defines" menu item set: (c::compiling?) ;; ==> #t
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.
Wraith Scheme 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:
(c::define a 42) ;; ==> a a ;; ==> 42
Type:
Procedure.
Operation:
Disables output from Wraith Scheme to the Wraith Scheme window, except for echoing of text entered into the Wraith Scheme Input Panel. Also see c::enable-window-output and c::window-output-enabled?.
Rationale, Explanation, Excuses:
Window output is slow.
Arguments:
None.
Side Effects:
Disables window output.
Returned Value:
#t
For Example:
(c::disable-window-output) ;; ==> #t, and window output is disabled.
Type:
Procedure.
Operation:
Test the Wraith Scheme mechanism for reporting fatal errors by crashing Wraith Scheme.
If this procedure is executed by the MomCat, the MomCat and all kittens crash. If it is executed by some kitten other than the MomCat, just that kitten crashes.
Rationale, Explanation, Excuses:
For further development of Wraith Scheme, I needed an easy mechanism to verify that the Wraith Scheme mechanism for reporting fatal errors was working correctly.
Arguments:
None.
Side Effects:
WRAITH SCHEME CRASHES.
Returned Value:
Does not apply.
For Example:
(c::down-in-flames!!!) ;; ==> <Wraith Scheme crashes> ;; Wasn't that fun?
Type:
Procedure.
Operation:
Enables output from Wraith Scheme to the Wraith Scheme window. Also see c::disable-window-output and c::window-output-enabled?.
Rationale, Explanation, Excuses:
Window output is slow.
Arguments:
None.
Side Effects:
Enables window output.
Returned Value:
#t
For Example:
(c::enable-window-output) ;; ==> #t, and window output is enabled.
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 Wraith Scheme 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:
;; Called at top level: (c::environment) ;; ==> ;; Lots of printout. The ;; top-level environment is ;; large. (let ((x 3)) (c::environment)) ;; ==> e.g., (((3 . g23224)) ;; followed by the large printout for the ;; top-level environment.
Type:
Procedure.
Operation:
Evaluate an expression in a specified environment.
Rationale, Explanation, Excuses:
This procedure is a generalization of the standard Scheme eval procedure, that accepts any instance of an "environment", in the implementation-specific form used by Wraith Scheme, for its second argument.
Arguments:
One Scheme object, and one instance of a Wraith Scheme environment list.
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:
(c::eval-in-environment '(+ 2 2) (interaction-environment)) ;; ==> 4 (c::eval-in-environment '(+ 2 2) (scheme-report-environment 5)) ;; ==> 4 (c::eval-in-environment '(+ 2 2) (null-environment 5)) ;; ==> <error> ;; "+" is not defined in the null environment. (c::eval-in-environment '(if #t 2 3) (null-environment 5)) ;; ==> 2 (define a 42) ;; ==> a a ;; ==> 42 (let ((a 3)) a) ;; ==> 3 (let ((a 3)) (c::eval-in-environment 'a (interaction-environment))) ;; ==> 42These examples of "c::eval-in-environment" use the procedures whereby standard "eval" obtains environment lists. There are other ways to obtain such an environment list, such as by using procedure “c::environment”, but constructing an example that uses them involves enough detail to obscure the main point about how "c::eval-in-environment" works.
Type:
Procedure.
Operation:
Provide simple statistics about how close the given float matrix is to an identity float matrix of the same side.
Rationale, Explanation, Excuses:
Created for use in tests of Wraith Scheme itself: For example, testing how close the product of a float matrix and its calculated inverse is to the identity. (The calculation may not be perfect because of floating-point inaccuracies.)
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
A four-element list.
If the list returned is (A B C D), then ...
For Example:
(define a (c::float-matrix-generate-random 100 100)) ;; ==> a (c::float-matrix-check-identity a) ;; ==> Try it and see ...
Type:
Procedure.
Operation:
Generate a float matrix with each element set to a random real number in the (open) interval (0..2).
Rationale, Explanation, Excuses:
Created for use in tests of Wraith Scheme itself.
Arguments:
Two exact integers, respectively the number of rows and columns in the matrix to be created.
Side Effects:
None.
Returned Value:
A a float matrix with each element set to a random real number in the (open) interval (0..2).
For Example:
(c::float-matrix-generate-random 6 8) ;; ==> Try it and see ...
Type:
Procedure.
Operation:
Provide simple statistics about how close the given float matrix is to a zero float matrix of the same size.
Rationale, Explanation, Excuses:
Created for use in tests of Wraith Scheme itself: For example, comparing the result of an operation with a known exact result.
Arguments:
One float matrix.
Side Effects:
None.
Returned Value:
A two-element list.
If the list returned is (A B), then ...
For Example:
(define a (c::float-matrix-generate-random 100 100)) ;; ==> a (c::float-matrix-check-zero a) ;; ==> Try it and see ...
Type:
Procedure.
Operation:
Return the hash value of the string, as used by Wraith Scheme 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:
(c::hash-string "abcd") ;; ==> 4994
Type:
Procedure.
Operation:
Set the interrupt flag for a Wraith Scheme interrupt, then interrupt a Wraith Scheme process, so that it will respond to the interrupt. If there is no interrupt handler for the given interrupt, nothing will happen.
Note that the kitten that responds to the interrupt need not necessarily be the one that executes the interrupt handler.
Rationale, Explanation, Excuses:
Part of the mechanism for allowing Wraith Scheme to deal with to "SIGUSR1" Unix software interrupts. This procedure is perhaps most useful for allowing tests of interrupts without using other programs than Wraith Scheme.
Arguments:
Two: The first the kitten number of the Wraith Scheme process to be interrupted, the second an integer indicating the interrupt to be dealt with.
Side Effects:
No direct side effects, but the handling of the interrupt may have arbitrary side effects.
Returned Value:
#t
For Example:
(c::interrupt 4 137) ;; ==> Kitten 4 deals with interrupt 137.
Type:
Procedure.
Operation:
Return Wraith Scheme's vector of interrupt handlers. The vector is indexed by interrupt number. Each element is a cons cell whose car is the kitten number of the Wraith Scheme process intended to execute the handler, and whose cdr is a Scheme expression to be added to the input queue of that kitten.
Note that it is probably a bad idea to alter this vector directly; Wraith Scheme is likely to crash if the format of its entries is not exactly correct. Use the procedures c::set-interrupt-handler! and c::clear-interrupt-handler! instead.
Rationale, Explanation, Excuses:
Part of the mechanism for allowing Wraith Scheme to deal with to "SIGUSR1" Unix software interrupts.
Arguments:
None.
Side Effects:
None.
Returned Value:
Wraith Scheme's vector of interrupt handlers.
For Example:
(c::interrupt-handler-vector) ;; ==> A very long vector.
Type:
Procedure.
Operation:
Returns whether the kitten indicated was evaluating an expression at the time the procedure got around to asking. That state may have changed by the time the return value is provided to the caller.
Rationale, Explanation, Excuses:
Provided for possible load distribution among kittens.
Arguments:
An integer: The argument must be no less than zero and no greater than the number of kittens last launched in parallel.
Side Effects:
None.
Returned Value:
A boolean:
For Example:
(c::kitten-busy? 1) ;; ==> #t or #f if kitten 1 was or was not busy.
Type:
Procedure.
Operation:
Returns a boolean telling whether the input queue for the given kitten is empty.
Rationale, Explanation, Excuses:
Provided mostly for testing the input queue implementation.
Arguments:
An integer: The argument must be no less than zero and no greater than the number of kittens last launched in parallel.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, the input queue for the given kitten is empty. Otherwise, returns #f.
For Example:
(c::kitten-empty-queue? 1) ;; ==> #t
Type:
Procedure.
Operation:
Returns the content of the input queue of the kitten given, as a list.
Rationale, Explanation, Excuses:
Provided mostly for testing the input queue implementation.
Arguments:
An integer: The argument must be no less than zero and no greater than the number of kittens last launched in parallel.
Side Effects:
None.
Returned Value:
A boolean:
For Example:
(c::kitten-input-queue 1) ;; ==> ()
Type:
Procedure.
Operation:
Empties the input queue of the kitten indicated.
Rationale, Explanation, Excuses:
Provided mostly for testing the input queue implementation.
Arguments:
An integer: The argument must be no less than zero and no greater than the number of kittens last launched in parallel.
Side Effects:
Empties the input queue of the kitten indicated.
Returned Value:
#t
For Example:
(c::kitten-purge-queue 1) ;; ==> #t
Type:
Procedure.
Operation:
Resets the kitten indicated.
Rationale, Explanation, Excuses:
Provided for process control and error recovery.
Arguments:
An integer: The argument must be no less than zero and no greater than the number of kittens last launched in parallel.
Side Effects:
Resets the kitten indicated.
Returned Value:
#t
For Example:
(c::kitten-reset 3) ;; ==> #t, and resets kitten 3.
Type:
Procedure.
Operation:
Provide a way to debug circumstances in which a kitten is trying to lock access to a Wraith Scheme object that is already locked, and has remained locked for a worrisome amount of time. The "worrisome amount of time" is guaranteed to be at least 0.03 seconds, but may be longer, depending on the speed of your Macintosh and on what else -- other than Wraith Scheme -- it is doing.
I have changed the capabilities of this procedure from time to time, depending on what I was trying to debug, and have not attempted to document the changes. Therefor, do not be surprised if its operation is mysterious.
This procedure does not apply to locks of bins of the hash tables used to control access to Wraith Scheme's oblist and top-level environment.
If the kitten whose kitten number is passed to the procedure has been trying to obtain access to a locked object for more than the "worrisome amount of time" just described, this procedure will cause it to give up trying, print out some information about what it was attempting to lock, and reset to top-level.
This procedure may be applied to any kitten and called from any kitten.
This procedure is dangerous, because release of deadlocks may cause Wraith Scheme to crash or hang.
Rationale, Explanation, Excuses:
For use in debugging.
Arguments:
An integer: The kitten number of the kitten on on which deadlocks are to be allowed to time out.
Side Effects:
Quite possibly, Wraith Scheme will crash. With luck, Wraith Scheme will end up in a state in which you can investigate what was causing any mysterious possible deadlocks that may have been giving you cause for concern.
Returned Value:
#t
For Example:
(c::let-deadlock-time-out 0) ;; ==> #t ;; And kitten 0 may print some information about ;; any deadlock it may have been dealing with, and ;; then reset. Here is a sample of this output: Atomic test-and-set timed out at memory address 0x15e70f04: 13002079-00000004. Called by kitten 0, location 2, blocked by kitten 0, location 19. (values may have changed between timeout and report) (4 5) Problem: Failed to lock in "car". (Resetting) Top-level loop ...
Type:
Procedure.
Operation:
Read a Scheme string, and process its contents as if they had been entered at the keyboard. Wraith Scheme prints the results of any such evaluation, but not the literal text of the string itself.
Rationale, Explanation, Excuses:
Useful, perhaps in particular with the Wraith Scheme foreign-function interface, in which case it might allow Wraith Scheme to evaluate an expression prepared for it by a foreign function and copied in using e::peek-c-string.
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, Wraith Scheme will wait patiently for additional top-level input after it has completed reading the string.
Returned Value:
#t
For Example:
(c::load-from-string "(+ 2 2 )") ;; ==> #t, and then ;; Wraith Scheme prints "4".
Type:
Procedure.
Operation:
Loads a file into a specially prepared environment list, which comprises the environment list passed in as one of the arguments, with an initially empty additional environment consed onto the head of the passed-in environment list. Thus any defines within the file will create new bindings in the initially empty environment. The procedure returns the newly-prepared environment list (including the consed-on addition).
Rationale, Explanation, Excuses:
This procedure is intended as a primitive for building "package" systems.
Arguments:
One or two.
If there are two arguments, the first must be a string containing a Unix-style path to the file to be loaded. If there is only one argument, Wraith Scheme will use the Wraith Scheme Dialog Panel to obtain such a path from the user.
The remaining argument must be a Wraith Scheme environment list, such as the one returned by "c::environment" or by "c::top-level-environment".
Side Effects:
Creates and returns new environment list, as described.
Returned Value:
A Wraith Scheme environment list.
For Example:
(define (foo123) (bar456)) (define (bar456) (baz789)) (define (baz789) (display "This is baz789\n"))Suppose we evaluate the following:
(define e (c::load-with-environment-list "SomeFile.s" (c::top-level-environment))) ;; ==> eThen when we evaluate "e", we get a long printout of the returned environment list, which begins
e ;; ==> (((#<Interpreted lambda expression, possibly named "baz789"> . baz789) ;; (#<Interpreted lambda expression, possibly named "bar456"> . bar456) ;; (#<Interpreted lambda expression, possibly named "foo123"> . foo123)) ;; ...The portion of the printout shown is just the new, consed-on environment, with three entries corresponding to the symbols defined in "SomeFile.s". The ellipsis stands for the entire top-level environment, which was the passed-in argument.
Having done this, if we look for one of the new symbols at top level, we do not find it:
foo123 ;; ==> foo123 ;; Problem: No lexically visible binding of this symbol. (Resetting) ;; Top-level loop ...Whereas if we look explicitly in the new environment list that was returned from "c::load-with-environment-list", we find the new binding.
(c::symeval-in-environment 'foo123 e) ;; ==> #<Interpreted lambda expression, possibly named "foo123">We may rename the binding so obtained, and use it in the manner of something imported from a package.
(define foo (c::symeval-in-environment 'foo123 e)) ;; ==> foo (foo) ;; => This is baz789 ;; #t
Type:
Procedure.
Operation:
Construct a Wraith Scheme 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 Wraith Scheme 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
snprintf( scratch, 256, <your number coerced to double>, <your format string>)
Then the scratch buffer is used to construct a newly-allocated Wraith Scheme string, so there is no need to copy anything to use the new string, and no concern about overwriting it.
For Example:
(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!!"
Type:
Procedure.
Operation:
Open a Unix socket for reading.
Rationale, Explanation, Excuses:
One of a group of procedures allowing a Wraith Scheme process to act as a Unix socket server.
These sockets are the kind intended for communicating with other programs on the computer where Wraith Scheme is running.
Arguments:
An integer identifying the socket to be opened for reading.
Side Effects:
None.
Returned Value:
A Scheme input port connected to the given socket.
For Example:
;; Assume 42 is the identifier of a Unix socket, perhaps ;; returned by "c::socket-accept". (c::open-input-socket 42) ;; ==> A Scheme input port.
Type:
Procedure.
Operation:
Release any lock on its argument. (The procedure does not test to see whether its argument was originally locked.) See c::block and e::block-symbol-binding.
This procedure is one of five that are particularly useful in dealing with critical sections that involve Wraith Scheme objects, notably symbols. The five procedures in question are
These procedures should be used with great caution: They are individually and collectively calamitous, for several reasons.
Technical Note: The problem indicated is a deadlock due to an attempt to access a locked object.
Rationale, Explanation, Excuses:
Fundamental low-level primitive for parallel programming.
Arguments:
One Wraith Scheme object which is stored in Wraith Scheme main memory, and which is presumably locked to begin with. This procedure does not type-check its argument.
Side Effects:
Releases any lock in effect on its argument.
Returned Value:
#t
For Example:
(c::release-block 3) ;; ==> (Wraith Scheme crashes)
For a more realistic example, suppose you had some data that in principle might be modified by any of several different Wraith Scheme processes, and the nature of the data and modification was such that two Wraith Scheme processes could get in each other's way if they tried to modify the data at the same time. Thus the data might be a global counter, whose value was supposed to be incremented by various processes at various times, and it might be important that the total number of increments be recorded accurately.
Here is a way to do that using "c::block" and "c::release-block". First, make a list whose car is the actual counter -- initialized to zero -- and whose cadr is arbitrary: That is, the list must *have* a cadr -- we couldn't just initialize it to (list 0) -- but we don't care what value its cadr is.
(define the-counter-wrapper (list 0 42))
Now write an increment function that locks the cadr of our list -- note that we neither know nor care what the value of the cadr is, all we care is that it gets locked -- then modifies the car of the list and finally releases the lock.
(define (increment-the-counter) (let* ((the-block (c::block (cdr the-counter-wrapper))) (the-current-value (car the-counter-wrapper)) ) (set-car! the-counter-wrapper (+ the-current-value 1)) (c::release-block the-block)))
There is an implicit assumption here, that all the Wraith Scheme processes are cooperating. That is presumably the case, because they are all doing what you, the user, told them to do, and you will presumably respect the convention of paying attention to the block. Yet there is nothing to prevent you from evaluating
(set-car! the-counter-wrapper (+ (car the-counter-wrapper) 1))
any time you wish: Wraith Scheme does not try to keep you from shooting yourself in the foot, it only provides tools with which you may endeavor to protect yourself, if you should choose to do so.
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 Wraith Scheme's oblist and top-level environment, and then release every lock found.
Rationale, Explanation, Excuses:
For use in debugging.
Arguments:
None.
Side Effects:
Quite possibly, Wraith Scheme will crash. With luck, Wraith Scheme 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:
(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
Type:
Procedure.
Operation:
Change the value of a symbol that has been previously subject to the procedure e::block-symbol-binding (which see). The procedure "c::set-blocked-binding!" should not be used for any other purpose.
This procedure is one of five that are particularly useful in dealing with critical sections that involve Wraith Scheme objects, notably symbols. The five procedures in question are
These procedures should be used with great caution: They are individually and collectively calamitous, for several reasons.
Technical Note: The problem indicated is a deadlock due to an attempt to access a locked object.
Rationale, Explanation, Excuses:
Useful low-level primitive for parallel programming.
Arguments:
Two arguments. The first must be a lock received from e::block-symbol-binding (which see). The second may be any Scheme object. This procedure does not type-check either of its arguments.
Side Effects:
Change the value of the variable whose blocked variable-binding is the first argument, to the second argument.
Returned Value:
#t
For Example:
(define a 0) (define (blocked-increment-of-a) (let* ((the-block-list (e::block-symbol-binding 'a)) (the-value (car the-block-list)) (the-lock (cadr the-block-list)) ) (c::set-blocked-binding! the-lock (+ the-value 1)) (c::release-block the-lock)))
Type:
Procedure.
Operation:
Make Wraith Scheme capable of doing something useful in response to a particular interrupt, by providing a handler for that interrupt that is not the empty list.
Rationale, Explanation, Excuses:
Part of the mechanism for allowing Wraith Scheme to respond to "SIGUSR1" Unix software interrupts.
Arguments:
Three: The first an integer representing the interrupt whose handler is to be set, the second the kitten number of the kitten intended to execute the handler, the third a Scheme expression which is to be added to the input queue of that kitten when a Wraith Scheme process responds to the given interrupt.
Side Effects:
Changes Wraith Scheme's vector of interrupt handlers, by adding a handler for the given interrupt. Clears the flag showing whether the given interrupt has been requested.
Returned Value:
#t
For Example:
(c::set-interrupt-handler! 999 3 '(display "MEOW!!!\n")) ;; ==> #t ;; Wraith Scheme is now set up to deal with interrupt ;; 999 by telling kitten 3 to complain loudly (or at ;; least, to complain in block capitals.)
Type:
Procedure.
Operation:
Wait -- perhaps forever -- for a connection to be made on the given Unix socket, and return the number of the accepted socket. This procedure executes the Unix/C++ function "accept".
NOTE that this procedure will not return until a connection is made.
Rationale, Explanation, Excuses:
One of a group of procedures allowing a Wraith Scheme process to act as a Unix socket server.
These sockets are the kind intended for communicating with other programs on the computer where Wraith Scheme is running.
Arguments:
One integer, identifying the Unix socket that is to wait for the connection.
Side Effects:
None.
Returned Value:
An integer identifying the accepted socket.
For Example:
;; Assume 42 is the identifier of a Unix socket, perhaps ;; returned by "c::socket-create-and-listen". (c::socket-accept 42) ;; ==> Perhaps, another socket number.
Type:
Procedure.
Operation:
Create a Unix server socket and start it listening, by executing the Unix/C++ functions "socket", "bind" and "listen".
Rationale, Explanation, Excuses:
One of a group of procedures allowing a Wraith Scheme process to act as a Unix socket server.
These sockets are the kind intended for communicating with other programs on the computer where Wraith Scheme is running.
Arguments:
Two: The first a string naming a socket, the second a positive integer indicating the desired backlog for that socket.
Side Effects:
None.
Returned Value:
An integer identifying the socket created.
For Example:
(c::socket-create-and-listen "/var/tmp/my_socket" 100) ;; ==> a socket number
Type:
Procedure.
Operation:
Read up to 128 bytes from a Scheme input port that is connected to a socket, by using the Unix/C++ function "fgets", and return what was read as a Scheme string. The number "128" is rather an arbitrary choice.
Rationale, Explanation, Excuses:
One of a group of procedures allowing a Wraith Scheme process to act as a Unix socket server.
These sockets are the kind intended for communicating with other programs on the computer where Wraith Scheme is running.
Arguments:
One Scheme input port that has previously been connected to a Unix socket.
Side Effects:
None.
Returned Value:
A Scheme string containing the text read from the socket.
For Example:
;; Assume "foo" is a Scheme input port connected to a socket, ;; perhaps returned by "c::open-input-socket". (c::socket-fgets foo) ;; ==> "The socket speaks!"
Type:
Procedure.
Operation:
Write text to a Unix socket.
Rationale, Explanation, Excuses:
One of a group of procedures allowing a Wraith Scheme process to act as a Unix socket server.
These sockets are the kind intended for communicating with other programs on the computer where Wraith Scheme is running.
Arguments:
Two: The first an integer identifying the socket to receive the write, the second a Scheme string containing the text to be written.
Side Effects:
None.
Returned Value:
#t
For Example:
;; Assume 42 is the identifier of a Unix socket, perhaps ;; returned by "c::socket-accept". (c::socket-write 42 "Listen to this!") ;; ==> #t
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:
(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
Type:
Procedure.
Operation:
Find the value or binding of a symbol, if there is one.
Rationale, Explanation, Excuses:
This procedure is in essence a mini "eval" that works only for symbols. It obtains the value or binding of the symbol in the environment list with which it was called.
Arguments:
Two: The first, a symbol, the second a Wraith Scheme environment list, within which the symbol is to be evaluated.
Side Effects:
None.
Returned Value:
Any Scheme object: Returns the value or binding or the argument in the given environment list. Reports an error if the argument has no value or binding in that environment list.
For Example:
(c::symeval-in-environment 'cons (c::top-level-environment)) ;; ==> #<Built-in procedure "cons"> (c::symeval-in-environment 'not-bound (c::top-level-environment)) ;; ==> ;; error message: not-bound Problem: No lexically visible binding of this symbol in the given environment. (Resetting) Top-level loop ... (define not-bound 42) ;; ==> not-bound (c::symeval-in-environment 'not-bound (c::top-level-environment)) ;; ==> 42
Type:
Procedure.
Operation:
Get the entire top-level 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 Wraith Scheme 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 at top level in Wraith Scheme.
For Example:
;; Called at top level: (c::top-level-environment) ;; ==> ;; Lots of printout. The ;; top-level environment is ;; large.
Type:
Procedure.
Operation:
Check whether window output is enabled or not. Also see c::disable-window-output, and c::enable-window-output.
Rationale, Explanation, Excuses:
Window output is slow.
Arguments:
None.
Side Effects:
None.
Returned Value:
A boolean: Returns #t if, and only if, window output is enabled. Otherwise, returns #f.
For Example:
(c::window-output-enabled?) ;; ==> #t or #f, depending on whether window output is enabled.
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 Wraith Scheme, atoms include all objects of the the following kinds:
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
Atoms also include many kinds of numbers.
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 Wraith Scheme -- 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
(define my-pair (cons 1 2))
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 Wraith Scheme 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:
;; 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)
Just which kinds of objects are associated with variables by bindings and which are not will vary from Lisp system to Lisp system. In Wraith Scheme, 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, many kinds of numbers, ports, symbols and procedures.
That list is a little fuzzy, because Wraith Scheme 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.
Wraith Scheme 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 Macintosh computers. 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 unreally -- a hybrid species.
Clarus was reported to have several vocalizations: The most common was "Moof!™" -- I have never been quite sure how to pronounce the '™' -- 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 Incorporated.
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 Wraith Scheme 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 Wraith Scheme packages up as a continuation, for "call-with-current-continuation", is in essence a complete copy of the Wraith Scheme 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 or 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.
Wraith Scheme 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 Wraith Scheme, 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 Wraith Scheme, 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 Wraith Scheme.
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 Wraith Scheme macros that implement some of the syntactic keywords. The Scheme report environment adds everything else from the R5 report that Wraith Scheme implements. The interaction environment adds Wraith Scheme'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.
In Wraith Scheme, every such hierarchy of environments is implemented as a list of the individual environments. At various points in the documentation, I refer to this hierarchy as an "environment list". That is, each instance of the second meaning of "environment" is implemented as a list of instances of the third meaning of "environment", as described immediately below.
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, Wraith Scheme will use the binding of each variable that exists in the closest lexical scope to the place where the print occurs.
;; 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
The term "environment list" refers to the hierarchy of environments described as the second meaning of "environment" in the discussion above. Wraith Scheme 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:
(define my-expression '(+ 2 2)) ;; ==> my-expression my-expression ;; ==> (+ 2 2)
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
my-expression ;; ==> (a b c)
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.
(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
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:
top-level-list ;; ==> (list a b c) let-list ;; ==> (list a b c) lambda-list ;; ==> (list a b c)
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. Wraith Scheme provides an implementation of that "eval".
Wraith Scheme also provides 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:
(define eval2 e::cons-with-continuation) ;; ==> eval2 (eval2 top-level-list) ;; ==> (a-from-top-level b-from-top-level c-from-top-level) (eval2 let-list) ;; ==> (a-from-top-level b-from-top-level c-from-top-level) (eval2 lambda-list) ;; ==> (a-from-top-level b-from-top-level c-from-top-level)
So indeed, each of the three lists evaluates using the bindings to "a", "b" and "c" that obtained in the top level.
Wraith Scheme has a data type, "float matrix", for matrices composed of IEEE 64-bit floating-point numbers, and has procedures to operate on those matrices. Float matrices are non-atomic, which means that the data representing them is stored in Scheme main memory, but the details of that storage are different than for other non-atomic data types, such as lists, strings and vectors. Thus special procedures are required to deal with them.
The elements of float matrices are stored as IEEE 64-bit floating-point numbers, just as are Wraith Scheme's regular flonums, but the procedures to manipulate them do not keep track of exactness. Thus Wraith Scheme will present any data elements retrieved from a float matrix as inexact -- with the "exact bit" not set.
Float matrices may be initialized, or have their data elements otherwise set, using any kind of real number known to Wraith Scheme, including fixnums, flonums, and long ratnums, but all such numbers will be converted to IEEE 64-bit floating-point numbers before being stored into float matrices. Such conversions may result in loss of precision, such as when loading an integer outside the range that can be expressed precisely as IEEE 64-bit floating-point numbers, or when loading a number in fraction form, such as 3/1.
The row and column numbers of Wraith Scheme float matrices are zero-based. Thus a 3x4 float matrix has rows 0, 1, and 2, and has columns 0, 1, 2, and 3.
The data elements of float matrices are stored in Scheme main memory in row-major order; that is, the linear order in memory is first row, second row, third row, and so on. When working with large matrices, operations may be much faster if elements are accessed in row-major order.
Float matrices can be very large -- they are limited in size only by the amount of Scheme main memory available. The number of bytes used by a float matrix with M rows and N columns is 8 * M * N for the data, plus a few tens of bytes more for storing M and N, and for other data describing the byte block.
Procedures involving very large float matrices can take a long time to execute, particularly on Macintoshes with small amounts of physical memory. Operations that are particularly slow include matrix multiplication, matrix inversion, and calculating the determinant of a matrix. These operations all have execution times that are proportional to the cube of the matrix side, hence the times increase rapidly as matrix size increases.
If you need to interrupt such an operation by telling Wraith Scheme to reset or quit, it may take a while before Wraith Scheme responds. In extreme cases, it may be necessary to quit Wraith Scheme from the Macintosh Finder.
The best way to become familiar with the speed and interrupt-response time of Wraith Scheme float matrix procedures on your Macintosh is to experiment. Try things out with small matrices first, and increase matrix size gradually.
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".
Wraith Scheme 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 Wraith Scheme 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 Wraith Scheme 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 Wraith Scheme 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 Wraith Scheme 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. You of course can go to the desktop you just left if you need to look at anything on it. 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. Wraith Scheme 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, Wraith Scheme maintains a list of pointers that are in main memory and point either to 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, in the sense of the well-known curse, "May you live in interesting times."
The term "gensym" is Unix slang for "generate symbol". Wraith Scheme, 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.
Gpio pins are the hard-wired input/output pins used in the Raspberry Pi family of single-board computers. The supplementary program to Wraith Scheme, Weasel Scheme, runs on the Raspberry Pi 400, and offers some access to those pins.
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, Wraith Scheme 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 entities 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.
In Wraith Scheme Kitten Graphics, the virtual creature is a kitty pushing a ball of colored yarn.
All of the Wraith Scheme procedures that operate the kitten graphics system start with "e::kitty-".
Every Wraith Scheme process has its own kitten graphics window. All of the "e::kitty-" procedures affect only the kitten graphics window that belongs to the kitten where the procedures were run.
When running several instances of Wraith Scheme cooperatively in parallel, all processes which are not the MomCat -- that is, all processes whose kitten number is greater than zero -- are called kittens.
Computer programs often let a variable 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 to the symbols which are its formal parameters, at the time a lambda expression is applied to a group of actual 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 Wraith Scheme at top level.
;; "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. )
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". According to artificial-intelligence historian Pamela McCorduck, what "MAC" stood for was either "Man And Computers" or "Machine-Aided Cognition", and the ambiguity was deliberate. See the footnote on p. 287 of McCorduck's Machines Who Think (2004 -- 25th-anniversary update -- A. K. Peters).
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 as you can see, 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 and popular machine for its day -- I know someone who used to have one up and running in her garage, but 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 256 KByte 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. Wraith Scheme also has a built-in low-level macro capability that works as follows:
A Wraith Scheme 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 Wraith Scheme list, the Wraith Scheme 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.
It is beyond the scope of this document to describe memory-mapping in detail. For a start at learning about that rather challenging subject, try "man mmap" at a Unix command line.
Wraith Scheme encapsulates information about shared memory areas in Wraith Scheme objects called "memory-mapped blocks", which are stored in Wraith Scheme main memory. Notwithstanding the name, such a Wraith Scheme object does not actually contain a memory-mapped area, just a pointer to it, along with other information about the block in question.
When several Wraith Scheme processes -- a MomCat and some kittens -- are running in parallel, they are all separate Unix processes. Therefore, even though a "memory-mapped block" object is itself stored in Scheme main memory, where any of those Wraith Scheme processes can get at it, the actual memory-mapped block of memory is not accessible to any given Wraith Scheme process until that process itself has used "mmap" to make the block available to itself.
There is one Wraith Scheme procedure, e::make-memory-mapped-block, to memory-map the block the first time (in which case a file associated with it is also created and written full zeros). That procedure memory-maps the block only in the Wraith Scheme process which executes it, and returns a memory-mapped block object describing and pointing to the actual area that has been mapped. A second Wraith Scheme procedure, e::memory-map-block-in-current-kitten, takes a pre-existing instance of memory-mapped block as an argument, and uses the information stored in it to memory-map the block anew in whatever Wraith Scheme process is executing that second procedure. In this way, a given memory-mapped block may be made available to as many Wraith Scheme processes as need it.
The reason why the first of those two primitives does not immediately memory-map the block in all extant Wraith Scheme processes is that there is no way for one Wraith Scheme process to get another Wraith Scheme process to do something immediately. The user could be misled into thinking that all Wraith Scheme processes had memory-mapped the block when in fact they had not.
The memory regions used for these blocks are allocated from a large area of Wraith Scheme shared memory that is reserved when Wraith Scheme starts running. The allocation mechanism is trivial -- it simply goes straight through the available area until it runs out. There is no provision to "free" the memory in such a memory-mapped blocks. However, there is a lot of memory available: The total amount depends on whether you are using a Macintosh with an Intel processor or one with an "Apple Silicon: processor: It is about 150 MByte in the former and over 100 GByte in the latter. I hope that is sufficient for the moment, even without freeing. I hasten to say that these addresses are all in virtual address space; that is, you don't really need 100 GByte of RAM to use them -- Mac OS will "swap" memory to and from disc as required.
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 to default to when there are no non-default defaults to default to. Yes, Lisp programmers really do think up sentences like that last one.
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 ..."
(define (frob-with foo) ...)
If you think this discussion makes complete sense, you are missing the point. If you think this discussion makes no sense whatsoever, you are missing the point.
When running several instances of Wraith Scheme cooperatively in parallel, one of them, which has a kitten number of zero, is of particular importance: It is called the "MomCat". For example, only the MomCat can load or save worlds, and only the MomCat will read any file specified in the Wraith Scheme preferences to load at startup. The MomCat also has an organizational role in garbage collection.
The MomCat is of sufficient importance that Wraith Scheme programs cannot run in parallel without it; thus, things that cause the MomCat to terminate -- such as its "Quit" command -- tend also to cause any kittens present to terminate. If some disaster causes the MomCat to quit and leave kittens still active, the leftover kittens won't be good for much, and you will have to terminate them yourself.
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 furlongs. 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. For example, many of us were at one time or another taught 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", Wraith Scheme can indeed store the integer 123 with no problem, and will annotate it as an exact number, whereas if I type and evaluate "(/ 4 3)", Wraith Scheme will store an inexact number whose value is close to 1.333333 ... . Similarly, the mathematical primitives that Wraith Scheme uses are capable of noticing whether certain algorithms return approximate or exact results. Thus Wraith Scheme 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 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 has in fact been chosen, 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-odd 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. For example, many of us were at one time or another taught 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 is supposed to print out an external representation that has enough precision to represent with perfect accuracy the internal value of the number that was provided as the argument to "number-string".
An ob-list is a list of all the symbols in use in a Lisp system. Wraith Scheme 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 much faster.
Technical Note: Actually, there is a little more to it. Internally, Wraith Scheme 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 name is printed by following the pointer to get to the appropriate string.
Wraith Scheme allows the symbols to be declared "permanent", which means that Wraith Scheme 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 Wraith Scheme 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 Wraith Scheme's predecessor, Pixie Scheme, is 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, and if you are collecting software for a really old Macintosh you can download it from my web site. Pixie Scheme is the direct ancestor of Wraith Scheme; indeed, much of Pixie Scheme's source code was incorporated in the first release of Wraith Scheme without change, and still survives in subsequent releases.
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.
A rather dated version of Pixie Scheme II is available from the software page of my web site, http://JayReynoldsFreeman.com/My/Software.html. That version only runs on Macintosh computers with Intel processors. 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 Wraith Scheme, Pixie Scheme II, and Pixie Scheme III.
Pixie Scheme III an implementation of "R5" Scheme for the Apple iPad™, that was for sale in the App Store, but I have not updated it for current iPads, so it is no longer available there. Pixie Scheme II was in great part a design prototype for Pixie Scheme III.
Pixie Scheme III is open-source under the GNU General Public License. Copies of the source distribution are available from the Software page of my web site, http://JayReynoldsFreeman.com/My/Software.html. One source distribution includes the source for Wraith Scheme, Pixie Scheme II, and Pixie Scheme III.
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
(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.
The Raspberry Pi family of single-board microcomputers was developed in the 2010s, and is widely used in education and by hobbyists. These boards are noted for powerful hardware input/output capability, with dedicated general-purpose input/output pins (gpio pins) that are directly controlled by the microprocessor itself. The Raspberry Pi family has grown rapidly, and is well and widely documented on the Internet, so I will not go into detail about all of them here -- try Google and Wikipedia.
The main point of this glossary entry is that the current release of Wraith Scheme is accompanied by a release of a closely-related program, Weasel Scheme, designed and tested to run on the Raspberry Pi 400, which is a version of the Raspberry Pi embedded within a dedicated keyboard. Weasel Scheme may also run on earlier versions of the Raspberry Pi -- though I doubt it, and have not tested it on earlier versions.
Weasel Scheme is rather an offshoot of the Wraith Scheme project, and has no separate documentation of its own: Use the documentation for Wraith Scheme, with the caveat that any Wraith Scheme feature that looks remotely like it requires a Macintosh to run on, almost certainly does. Weasel Scheme allows rudimentary access to the gpio pins of the Raspberry Pi 400, as documented in the Wraith Scheme Help File, and above herein. Better access may follow in the future.
"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:
(define (increment x) (+ x 1))
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:
(define next-number 1) (define (get-next-number) (let ((return-value next-number)) (set! next-number (+ next-number 1)) return-value))
Consecutive calls to "next-number" will return 1, 2, 3 ...
Here is another Scheme procedure which is not referentially transparent:
char-read
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" Wraith Scheme 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, 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, but I do not presently plan to support them in Wraith 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.
Wraith Scheme'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.
Wraith Scheme uses much the same kind of virtual machine model and implementation that Pixie Scheme did, but with several additional changes. See the Wraith Scheme Internals document for further details.
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 evaluatable 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.
I sometimes distinguish macros from Wraith Scheme's built-in special forms, because these two kinds of entities are handled somewhat differently in the operation of Wraith Scheme.
Every Wraith Scheme object has associated with it an instance of a data type peculiar to Wraith Scheme, 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 Wraith Scheme 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 Wraith Scheme object, and when the 64-bit field is a pointer, the tagged aval represents the binding of a Wraith Scheme 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.
Wraith Scheme 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:
(define (lnth l) (if (null? l) 0 (+ 1 (lnth (cdr l)))))
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 billion 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":
(define (foo n) ... (bar (- n 1)) )
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" with things set up so that when and if "bar" 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:
(define (foo n) (foo (- n 1)) )
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:
(define (lnth-aux l n) (if (null? l) n (lnth-aux (cdr l) (+ n 1))) ) (define (lnth l) (lnth-aux l 0))
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 billion 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".
Wraith Scheme 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.
The process of reclaiming memory this way is known as tail call optimization. Procedure calls in which it is possible to perform tail call optimization are said to be tail recursive.
Transcript files are a Scheme feature, described in the R5 report, for logging user interactions with Scheme. See the discussion of "transcript-on", "e::transcript-on-append", 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.
Wraith Scheme has enhancements to save and load world files; look for "e::save-world" and "e::load-world!" in the Command Summary portion of this document.
You might consider using a world file to save work in progress, just as you might save copies of a document you were working on in a word processor. You might also use a world file to save a standard starting state of some kind of work session, if it took a long time to create that state -- perhaps there were lots of files to load and lots of preliminary calculations to be done. Wraith Scheme loads a world file at startup, that was created with this latter function in mind.
Wraith Scheme has provision to have a world file execute a procedure when a world is loaded; that procedure can do anything you want. See "e::main" in the Command Summary portion of this document.
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.
-- Jay Reynolds Freeman, March 2023