This is Info file slib.info, produced by Makeinfo-1.64 from the input file slib.texi. This file documents SLIB, the portable Scheme library. Copyright (C) 1993 Todd R. Eigenschink Copyright (C) 1993, 1994, 1995 Aubrey Jaffer Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the author.  File: slib.info, Node: Cyclic Checksum, Next: Plotting, Prev: Random Numbers, Up: Numerics Cyclic Checksum =============== `(require 'make-crc)' - Function: make-port-crc - Function: make-port-crc DEGREE - Function: make-port-crc DEGREE GENERATOR Returns an expression for a procedure of one argument, a port. This procedure reads characters from the port until the end of file and returns the integer checksum of the bytes read. The integer DEGREE, if given, specifies the degree of the polynomial being computed - which is also the number of bits computed in the checksums. The default value is 32. The integer GENERATOR specifies the polynomial being computed. The power of 2 generating each 1 bit is the exponent of a term of the polynomial. The bit at position DEGREE is implicit and should not be part of GENERATOR. This allows systems with numbers limited to 32 bits to calculate 32 bit checksums. The default value of GENERATOR when DEGREE is 32 (its default) is: (make-port-crc 32 #b00000100110000010001110110110111) Creates a procedure to calculate the P1003.2/D11.2 (POSIX.2) 32-bit checksum from the polynomial: 32 26 23 22 16 12 11 ( x + x + x + x + x + x + x + 10 8 7 5 4 2 1 x + x + x + x + x + x + x + 1 ) mod 2 (require 'make-crc) (define crc32 (slib:eval (make-port-crc))) (define (file-check-sum file) (call-with-input-file file crc32)) (file-check-sum (in-vicinity (library-vicinity) "ratize.scm")) => 3553047446  File: slib.info, Node: Plotting, Next: Root Finding, Prev: Cyclic Checksum, Up: Numerics Plotting on Character Devices ============================= `(require 'charplot)' The plotting procedure is made available through the use of the `charplot' package. `charplot' is loaded by inserting `(require 'charplot)' before the code that uses this procedure. - Variable: charplot:height The number of rows to make the plot vertically. - Variable: charplot:width The number of columns to make the plot horizontally. - Procedure: plot! COORDS X-LABEL Y-LABEL COORDS is a list of pairs of x and y coordinates. X-LABEL and Y-LABEL are strings with which to label the x and y axes. Example: (require 'charplot) (set! charplot:height 19) (set! charplot:width 45) (define (make-points n) (if (zero? n) '() (cons (cons (/ n 6) (sin (/ n 6))) (make-points (1- n))))) (plot! (make-points 37) "x" "Sin(x)") -| Sin(x) ______________________________________________ 1.25|- | | | 1|- **** | | ** ** | 750.0e-3|- * * | | * * | 500.0e-3|- * * | | * | 250.0e-3|- * | | * * | 0|-------------------*--------------------------| | * | -250.0e-3|- * * | | * * | -500.0e-3|- * | | * * | -750.0e-3|- * * | | ** ** | -1|- **** | |____________:_____._____:_____._____:_________| x 2 4  File: slib.info, Node: Root Finding, Prev: Plotting, Up: Numerics Root Finding ============ `(require 'root)' - Function: newtown:find-integer-root F DF/DX X0 Given integer valued procedure F, its derivative (with respect to its argument) DF/DX, and initial integer value X0 for which DF/DX(X0) is non-zero, returns an integer X for which F(X) is closer to zero than either of the integers adjacent to X; or returns `#f' if such an integer can't be found. To find the closest integer to a given integers square root: (define (integer-sqrt y) (newton:find-integer-root (lambda (x) (- (* x x) y)) (lambda (x) (* 2 x)) (ash 1 (quotient (integer-length y) 2)))) (integer-sqrt 15) => 4 - Function: integer-sqrt Y Given a non-negative integer Y, returns the rounded square-root of Y. - Function: newton:find-root F DF/DX X0 PREC Given real valued procedures F, DF/DX of one (real) argument, initial real value X0 for which DF/DX(X0) is non-zero, and positive real number PREC, returns a real X for which `abs'(F(X)) is less than PREC; or returns `#f' if such a real can't be found. If `prec' is instead a negative integer, `newton:find-root' returns the result of -PREC iterations. H. J. Orchard, `The Laguerre Method for Finding the Zeros of Polynomials', IEEE Transactions on Circuits and Systems, Vol. 36, No. 11, November 1989, pp 1377-1381. There are 2 errors in Orchard's Table II. Line k=2 for starting value of 1000+j0 should have Z_k of 1.0475 + j4.1036 and line k=2 for starting value of 0+j1000 should have Z_k of 1.0988 + j4.0833. - Function: laguerre:find-root F DF/DZ DDF/DZ^2 Z0 PREC Given complex valued procedure F of one (complex) argument, its derivative (with respect to its argument) DF/DX, its second derivative DDF/DZ^2, initial complex value Z0, and positive real number PREC, returns a complex number Z for which `magnitude'(F(Z)) is less than PREC; or returns `#f' if such a number can't be found. If `prec' is instead a negative integer, `laguerre:find-root' returns the result of -PREC iterations. - Function: laguerre:find-polynomial-root DEG F DF/DZ DDF/DZ^2 Z0 PREC Given polynomial procedure F of integer degree DEG of one argument, its derivative (with respect to its argument) DF/DX, its second derivative DDF/DZ^2, initial complex value Z0, and positive real number PREC, returns a complex number Z for which `magnitude'(F(Z)) is less than PREC; or returns `#f' if such a number can't be found. If `prec' is instead a negative integer, `laguerre:find-polynomial-root' returns the result of -PREC iterations.  File: slib.info, Node: Procedures, Next: Standards Support, Prev: Numerics, Up: Top Procedures ********** Anything that doesn't fall neatly into any of the other categories winds up here. * Menu: * Batch:: 'batch * Common List Functions:: 'common-list-functions * Format:: 'format * Generic-Write:: 'generic-write * Line I/O:: 'line-i/o * Multi-Processing:: 'process * Object-To-String:: 'object->string * Pretty-Print:: 'pretty-print, 'pprint-file * Sorting:: 'sort * Topological Sort:: * Standard Formatted I/O:: 'printf, 'scanf * String-Case:: 'string-case * String Ports:: 'string-port * String Search:: * Tektronix Graphics Support:: * Tree Operations:: 'tree  File: slib.info, Node: Batch, Next: Common List Functions, Prev: Procedures, Up: Procedures Batch ===== `(require 'batch)' The batch procedures provide a way to write and execute portable scripts for a variety of operating systems. Each `batch:' procedure takes as its first argument a parameter-list (*note Parameter lists::.). This parameter-list argument PARMS contains named associations. Batch currently uses 2 of these: `batch-port' The port on which to write lines of the batch file. `batch-dialect' The syntax of batch file to generate. Currently supported are: * unix * dos * vms * system * *unknown* `batch.scm' uses 2 enhanced relational tables (*note Database Utilities::.) to store information linking the names of `operating-system's to `batch-dialect'es. - Function: batch:initialize! DATABASE Defines `operating-system' and `batch-dialect' tables and adds the domain `operating-system' to the enhanced relational database DATABASE. - Variable: batch:platform Is batch's best guess as to which operating-system it is running under. `batch:platform' is set to `(software-type)' (*note Configuration::.) unless `(software-type)' is `unix', in which case finer distinctions are made. - Function: batch:call-with-output-script PARMS FILE PROC PROC should be a procedure of one argument. If FILE is an output-port, `batch:call-with-output-script' writes an appropriate header to FILE and then calls PROC with FILE as the only argument. If FILE is a string, `batch:call-with-output-script' opens a output-file of name FILE, writes an appropriate header to FILE, and then calls PROC with the newly opened port as the only argument. Otherwise, `batch:call-with-output-script' acts as if it was called with the result of `(current-output-port)' as its third argument. - Function: batch:apply-chop-to-fit PROC ARG1 ARG2 ... LIST The procedure PROC must accept at least one argument and return `#t' if successful, `#f' if not. `batch:apply-chop-to-fit' calls PROC with ARG1, ARG2, ..., and CHUNK, where CHUNK is a subset of LIST. `batch:apply-chop-to-fit' tries PROC with successively smaller subsets of LIST until either PROC returns non-false, or the CHUNKs become empty. The rest of the `batch:' procedures write (or execute if `batch-dialect' is `system') commands to the batch port which has been added to PARMS or `(copy-tree PARMS)' by the code: (adjoin-parameters! PARMS (list 'batch-port PORT)) - Function: batch:system PARMS STRING1 STRING2 ... Calls `batch:try-system' (below) with arguments, but signals an error if `batch:try-system' returns `#f'. These functions return a non-false value if the command was successfully translated into the batch dialect and `#f' if not. In the case of the `system' dialect, the value is non-false if the operation suceeded. - Function: batch:try-system PARMS STRING1 STRING2 ... Writes a command to the `batch-port' in PARMS which executes the program named STRING1 with arguments STRING2 .... - Function: batch:run-script PARMS STRING1 STRING2 ... Writes a command to the `batch-port' in PARMS which executes the batch script named STRING1 with arguments STRING2 .... *Note:* `batch:run-script' and `batch:try-system' are not the same for some operating systems (VMS). - Function: batch:comment PARMS LINE1 ... Writes comment lines LINE1 ... to the `batch-port' in PARMS. - Function: batch:lines->file PARMS FILE LINE1 ... Writes commands to the `batch-port' in PARMS which create a file named FILE with contents LINE1 .... - Function: batch:delete-file PARMS FILE Writes a command to the `batch-port' in PARMS which deletes the file named FILE. - Function: batch:rename-file PARMS OLD-NAME NEW-NAME Writes a command to the `batch-port' in PARMS which renames the file OLD-NAME to NEW-NAME. In addition, batch provides some small utilities very useful for writing scripts: - Function: replace-suffix STR OLD NEW Returns a new string similar to `str' but with the suffix string OLD removed and the suffix string NEW appended. If the end of STR does not match OLD, an error is signaled. - Function: string-join JOINER STRING1 ... Returns a new string consisting of all the strings STRING1 ... in order appended together with the string JOINER between each adjacent pair. - Function: must-be-first LIST1 LIST2 Returns a new list consisting of the elements of LIST2 ordered so that if some elements of LIST1 are `equal?' to elements of LIST2, then those elements will appear first and in the order of LIST1. - Function: must-be-last LIST1 LIST2 Returns a new list consisting of the elements of LIST1 ordered so that if some elements of LIST2 are `equal?' to elements of LIST1, then those elements will appear last and in the order of LIST2. - Function: os->batch-dialect OSNAME Returns its best guess for the `batch-dialect' to be used for the operating-system named OSNAME. `os->batch-dialect' uses the tables added to DATABASE by `batch:initialize!'. Here is an example of the use of most of batch's procedures: (require 'database-utilities) (require 'parameters) (require 'batch) (define batch (create-database #f 'alist-table)) (batch:initialize! batch) (define my-parameters (list (list 'batch-dialect (os->batch-dialect batch:platform)) (list 'platform batch:platform) (list 'batch-port (current-output-port)))) ;gets filled in later (batch:call-with-output-script my-parameters "my-batch" (lambda (batch-port) (adjoin-parameters! my-parameters (list 'batch-port batch-port)) (and (batch:comment my-parameters "================ Write file with C program.") (batch:rename-file my-parameters "hello.c" "hello.c~") (batch:lines->file my-parameters "hello.c" "#include " "int main(int argc, char **argv)" "{" " printf(\"hello world\\n\");" " return 0;" "}" ) (batch:system my-parameters "cc" "-c" "hello.c") (batch:system my-parameters "cc" "-o" "hello" (replace-suffix "hello.c" ".c" ".o")) (batch:system my-parameters "hello") (batch:delete-file my-parameters "hello") (batch:delete-file my-parameters "hello.c") (batch:delete-file my-parameters "hello.o") (batch:delete-file my-parameters "my-batch") ))) Produces the file `my-batch': #!/bin/sh # "my-batch" build script created Sat Jun 10 21:20:37 1995 # ================ Write file with C program. mv -f hello.c hello.c~ rm -f hello.c echo '#include '>>hello.c echo 'int main(int argc, char **argv)'>>hello.c echo '{'>>hello.c echo ' printf("hello world\n");'>>hello.c echo ' return 0;'>>hello.c echo '}'>>hello.c cc -c hello.c cc -o hello hello.o hello rm -f hello rm -f hello.c rm -f hello.o rm -f my-batch When run, `my-batch' prints: bash$ my-batch mv: hello.c: No such file or directory hello world  File: slib.info, Node: Common List Functions, Next: Format, Prev: Batch, Up: Procedures Common List Functions ===================== `(require 'common-list-functions)' The procedures below follow the Common LISP equivalents apart from optional arguments in some cases. * Menu: * List construction:: * Lists as sets:: * Lists as sequences:: * Destructive list operations:: * Non-List functions::  File: slib.info, Node: List construction, Next: Lists as sets, Prev: Common List Functions, Up: Common List Functions List construction ----------------- - Function: make-list K . INIT `make-list' creates and returns a list of K elements. If INIT is included, all elements in the list are initialized to INIT. Example: (make-list 3) => (# # #) (make-list 5 'foo) => (foo foo foo foo foo) - Function: list* X . Y Works like `list' except that the cdr of the last pair is the last argument unless there is only one argument, when the result is just that argument. Sometimes called `cons*'. E.g.: (list* 1) => 1 (list* 1 2 3) => (1 2 . 3) (list* 1 2 '(3 4)) => (1 2 3 4) (list* ARGS '()) == (list ARGS) - Function: copy-list LST `copy-list' makes a copy of LST using new pairs and returns it. Only the top level of the list is copied, i.e., pairs forming elements of the copied list remain `eq?' to the corresponding elements of the original; the copy is, however, not `eq?' to the original, but is `equal?' to it. Example: (copy-list '(foo foo foo)) => (foo foo foo) (define q '(foo bar baz bang)) (define p q) (eq? p q) => #t (define r (copy-list q)) (eq? q r) => #f (equal? q r) => #t (define bar '(bar)) (eq? bar (car (copy-list (list bar 'foo)))) => #t  File: slib.info, Node: Lists as sets, Next: Lists as sequences, Prev: List construction, Up: Common List Functions Lists as sets ------------- `eq?' is used to test for membership by all the procedures below which treat lists as sets. - Function: adjoin E L `adjoin' returns the adjoint of the element E and the list L. That is, if E is in L, `adjoin' returns L, otherwise, it returns `(cons E L)'. Example: (adjoin 'baz '(bar baz bang)) => (bar baz bang) (adjoin 'foo '(bar baz bang)) => (foo bar baz bang) - Function: union L1 L2 `union' returns the combination of L1 and L2. Duplicates between L1 and L2 are culled. Duplicates within L1 or within L2 may or may not be removed. Example: (union '(1 2 3 4) '(5 6 7 8)) => (4 3 2 1 5 6 7 8) (union '(1 2 3 4) '(3 4 5 6)) => (2 1 3 4 5 6) - Function: intersection L1 L2 `intersection' returns all elements that are in both L1 and L2. Example: (intersection '(1 2 3 4) '(3 4 5 6)) => (3 4) (intersection '(1 2 3 4) '(5 6 7 8)) => () - Function: set-difference L1 L2 `set-difference' returns the union of all elements that are in L1 but not in L2. Example: (set-difference '(1 2 3 4) '(3 4 5 6)) => (1 2) (set-difference '(1 2 3 4) '(1 2 3 4 5 6)) => () - Function: member-if PRED LST `member-if' returns LST if `(PRED ELEMENT)' is `#t' for any ELEMENT in LST. Returns `#f' if PRED does not apply to any ELEMENT in LST. Example: (member-if vector? '(1 2 3 4)) => #f (member-if number? '(1 2 3 4)) => (1 2 3 4) - Function: some PRED LST . MORE-LSTS PRED is a boolean function of as many arguments as there are list arguments to `some' i.e., LST plus any optional arguments. PRED is applied to successive elements of the list arguments in order. `some' returns `#t' as soon as one of these applications returns `#t', and is `#f' if none returns `#t'. All the lists should have the same length. Example: (some odd? '(1 2 3 4)) => #t (some odd? '(2 4 6 8)) => #f (some > '(2 3) '(1 4)) => #f - Function: every PRED LST . MORE-LSTS `every' is analogous to `some' except it returns `#t' if every application of PRED is `#t' and `#f' otherwise. Example: (every even? '(1 2 3 4)) => #f (every even? '(2 4 6 8)) => #t (every > '(2 3) '(1 4)) => #f - Function: notany PRED . LST `notany' is analogous to `some' but returns `#t' if no application of PRED returns `#t' or `#f' as soon as any one does. - Function: notevery PRED . LST `notevery' is analogous to `some' but returns `#t' as soon as an application of PRED returns `#f', and `#f' otherwise. Example: (notevery even? '(1 2 3 4)) => #t (notevery even? '(2 4 6 8)) => #f - Function: find-if PRED LST `find-if' searches for the first ELEMENT in LST such that `(PRED ELEMENT)' returns `#t'. If it finds any such ELEMENT in LST, ELEMENT is returned. Otherwise, `#f' is returned. Example: (find-if number? '(foo 1 bar 2)) => 1 (find-if number? '(foo bar baz bang)) => #f (find-if symbol? '(1 2 foo bar)) => foo - Function: remove ELT LST `remove' removes all occurrences of ELT from LST using `eqv?' to test for equality and returns everything that's left. N.B.: other implementations (Chez, Scheme->C and T, at least) use `equal?' as the equality test. Example: (remove 1 '(1 2 1 3 1 4 1 5)) => (2 3 4 5) (remove 'foo '(bar baz bang)) => (bar baz bang) - Function: remove-if PRED LST `remove-if' removes all ELEMENTs from LST where `(PRED ELEMENT)' is `#t' and returns everything that's left. Example: (remove-if number? '(1 2 3 4)) => () (remove-if even? '(1 2 3 4 5 6 7 8)) => (1 3 5 7) - Function: remove-if-not PRED LST `remove-if-not' removes all ELEMENTs from LST for which `(PRED ELEMENT)' is `#f' and returns everything that's left. Example: (remove-if-not number? '(foo bar baz)) => () (remove-if-not odd? '(1 2 3 4 5 6 7 8)) => (1 3 5 7) - Function: has-duplicates? LST returns `#t' if 2 members of LST are `equal?', `#f' otherwise. Example: (has-duplicates? '(1 2 3 4)) => #f (has-duplicates? '(2 4 3 4)) => #t  File: slib.info, Node: Lists as sequences, Next: Destructive list operations, Prev: Lists as sets, Up: Common List Functions Lists as sequences ------------------ - Function: position OBJ LST `position' returns the 0-based position of OBJ in LST, or `#f' if OBJ does not occur in LST. Example: (position 'foo '(foo bar baz bang)) => 0 (position 'baz '(foo bar baz bang)) => 2 (position 'oops '(foo bar baz bang)) => #f - Function: reduce P LST `reduce' combines all the elements of a sequence using a binary operation (the combination is left-associative). For example, using `+', one can add up all the elements. `reduce' allows you to apply a function which accepts only two arguments to more than 2 objects. Functional programmers usually refer to this as "foldl". `collect:reduce' (*Note Collections::) provides a version of `collect' generalized to collections. Example: (reduce + '(1 2 3 4)) => 10 (define (bad-sum . l) (reduce + l)) (bad-sum 1 2 3 4) == (reduce + (1 2 3 4)) == (+ (+ (+ 1 2) 3) 4) => 10 (bad-sum) == (reduce + ()) => () (reduce string-append '("hello" "cruel" "world")) == (string-append (string-append "hello" "cruel") "world") => "hellocruelworld" (reduce anything '()) => () (reduce anything '(x)) => x What follows is a rather non-standard implementation of `reverse' in terms of `reduce' and a combinator elsewhere called "C". ;;; Contributed by Jussi Piitulainen (jpiitula@ling.helsinki.fi) (define commute (lambda (f) (lambda (x y) (f y x)))) (define reverse (lambda (args) (reduce-init (commute cons) args))) - Function: reduce-init P INIT LST `reduce-init' is the same as reduce, except that it implicitly inserts INIT at the start of the list. `reduce-init' is preferred if you want to handle the null list, the one-element, and lists with two or more elements consistently. It is common to use the operator's idempotent as the initializer. Functional programmers usually call this "foldl". Example: (define (sum . l) (reduce-init + 0 l)) (sum 1 2 3 4) == (reduce-init + 0 (1 2 3 4)) == (+ (+ (+ (+ 0 1) 2) 3) 4) => 10 (sum) == (reduce-init + 0 '()) => 0 (reduce-init string-append "@" '("hello" "cruel" "world")) == (string-append (string-append (string-append "@" "hello") "cruel") "world") => "@hellocruelworld" Given a differentiation of 2 arguments, `diff', the following will differentiate by any number of variables. (define (diff* exp . vars) (reduce-init diff exp vars)) Example: ;;; Real-world example: Insertion sort using reduce-init. (define (insert l item) (if (null? l) (list item) (if (< (car l) item) (cons (car l) (insert (cdr l) item)) (cons item l)))) (define (insertion-sort l) (reduce-init insert '() l)) (insertion-sort '(3 1 4 1 5) == (reduce-init insert () (3 1 4 1 5)) == (insert (insert (insert (insert (insert () 3) 1) 4) 1) 5) == (insert (insert (insert (insert (3)) 1) 4) 1) 5) == (insert (insert (insert (1 3) 4) 1) 5) == (insert (insert (1 3 4) 1) 5) == (insert (1 1 3 4) 5) => (1 1 3 4 5) - Function: butlast LST N `butlast' returns all but the last N elements of LST. Example: (butlast '(1 2 3 4) 3) => (1) (butlast '(1 2 3 4) 4) => () - Function: nthcdr N LST `nthcdr' takes N `cdr's of LST and returns the result. Thus `(nthcdr 3 LST)' == `(cdddr LST)' Example: (nthcdr 2 '(1 2 3 4)) => (3 4) (nthcdr 0 '(1 2 3 4)) => (1 2 3 4) - Function: last LST N `last' returns the last N elements of LST. N must be a non-negative integer. Example: (last '(foo bar baz bang) 2) => (baz bang) (last '(1 2 3) 0) => 0  File: slib.info, Node: Destructive list operations, Next: Non-List functions, Prev: Lists as sequences, Up: Common List Functions Destructive list operations --------------------------- These procedures may mutate the list they operate on, but any such mutation is undefined. - Procedure: nconc ARGS `nconc' destructively concatenates its arguments. (Compare this with `append', which copies arguments rather than destroying them.) Sometimes called `append!' (*Note Rev2 Procedures::). Example: You want to find the subsets of a set. Here's the obvious way: (define (subsets set) (if (null? set) '(()) (append (mapcar (lambda (sub) (cons (car set) sub)) (subsets (cdr set))) (subsets (cdr set))))) But that does way more consing than you need. Instead, you could replace the `append' with `nconc', since you don't have any need for all the intermediate results. Example: (define x '(a b c)) (define y '(d e f)) (nconc x y) => (a b c d e f) x => (a b c d e f) `nconc' is the same as `append!' in `sc2.scm'. - Procedure: nreverse LST `nreverse' reverses the order of elements in LST by mutating `cdr's of the list. Sometimes called `reverse!'. Example: (define foo '(a b c)) (nreverse foo) => (c b a) foo => (a) Some people have been confused about how to use `nreverse', thinking that it doesn't return a value. It needs to be pointed out that (set! lst (nreverse lst)) is the proper usage, not (nreverse lst) The example should suffice to show why this is the case. - Procedure: delete ELT LST - Procedure: delete-if PRED LST - Procedure: delete-if-not PRED LST Destructive versions of `remove' `remove-if', and `remove-if-not'. Example: (define lst '(foo bar baz bang)) (delete 'foo lst) => (bar baz bang) lst => (foo bar baz bang) (define lst '(1 2 3 4 5 6 7 8 9)) (delete-if odd? lst) => (2 4 6 8) lst => (1 2 4 6 8) Some people have been confused about how to use `delete', `delete-if', and `delete-if', thinking that they dont' return a value. It needs to be pointed out that (set! lst (delete el lst)) is the proper usage, not (delete el lst) The examples should suffice to show why this is the case.  File: slib.info, Node: Non-List functions, Prev: Destructive list operations, Up: Common List Functions Non-List functions ------------------ - Function: and? . ARGS `and?' checks to see if all its arguments are true. If they are, `and?' returns `#t', otherwise, `#f'. (In contrast to `and', this is a function, so all arguments are always evaluated and in an unspecified order.) Example: (and? 1 2 3) => #t (and #f 1 2) => #f - Function: or? . ARGS `or?' checks to see if any of its arguments are true. If any is true, `or?' returns `#t', and `#f' otherwise. (To `or' as `and?' is to `and'.) Example: (or? 1 2 #f) => #t (or? #f #f #f) => #f - Function: atom? OBJECT Returns `#t' if OBJECT is not a pair and `#f' if it is pair. (Called `atom' in Common LISP.) (atom? 1) => #t (atom? '(1 2)) => #f (atom? #(1 2)) ; dubious! => #t - Function: type-of OBJECT Returns a symbol name for the type of OBJECT. - Function: coerce OBJECT RESULT-TYPE Converts and returns OBJECT of type `char', `number', `string', `symbol', `list', or `vector' to RESULT-TYPE (which must be one of these symbols).  File: slib.info, Node: Format, Next: Generic-Write, Prev: Common List Functions, Up: Procedures Format ====== `(require 'format)' * Menu: * Format Interface:: * Format Specification::  File: slib.info, Node: Format Interface, Next: Format Specification, Prev: Format, Up: Format Format Interface ---------------- - Function: format DESTINATION FORMAT-STRING . ARGUMENTS An almost complete implementation of Common LISP format description according to the CL reference book `Common LISP' from Guy L. Steele, Digital Press. Backward compatible to most of the available Scheme format implementations. Returns `#t', `#f' or a string; has side effect of printing according to FORMAT-STRING. If DESTINATION is `#t', the output is to the current output port and `#t' is returned. If DESTINATION is `#f', a formatted string is returned as the result of the call. NEW: If DESTINATION is a string, DESTINATION is regarded as the format string; FORMAT-STRING is then the first argument and the output is returned as a string. If DESTINATION is a number, the output is to the current error port if available by the implementation. Otherwise DESTINATION must be an output port and `#t' is returned. FORMAT-STRING must be a string. In case of a formatting error format returns `#f' and prints a message on the current output or error port. Characters are output as if the string were output by the `display' function with the exception of those prefixed by a tilde (~). For a detailed description of the FORMAT-STRING syntax please consult a Common LISP format reference manual. For a test suite to verify this format implementation load `formatst.scm'. Please send bug reports to `lutzeb@cs.tu-berlin.de'. Note: `format' is not reentrant, i.e. only one `format'-call may be executed at a time.  File: slib.info, Node: Format Specification, Prev: Format Interface, Up: Format Format Specification (Format version 3.0) ----------------------------------------- Please consult a Common LISP format reference manual for a detailed description of the format string syntax. For a demonstration of the implemented directives see `formatst.scm'. This implementation supports directive parameters and modifiers (`:' and `@' characters). Multiple parameters must be separated by a comma (`,'). Parameters can be numerical parameters (positive or negative), character parameters (prefixed by a quote character (`''), variable parameters (`v'), number of rest arguments parameter (`#'), empty and default parameters. Directive characters are case independent. The general form of a directive is: DIRECTIVE ::= ~{DIRECTIVE-PARAMETER,}[:][@]DIRECTIVE-CHARACTER DIRECTIVE-PARAMETER ::= [ [-|+]{0-9}+ | 'CHARACTER | v | # ] Implemented CL Format Control Directives ........................................ Documentation syntax: Uppercase characters represent the corresponding control directive characters. Lowercase characters represent control directive parameter descriptions. `~A' Any (print as `display' does). `~@A' left pad. `~MINCOL,COLINC,MINPAD,PADCHARA' full padding. `~S' S-expression (print as `write' does). `~@S' left pad. `~MINCOL,COLINC,MINPAD,PADCHARS' full padding. `~D' Decimal. `~@D' print number sign always. `~:D' print comma separated. `~MINCOL,PADCHAR,COMMACHARD' padding. `~X' Hexadecimal. `~@X' print number sign always. `~:X' print comma separated. `~MINCOL,PADCHAR,COMMACHARX' padding. `~O' Octal. `~@O' print number sign always. `~:O' print comma separated. `~MINCOL,PADCHAR,COMMACHARO' padding. `~B' Binary. `~@B' print number sign always. `~:B' print comma separated. `~MINCOL,PADCHAR,COMMACHARB' padding. `~NR' Radix N. `~N,MINCOL,PADCHAR,COMMACHARR' padding. `~@R' print a number as a Roman numeral. `~:R' print a number as an ordinal English number. `~:@R' print a number as a cardinal English number. `~P' Plural. `~@P' prints `y' and `ies'. `~:P' as `~P but jumps 1 argument backward.' `~:@P' as `~@P but jumps 1 argument backward.' `~C' Character. `~@C' prints a character as the reader can understand it (i.e. `#\' prefixing). `~:C' prints a character as emacs does (eg. `^C' for ASCII 03). `~F' Fixed-format floating-point (prints a flonum like MMM.NNN). `~WIDTH,DIGITS,SCALE,OVERFLOWCHAR,PADCHARF' `~@F' If the number is positive a plus sign is printed. `~E' Exponential floating-point (prints a flonum like MMM.NNN`E'EE). `~WIDTH,DIGITS,EXPONENTDIGITS,SCALE,OVERFLOWCHAR,PADCHAR,EXPONENTCHARE' `~@E' If the number is positive a plus sign is printed. `~G' General floating-point (prints a flonum either fixed or exponential). `~WIDTH,DIGITS,EXPONENTDIGITS,SCALE,OVERFLOWCHAR,PADCHAR,EXPONENTCHARG' `~@G' If the number is positive a plus sign is printed. `~$' Dollars floating-point (prints a flonum in fixed with signs separated). `~DIGITS,SCALE,WIDTH,PADCHAR$' `~@$' If the number is positive a plus sign is printed. `~:@$' A sign is always printed and appears before the padding. `~:$' The sign appears before the padding. `~%' Newline. `~N%' print N newlines. `~&' print newline if not at the beginning of the output line. `~N&' prints `~&' and then N-1 newlines. `~|' Page Separator. `~N|' print N page separators. `~~' Tilde. `~N~' print N tildes. `~' Continuation Line. `~:' newline is ignored, white space left. `~@' newline is left, white space ignored. `~T' Tabulation. `~@T' relative tabulation. `~COLNUM,COLINCT' full tabulation. `~?' Indirection (expects indirect arguments as a list). `~@?' extracts indirect arguments from format arguments. `~(STR~)' Case conversion (converts by `string-downcase'). `~:(STR~)' converts by `string-capitalize'. `~@(STR~)' converts by `string-capitalize-first'. `~:@(STR~)' converts by `string-upcase'. `~*' Argument Jumping (jumps 1 argument forward). `~N*' jumps N arguments forward. `~:*' jumps 1 argument backward. `~N:*' jumps N arguments backward. `~@*' jumps to the 0th argument. `~N@*' jumps to the Nth argument (beginning from 0) `~[STR0~;STR1~;...~;STRN~]' Conditional Expression (numerical clause conditional). `~N[' take argument from N. `~@[' true test conditional. `~:[' if-else-then conditional. `~;' clause separator. `~:;' default clause follows. `~{STR~}' Iteration (args come from the next argument (a list)). `~N{' at most N iterations. `~:{' args from next arg (a list of lists). `~@{' args from the rest of arguments. `~:@{' args from the rest args (lists). `~^' Up and out. `~N^' aborts if N = 0 `~N,M^' aborts if N = M `~N,M,K^' aborts if N <= M <= K Not Implemented CL Format Control Directives ............................................ `~:A' print `#f' as an empty list (see below). `~:S' print `#f' as an empty list (see below). `~<~>' Justification. `~:^' (sorry I don't understand its semantics completely) Extended, Replaced and Additional Control Directives .................................................... `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHD' `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHX' `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHO' `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHB' `~N,MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHR' COMMAWIDTH is the number of characters between two comma characters. `~I' print a R4RS complex number as `~F~@Fi' with passed parameters for `~F'. `~Y' Pretty print formatting of an argument for scheme code lists. `~K' Same as `~?.' `~!' Flushes the output if format DESTINATION is a port. `~_' Print a `#\space' character `~N_' print N `#\space' characters. `~/' Print a `#\tab' character `~N/' print N `#\tab' characters. `~NC' Takes N as an integer representation for a character. No arguments are consumed. N is converted to a character by `integer->char'. N must be a positive decimal number. `~:S' Print out readproof. Prints out internal objects represented as `#<...>' as strings `"#<...>"' so that the format output can always be processed by `read'. `~:A' Print out readproof. Prints out internal objects represented as `#<...>' as strings `"#<...>"' so that the format output can always be processed by `read'. `~Q' Prints information and a copyright notice on the format implementation. `~:Q' prints format version. `~F, ~E, ~G, ~$' may also print number strings, i.e. passing a number as a string and format it accordingly. Configuration Variables ....................... Format has some configuration variables at the beginning of `format.scm' to suit the systems and users needs. There should be no modification necessary for the configuration that comes with SLIB. If modification is desired the variable should be set after the format code is loaded. Format detects automatically if the running scheme system implements floating point numbers and complex numbers. FORMAT:SYMBOL-CASE-CONV Symbols are converted by `symbol->string' so the case type of the printed symbols is implementation dependent. `format:symbol-case-conv' is a one arg closure which is either `#f' (no conversion), `string-upcase', `string-downcase' or `string-capitalize'. (default `#f') FORMAT:IOBJ-CASE-CONV As FORMAT:SYMBOL-CASE-CONV but applies for the representation of implementation internal objects. (default `#f') FORMAT:EXPCH The character prefixing the exponent value in `~E' printing. (default `#\E') Compatibility With Other Format Implementations ............................................... SLIB format 2.x: See `format.doc'. SLIB format 1.4: Downward compatible except for padding support and `~A', `~S', `~P', `~X' uppercase printing. SLIB format 1.4 uses C-style `printf' padding support which is completely replaced by the CL `format' padding style. MIT C-Scheme 7.1: Downward compatible except for `~', which is not documented (ignores all characters inside the format string up to a newline character). (7.1 implements `~a', `~s', ~NEWLINE, `~~', `~%', numerical and variable parameters and `:/@' modifiers in the CL sense). Elk 1.5/2.0: Downward compatible except for `~A' and `~S' which print in uppercase. (Elk implements `~a', `~s', `~~', and `~%' (no directive parameters or modifiers)). Scheme->C 01nov91: Downward compatible except for an optional destination parameter: S2C accepts a format call without a destination which returns a formatted string. This is equivalent to a #f destination in S2C. (S2C implements `~a', `~s', `~c', `~%', and `~~' (no directive parameters or modifiers)). This implementation of format is solely useful in the SLIB context because it requires other components provided by SLIB.  File: slib.info, Node: Generic-Write, Next: Line I/O, Prev: Format, Up: Procedures Generic-Write ============= `(require 'generic-write)' `generic-write' is a procedure that transforms a Scheme data value (or Scheme program expression) into its textual representation and prints it. The interface to the procedure is sufficiently general to easily implement other useful formatting procedures such as pretty printing, output to a string and truncated output. - Procedure: generic-write OBJ DISPLAY? WIDTH OUTPUT OBJ Scheme data value to transform. DISPLAY? Boolean, controls whether characters and strings are quoted. WIDTH Extended boolean, selects format: #f single line format integer > 0 pretty-print (value = max nb of chars per line) OUTPUT Procedure of 1 argument of string type, called repeatedly with successive substrings of the textual representation. This procedure can return `#f' to stop the transformation. The value returned by `generic-write' is undefined. Examples: (write obj) == (generic-write obj #f #f DISPLAY-STRING) (display obj) == (generic-write obj #t #f DISPLAY-STRING) where DISPLAY-STRING == (lambda (s) (for-each write-char (string->list s)) #t)  File: slib.info, Node: Line I/O, Next: Multi-Processing, Prev: Generic-Write, Up: Procedures Line I/O ======== `(require 'line-i/o)' - Function: read-line - Function: read-line PORT Returns a string of the characters up to, but not including a newline or end of file, updating PORT to point to the character following the newline. If no characters are available, an end of file object is returned. PORT may be omitted, in which case it defaults to the value returned by `current-input-port'. - Function: read-line! STRING - Function: read-line! STRING PORT Fills STRING with characters up to, but not including a newline or end of file, updating the port to point to the last character read or following the newline if it was read. If no characters are available, an end of file object is returned. If a newline or end of file was found, the number of characters read is returned. Otherwise, `#f' is returned. PORT may be omitted, in which case it defaults to the value returned by `current-input-port'. - Function: write-line STRING - Function: write-line STRING PORT Writes STRING followed by a newline to the given port and returns an unspecified value. Port may be omited, in which case it defaults to the value returned by `current-input-port'.  File: slib.info, Node: Multi-Processing, Next: Object-To-String, Prev: Line I/O, Up: Procedures Multi-Processing ================ `(require 'process)' - Procedure: add-process! PROC Adds proc, which must be a procedure (or continuation) capable of accepting accepting one argument, to the `process:queue'. The value returned is unspecified. The argument to PROC should be ignored. If PROC returns, the process is killed. - Procedure: process:schedule! Saves the current process on `process:queue' and runs the next process from `process:queue'. The value returned is unspecified. - Procedure: kill-process! Kills the current process and runs the next process from `process:queue'. If there are no more processes on `process:queue', `(slib:exit)' is called (*Note System::).  File: slib.info, Node: Object-To-String, Next: Pretty-Print, Prev: Multi-Processing, Up: Procedures Object-To-String ================ `(require 'object->string)' - Function: object->string OBJ Returns the textual representation of OBJ as a string.  File: slib.info, Node: Pretty-Print, Next: Sorting, Prev: Object-To-String, Up: Procedures Pretty-Print ============ `(require 'pretty-print)' - Procedure: pretty-print OBJ - Procedure: pretty-print OBJ PORT `pretty-print's OBJ on PORT. If PORT is not specified, `current-output-port' is used. Example: (pretty-print '((1 2 3 4 5) (6 7 8 9 10) (11 12 13 14 15) (16 17 18 19 20) (21 22 23 24 25))) -| ((1 2 3 4 5) -| (6 7 8 9 10) -| (11 12 13 14 15) -| (16 17 18 19 20) -| (21 22 23 24 25)) `(require 'pprint-file)' - Procedure: pprint-file INFILE - Procedure: pprint-file INFILE OUTFILE Pretty-prints all the code in INFILE. If OUTFILE is specified, the output goes to OUTFILE, otherwise it goes to `(current-output-port)'. - Function: pprint-filter-file INFILE PROC OUTFILE - Function: pprint-filter-file INFILE PROC INFILE is a port or a string naming an existing file. Scheme source code expressions and definitions are read from the port (or file) and PROC is applied to them sequentially. OUTFILE is a port or a string. If no OUTFILE is specified then `current-output-port' is assumed. These expanded expressions are then `pretty-print'ed to this port. Whitepsace and comments (introduced by `;') which are not part of scheme expressions are reproduced in the output. This procedure does not affect the values returned by `current-input-port' and `current-output-port'. `pprint-filter-file' can be used to pre-compile macro-expansion and thus can reduce loading time. The following will write into `exp-code.scm' the result of expanding all defmacros in `code.scm'. (require 'pprint-file) (require 'defmacroexpand) (defmacro:load "my-macros.scm") (pprint-filter-file "code.scm" defmacro:expand* "exp-code.scm")