mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-12 00:30:20 +02:00
12187 lines
491 KiB
Text
12187 lines
491 KiB
Text
This is slib.info, produced by makeinfo version 4.0 from slib.texi.
|
||
|
||
INFO-DIR-SECTION The Algorithmic Language Scheme
|
||
START-INFO-DIR-ENTRY
|
||
* SLIB: (slib). Scheme Library
|
||
END-INFO-DIR-ENTRY
|
||
|
||
This file documents SLIB, the portable Scheme library.
|
||
|
||
Copyright (C) 1993 Todd R. Eigenschink
|
||
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 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: Top, Next: The Library System, Prev: (dir), Up: (dir)
|
||
|
||
"SLIB" is a portable library for the programming language "Scheme". It
|
||
provides a platform independent framework for using "packages" of
|
||
Scheme procedures and syntax. As distributed, SLIB contains useful
|
||
packages for all Scheme implementations. Its catalog can be
|
||
transparently extended to accomodate packages specific to a site,
|
||
implementation, user, or directory.
|
||
|
||
* Menu:
|
||
|
||
* The Library System:: How to use and customize.
|
||
* Scheme Syntax Extension Packages::
|
||
* Textual Conversion Packages::
|
||
* Mathematical Packages::
|
||
* Database Packages::
|
||
* Other Packages::
|
||
* About SLIB:: Install, etc.
|
||
* Index::
|
||
|
||
|
||
File: slib.info, Node: The Library System, Next: Scheme Syntax Extension Packages, Prev: Top, Up: Top
|
||
|
||
The Library System
|
||
******************
|
||
|
||
* Menu:
|
||
|
||
* Feature:: SLIB names.
|
||
* Requesting Features::
|
||
* Library Catalogs::
|
||
* Catalog Compilation::
|
||
* Built-in Support::
|
||
* About this manual::
|
||
|
||
|
||
File: slib.info, Node: Feature, Next: Requesting Features, Prev: The Library System, Up: The Library System
|
||
|
||
Feature
|
||
=======
|
||
|
||
SLIB denotes "features" by symbols. SLIB maintains a list of features
|
||
supported by the Scheme "session". The set of features provided by a
|
||
session may change over time. Some features are properties of the
|
||
Scheme implementation being used. The following features detail what
|
||
sort of numbers are available from an implementation.
|
||
|
||
* 'inexact
|
||
|
||
* 'rational
|
||
|
||
* 'real
|
||
|
||
* 'complex
|
||
|
||
* 'bignum
|
||
|
||
Other features correspond to the presence of sets of Scheme procedures
|
||
or syntax (macros).
|
||
|
||
- Function: provided? feature
|
||
Returns `#t' if FEATURE is supported by the current Scheme session.
|
||
|
||
- Procedure: provide feature
|
||
Informs SLIB that FEATURE is supported. Henceforth `(provided?
|
||
FEATURE)' will return `#t'.
|
||
|
||
(provided? 'foo) => #f
|
||
(provide 'foo)
|
||
(provided? 'foo) => #t
|
||
|
||
|
||
File: slib.info, Node: Requesting Features, Next: Library Catalogs, Prev: Feature, Up: The Library System
|
||
|
||
Requesting Features
|
||
===================
|
||
|
||
SLIB creates and maintains a "catalog" mapping features to locations of
|
||
files introducing procedures and syntax denoted by those features.
|
||
|
||
At the beginning of each section of this manual, there is a line like
|
||
`(require 'FEATURE)'. The Scheme files comprising SLIB are cataloged
|
||
so that these feature names map to the corresponding files.
|
||
|
||
SLIB provides a form, `require', which loads the files providing the
|
||
requested feature.
|
||
|
||
- Procedure: require feature
|
||
* If `(provided? FEATURE)' is true, then `require' just returns
|
||
an unspecified value.
|
||
|
||
* Otherwise, if FEATURE is found in the catalog, then the
|
||
corresponding files will be loaded and an unspecified value
|
||
returned.
|
||
|
||
Subsequently `(provided? FEATURE)' will return `#t'.
|
||
|
||
* Otherwise (FEATURE not found in the catalog), an error is
|
||
signaled.
|
||
|
||
The catalog can also be queried using `require:feature->path'.
|
||
|
||
- Function: require:feature->path feature
|
||
* If FEATURE is already provided, then returns `#t'.
|
||
|
||
* Otherwise, if FEATURE is in the catalog, the path or list of
|
||
paths associated with FEATURE is returned.
|
||
|
||
* Otherwise, returns `#f'.
|
||
|
||
|
||
File: slib.info, Node: Library Catalogs, Next: Catalog Compilation, Prev: Requesting Features, Up: The Library System
|
||
|
||
Library Catalogs
|
||
================
|
||
|
||
At the start of a session no catalog is present, but is created with the
|
||
first catalog inquiry (such as `(require 'random)'). Several sources
|
||
of catalog information are combined to produce the catalog:
|
||
|
||
* standard SLIB packages.
|
||
|
||
* additional packages of interest to this site.
|
||
|
||
* packages specifically for the variety of Scheme which this session
|
||
is running.
|
||
|
||
* packages this user wants to always have available. This catalog
|
||
is the file `homecat' in the user's "HOME" directory.
|
||
|
||
* packages germane to working in this (current working) directory.
|
||
This catalog is the file `usercat' in the directory to which it
|
||
applies. One would typically `cd' to this directory before
|
||
starting the Scheme session.
|
||
|
||
Catalog files consist of one or more "association list"s. In the
|
||
circumstance where a feature symbol appears in more than one list, the
|
||
latter list's association is retrieved. Here are the supported formats
|
||
for elements of catalog lists:
|
||
|
||
`(FEATURE . <symbol>)'
|
||
Redirects to the feature named <symbol>.
|
||
|
||
`(FEATURE . "<path>")'
|
||
Loads file <path>.
|
||
|
||
`(FEATURE source "<path>")'
|
||
`slib:load's the Scheme source file <path>.
|
||
|
||
`(FEATURE compiled "<path>" ...)'
|
||
`slib:load-compiled's the files <path> ....
|
||
|
||
The various macro styles first `require' the named macro package, then
|
||
just load <path> or load-and-macro-expand <path> as appropriate for the
|
||
implementation.
|
||
|
||
`(FEATURE defmacro "<path>")'
|
||
`defmacro:load's the Scheme source file <path>.
|
||
|
||
`(FEATURE macro-by-example "<path>")'
|
||
`defmacro:load's the Scheme source file <path>.
|
||
|
||
`(FEATURE macro "<path>")'
|
||
`macro:load's the Scheme source file <path>.
|
||
|
||
`(FEATURE macros-that-work "<path>")'
|
||
`macro:load's the Scheme source file <path>.
|
||
|
||
`(FEATURE syntax-case "<path>")'
|
||
`macro:load's the Scheme source file <path>.
|
||
|
||
`(FEATURE syntactic-closures "<path>")'
|
||
`macro:load's the Scheme source file <path>.
|
||
|
||
Here is an example of a `usercat' catalog. A Program in this directory
|
||
can invoke the `run' feature with `(require 'run)'.
|
||
|
||
;;; "usercat": SLIB catalog additions for SIMSYNCH. -*-scheme-*-
|
||
|
||
(
|
||
(simsynch . "../synch/simsynch.scm")
|
||
(run . "../synch/run.scm")
|
||
(schlep . "schlep.scm")
|
||
)
|
||
|
||
|
||
File: slib.info, Node: Catalog Compilation, Next: Built-in Support, Prev: Library Catalogs, Up: The Library System
|
||
|
||
Catalog Compilation
|
||
===================
|
||
|
||
SLIB combines the catalog information which doesn't vary per user into
|
||
the file `slibcat' in the implementation-vicinity. Therefore `slibcat'
|
||
needs change only when new software is installed or compiled. Because
|
||
the actual pathnames of files can differ from installation to
|
||
installation, SLIB builds a separate catalog for each implementation it
|
||
is used with.
|
||
|
||
The definition of `*SLIB-VERSION*' in SLIB file `require.scm' is
|
||
checked against the catalog association of `*SLIB-VERSION*' to
|
||
ascertain when versions have changed. I recommend that the definition
|
||
of `*SLIB-VERSION*' be changed whenever the library is changed. If
|
||
multiple implementations of Scheme use SLIB, remember that recompiling
|
||
one `slibcat' will fix only that implementation's catalog.
|
||
|
||
The compilation scripts of Scheme implementations which work with SLIB
|
||
can automatically trigger catalog compilation by deleting `slibcat' or
|
||
by invoking a special form of `require':
|
||
|
||
- Procedure: require 'new-catalog
|
||
This will load `mklibcat', which compiles and writes a new
|
||
`slibcat'.
|
||
|
||
Another special form of `require' erases SLIB's catalog, forcing it to
|
||
be reloaded the next time the catalog is queried.
|
||
|
||
- Procedure: require #f
|
||
Removes SLIB's catalog information. This should be done before
|
||
saving an executable image so that, when restored, its catalog
|
||
will be loaded afresh.
|
||
|
||
Each file in the table below is descibed in terms of its file-system
|
||
independent "vicinity" (*note Vicinity::). The entries of a catalog in
|
||
the table override those of catalogs above it in the table.
|
||
|
||
`implementation-vicinity' `slibcat'
|
||
This file contains the associations for the packages comprising
|
||
SLIB, the `implcat' and the `sitecat's. The associations in the
|
||
other catalogs override those of the standard catalog.
|
||
|
||
`library-vicinity' `mklibcat.scm'
|
||
creates `slibcat'.
|
||
|
||
`library-vicinity' `sitecat'
|
||
This file contains the associations specific to an SLIB
|
||
installation.
|
||
|
||
`implementation-vicinity' `implcat'
|
||
This file contains the associations specific to an implementation
|
||
of Scheme. Different implementations of Scheme should have
|
||
different `implementation-vicinity'.
|
||
|
||
`implementation-vicinity' `mkimpcat.scm'
|
||
if present, creates `implcat'.
|
||
|
||
`implementation-vicinity' `sitecat'
|
||
This file contains the associations specific to a Scheme
|
||
implementation installation.
|
||
|
||
`home-vicinity' `homecat'
|
||
This file contains the associations specific to an SLIB user.
|
||
|
||
`user-vicinity' `usercat'
|
||
This file contains associations effecting only those sessions whose
|
||
"working directory" is `user-vicinity'.
|
||
|
||
|
||
File: slib.info, Node: Built-in Support, Next: About this manual, Prev: Catalog Compilation, Up: The Library System
|
||
|
||
Built-in Support
|
||
================
|
||
|
||
The procedures described in these sections are supported by all
|
||
implementations as part of the `*.init' files or by `require.scm'.
|
||
|
||
* Menu:
|
||
|
||
* Require:: Module Management
|
||
* Vicinity:: Pathname Management
|
||
* Configuration:: Characteristics of Scheme Implementation
|
||
* Input/Output:: Things not provided by the Scheme specs.
|
||
* Legacy::
|
||
* System:: LOADing, EVALing, ERRORing, and EXITing
|
||
|
||
|
||
File: slib.info, Node: Require, Next: Vicinity, Prev: Built-in Support, Up: Built-in Support
|
||
|
||
Require
|
||
-------
|
||
|
||
- Variable: *features*
|
||
Is a list of symbols denoting features supported in this
|
||
implementation. *FEATURES* can grow as modules are `require'd.
|
||
*FEATURES* must be defined by all implementations (*note
|
||
Porting::).
|
||
|
||
Here are features which SLIB (`require.scm') adds to *FEATURES*
|
||
when appropriate.
|
||
|
||
* 'inexact
|
||
|
||
* 'rational
|
||
|
||
* 'real
|
||
|
||
* 'complex
|
||
|
||
* 'bignum
|
||
|
||
For each item, `(provided? 'FEATURE)' will return `#t' if that
|
||
feature is available, and `#f' if not.
|
||
|
||
- Variable: *modules*
|
||
Is a list of pathnames denoting files which have been loaded.
|
||
|
||
- Variable: *catalog*
|
||
Is an association list of features (symbols) and pathnames which
|
||
will supply those features. The pathname can be either a string
|
||
or a pair. If pathname is a pair then the first element should be
|
||
a macro feature symbol, `source', or `compiled'. The cdr of the
|
||
pathname should be either a string or a list.
|
||
|
||
In the following functions if the argument FEATURE is not a symbol it
|
||
is assumed to be a pathname.
|
||
|
||
- Function: provided? feature
|
||
Returns `#t' if FEATURE is a member of `*features*' or `*modules*'
|
||
or if FEATURE is supported by a file already loaded and `#f'
|
||
otherwise.
|
||
|
||
- Procedure: require feature
|
||
FEATURE is a symbol. If `(provided? FEATURE)' is true `require'
|
||
returns. Otherwise, if `(assq FEATURE *catalog*)' is not `#f',
|
||
the associated files will be loaded and `(provided? FEATURE)' will
|
||
henceforth return `#t'. An unspecified value is returned. If
|
||
FEATURE is not found in `*catalog*', then an error is signaled.
|
||
|
||
- Procedure: require pathname
|
||
PATHNAME is a string. If PATHNAME has not already been given as
|
||
an argument to `require', PATHNAME is loaded. An unspecified
|
||
value is returned.
|
||
|
||
- Procedure: provide feature
|
||
Assures that FEATURE is contained in `*features*' if FEATURE is a
|
||
symbol and `*modules*' otherwise.
|
||
|
||
- Function: require:feature->path feature
|
||
Returns `#t' if FEATURE is a member of `*features*' or `*modules*'
|
||
or if FEATURE is supported by a file already loaded. Returns a
|
||
path if one was found in `*catalog*' under the feature name, and
|
||
`#f' otherwise. The path can either be a string suitable as an
|
||
argument to load or a pair as described above for *catalog*.
|
||
|
||
|
||
File: slib.info, Node: Vicinity, Next: Configuration, Prev: Require, Up: Built-in Support
|
||
|
||
Vicinity
|
||
--------
|
||
|
||
A vicinity is a descriptor for a place in the file system. Vicinities
|
||
hide from the programmer the concepts of host, volume, directory, and
|
||
version. Vicinities express only the concept of a file environment
|
||
where a file name can be resolved to a file in a system independent
|
||
manner. Vicinities can even be used on "flat" file systems (which have
|
||
no directory structure) by having the vicinity express constraints on
|
||
the file name. On most systems a vicinity would be a string. All of
|
||
these procedures are file system dependent.
|
||
|
||
These procedures are provided by all implementations.
|
||
|
||
- Function: make-vicinity path
|
||
Returns the vicinity of PATH for use by `in-vicinity'.
|
||
|
||
- Function: program-vicinity
|
||
Returns the vicinity of the currently loading Scheme code. For an
|
||
interpreter this would be the directory containing source code.
|
||
For a compiled system (with multiple files) this would be the
|
||
directory where the object or executable files are. If no file is
|
||
currently loading it the result is undefined. *Warning:*
|
||
`program-vicinity' can return incorrect values if your program
|
||
escapes back into a `load'.
|
||
|
||
- Function: library-vicinity
|
||
Returns the vicinity of the shared Scheme library.
|
||
|
||
- Function: implementation-vicinity
|
||
Returns the vicinity of the underlying Scheme implementation. This
|
||
vicinity will likely contain startup code and messages and a
|
||
compiler.
|
||
|
||
- Function: user-vicinity
|
||
Returns the vicinity of the current directory of the user. On most
|
||
systems this is `""' (the empty string).
|
||
|
||
- Function: home-vicinity
|
||
Returns the vicinity of the user's "HOME" directory, the directory
|
||
which typically contains files which customize a computer
|
||
environment for a user. If scheme is running without a user (eg.
|
||
a daemon) or if this concept is meaningless for the platform, then
|
||
`home-vicinity' returns `#f'.
|
||
|
||
- Function: in-vicinity vicinity filename
|
||
Returns a filename suitable for use by `slib:load',
|
||
`slib:load-source', `slib:load-compiled', `open-input-file',
|
||
`open-output-file', etc. The returned filename is FILENAME in
|
||
VICINITY. `in-vicinity' should allow FILENAME to override
|
||
VICINITY when FILENAME is an absolute pathname and VICINITY is
|
||
equal to the value of `(user-vicinity)'. The behavior of
|
||
`in-vicinity' when FILENAME is absolute and VICINITY is not equal
|
||
to the value of `(user-vicinity)' is unspecified. For most systems
|
||
`in-vicinity' can be `string-append'.
|
||
|
||
- Function: sub-vicinity vicinity name
|
||
Returns the vicinity of VICINITY restricted to NAME. This is used
|
||
for large systems where names of files in subsystems could
|
||
conflict. On systems with directory structure `sub-vicinity' will
|
||
return a pathname of the subdirectory NAME of VICINITY.
|
||
|
||
|
||
File: slib.info, Node: Configuration, Next: Input/Output, Prev: Vicinity, Up: Built-in Support
|
||
|
||
Configuration
|
||
-------------
|
||
|
||
These constants and procedures describe characteristics of the Scheme
|
||
and underlying operating system. They are provided by all
|
||
implementations.
|
||
|
||
- Constant: char-code-limit
|
||
An integer 1 larger that the largest value which can be returned by
|
||
`char->integer'.
|
||
|
||
- Constant: most-positive-fixnum
|
||
In implementations which support integers of practically unlimited
|
||
size, MOST-POSITIVE-FIXNUM is a large exact integer within the
|
||
range of exact integers that may result from computing the length
|
||
of a list, vector, or string.
|
||
|
||
In implementations which do not support integers of practically
|
||
unlimited size, MOST-POSITIVE-FIXNUM is the largest exact integer
|
||
that may result from computing the length of a list, vector, or
|
||
string.
|
||
|
||
- Constant: slib:tab
|
||
The tab character.
|
||
|
||
- Constant: slib:form-feed
|
||
The form-feed character.
|
||
|
||
- Function: software-type
|
||
Returns a symbol denoting the generic operating system type. For
|
||
instance, `unix', `vms', `macos', `amiga', or `ms-dos'.
|
||
|
||
- Function: slib:report-version
|
||
Displays the versions of SLIB and the underlying Scheme
|
||
implementation and the name of the operating system. An
|
||
unspecified value is returned.
|
||
|
||
(slib:report-version) => slib "2d1" on scm "5b1" on unix |
|
||
|
||
- Function: slib:report
|
||
Displays the information of `(slib:report-version)' followed by
|
||
almost all the information neccessary for submitting a problem
|
||
report. An unspecified value is returned.
|
||
|
||
- Function: slib:report #t
|
||
provides a more verbose listing.
|
||
|
||
- Function: slib:report filename
|
||
Writes the report to file `filename'.
|
||
|
||
(slib:report)
|
||
=>
|
||
slib "2d1" on scm "5b1" on unix |
|
||
(implementation-vicinity) is "/home/jaffer/scm/"
|
||
(library-vicinity) is "/home/jaffer/slib/"
|
||
(scheme-file-suffix) is ".scm"
|
||
loaded *features* :
|
||
trace alist qp sort
|
||
common-list-functions macro values getopt
|
||
compiled
|
||
implementation *features* :
|
||
bignum complex real rational
|
||
inexact vicinity ed getenv
|
||
tmpnam abort transcript with-file
|
||
ieee-p1178 rev4-report rev4-optional-procedures hash
|
||
object-hash delay eval dynamic-wind
|
||
multiarg-apply multiarg/and- logical defmacro
|
||
string-port source current-time record
|
||
rev3-procedures rev2-procedures sun-dl string-case
|
||
array dump char-ready? full-continuation
|
||
system
|
||
implementation *catalog* :
|
||
(i/o-extensions compiled "/home/jaffer/scm/ioext.so")
|
||
...
|
||
|
||
|
||
File: slib.info, Node: Input/Output, Next: Legacy, Prev: Configuration, Up: Built-in Support
|
||
|
||
Input/Output
|
||
------------
|
||
|
||
These procedures are provided by all implementations.
|
||
|
||
- Procedure: file-exists? filename
|
||
Returns `#t' if the specified file exists. Otherwise, returns
|
||
`#f'. If the underlying implementation does not support this
|
||
feature then `#f' is always returned.
|
||
|
||
- Procedure: delete-file filename
|
||
Deletes the file specified by FILENAME. If FILENAME can not be
|
||
deleted, `#f' is returned. Otherwise, `#t' is returned.
|
||
|
||
- Procedure: tmpnam
|
||
Returns a pathname for a file which will likely not be used by any
|
||
other process. Successive calls to `(tmpnam)' will return
|
||
different pathnames.
|
||
|
||
- Procedure: current-error-port
|
||
Returns the current port to which diagnostic and error output is
|
||
directed.
|
||
|
||
- Procedure: force-output
|
||
- Procedure: force-output port
|
||
Forces any pending output on PORT to be delivered to the output
|
||
device and returns an unspecified value. The PORT argument may be
|
||
omitted, in which case it defaults to the value returned by
|
||
`(current-output-port)'.
|
||
|
||
- Procedure: output-port-width
|
||
- Procedure: output-port-width port
|
||
Returns the width of PORT, which defaults to
|
||
`(current-output-port)' if absent. If the width cannot be
|
||
determined 79 is returned.
|
||
|
||
- Procedure: output-port-height
|
||
- Procedure: output-port-height port
|
||
Returns the height of PORT, which defaults to
|
||
`(current-output-port)' if absent. If the height cannot be
|
||
determined 24 is returned.
|
||
|
||
|
||
File: slib.info, Node: Legacy, Next: System, Prev: Input/Output, Up: Built-in Support
|
||
|
||
Legacy
|
||
------
|
||
|
||
These procedures are provided by all implementations.
|
||
|
||
- Function: identity x
|
||
IDENTITY returns its argument.
|
||
|
||
Example:
|
||
(identity 3)
|
||
=> 3
|
||
(identity '(foo bar))
|
||
=> (foo bar)
|
||
(map identity LST)
|
||
== (copy-list LST)
|
||
|
||
The following procedures were present in Scheme until R4RS (*note
|
||
Language changes: (r4rs)Notes.). They are provided by all SLIB
|
||
implementations.
|
||
|
||
- Constant: t
|
||
Derfined as `#t'.
|
||
|
||
- Constant: nil
|
||
Defined as `#f'.
|
||
|
||
- Function: last-pair l
|
||
Returns the last pair in the list L. Example:
|
||
(last-pair (cons 1 2))
|
||
=> (1 . 2)
|
||
(last-pair '(1 2))
|
||
=> (2)
|
||
== (cons 2 '())
|
||
|
||
|
||
File: slib.info, Node: System, Prev: Legacy, Up: Built-in Support
|
||
|
||
System
|
||
------
|
||
|
||
These procedures are provided by all implementations.
|
||
|
||
- Procedure: slib:load-source name
|
||
Loads a file of Scheme source code from NAME with the default
|
||
filename extension used in SLIB. For instance if the filename
|
||
extension used in SLIB is `.scm' then `(slib:load-source "foo")'
|
||
will load from file `foo.scm'.
|
||
|
||
- Procedure: slib:load-compiled name
|
||
On implementations which support separtely loadable compiled
|
||
modules, loads a file of compiled code from NAME with the
|
||
implementation's filename extension for compiled code appended.
|
||
|
||
- Procedure: slib:load name
|
||
Loads a file of Scheme source or compiled code from NAME with the
|
||
appropriate suffixes appended. If both source and compiled code
|
||
are present with the appropriate names then the implementation
|
||
will load just one. It is up to the implementation to choose
|
||
which one will be loaded.
|
||
|
||
If an implementation does not support compiled code then
|
||
`slib:load' will be identical to `slib:load-source'.
|
||
|
||
- Procedure: slib:eval obj
|
||
`eval' returns the value of OBJ evaluated in the current top level
|
||
environment. *Note Eval:: provides a more general evaluation
|
||
facility.
|
||
|
||
- Procedure: slib:eval-load filename eval
|
||
FILENAME should be a string. If filename names an existing file,
|
||
the Scheme source code expressions and definitions are read from
|
||
the file and EVAL called with them sequentially. The
|
||
`slib:eval-load' procedure does not affect the values returned by
|
||
`current-input-port' and `current-output-port'.
|
||
|
||
- Procedure: slib:warn arg1 arg2 ...
|
||
Outputs a warning message containing the arguments.
|
||
|
||
- Procedure: slib:error arg1 arg2 ...
|
||
Outputs an error message containing the arguments, aborts
|
||
evaluation of the current form and responds in a system dependent
|
||
way to the error. Typical responses are to abort the program or
|
||
to enter a read-eval-print loop.
|
||
|
||
- Procedure: slib:exit n
|
||
- Procedure: slib:exit
|
||
Exits from the Scheme session returning status N to the system.
|
||
If N is omitted or `#t', a success status is returned to the
|
||
system (if possible). If N is `#f' a failure is returned to the
|
||
system (if possible). If N is an integer, then N is returned to
|
||
the system (if possible). If the Scheme session cannot exit an
|
||
unspecified value is returned from `slib:exit'.
|
||
|
||
|
||
File: slib.info, Node: About this manual, Prev: Built-in Support, Up: The Library System
|
||
|
||
About this manual
|
||
=================
|
||
|
||
* Entries that are labeled as Functions are called for their return
|
||
values. Entries that are labeled as Procedures are called
|
||
primarily for their side effects.
|
||
|
||
* Examples in this text were produced using the `scm' Scheme
|
||
implementation.
|
||
|
||
* At the beginning of each section, there is a line that looks like
|
||
`(require 'feature)'. Include this line in your code prior to
|
||
using the package.
|
||
|
||
|
||
File: slib.info, Node: Scheme Syntax Extension Packages, Next: Textual Conversion Packages, Prev: The Library System, Up: Top
|
||
|
||
Scheme Syntax Extension Packages
|
||
********************************
|
||
|
||
* Menu:
|
||
|
||
* Defmacro:: Supported by all implementations
|
||
|
||
* R4RS Macros:: 'macro
|
||
* Macro by Example:: 'macro-by-example
|
||
* Macros That Work:: 'macros-that-work
|
||
* Syntactic Closures:: 'syntactic-closures
|
||
* Syntax-Case Macros:: 'syntax-case
|
||
|
||
Syntax extensions (macros) included with SLIB. Also *Note Structures::.
|
||
|
||
* Fluid-Let:: 'fluid-let
|
||
* Yasos:: 'yasos, 'oop, 'collect
|
||
|
||
|
||
File: slib.info, Node: Defmacro, Next: R4RS Macros, Prev: Scheme Syntax Extension Packages, Up: Scheme Syntax Extension Packages
|
||
|
||
Defmacro
|
||
========
|
||
|
||
Defmacros are supported by all implementations.
|
||
|
||
- Function: gentemp
|
||
Returns a new (interned) symbol each time it is called. The symbol
|
||
names are implementation-dependent
|
||
(gentemp) => scm:G0
|
||
(gentemp) => scm:G1
|
||
|
||
- Function: defmacro:eval e
|
||
Returns the `slib:eval' of expanding all defmacros in scheme
|
||
expression E.
|
||
|
||
- Function: defmacro:load filename
|
||
FILENAME should be a string. If filename names an existing file,
|
||
the `defmacro:load' procedure reads Scheme source code expressions
|
||
and definitions from the file and evaluates them sequentially.
|
||
These source code expressions and definitions may contain defmacro
|
||
definitions. The `macro:load' procedure does not affect the values
|
||
returned by `current-input-port' and `current-output-port'.
|
||
|
||
- Function: defmacro? sym
|
||
Returns `#t' if SYM has been defined by `defmacro', `#f' otherwise.
|
||
|
||
- Function: macroexpand-1 form
|
||
- Function: macroexpand form
|
||
If FORM is a macro call, `macroexpand-1' will expand the macro
|
||
call once and return it. A FORM is considered to be a macro call
|
||
only if it is a cons whose `car' is a symbol for which a
|
||
`defmacro' has been defined.
|
||
|
||
`macroexpand' is similar to `macroexpand-1', but repeatedly
|
||
expands FORM until it is no longer a macro call.
|
||
|
||
- Macro: defmacro name lambda-list form ...
|
||
When encountered by `defmacro:eval', `defmacro:macroexpand*', or
|
||
`defmacro:load' defines a new macro which will henceforth be
|
||
expanded when encountered by `defmacro:eval',
|
||
`defmacro:macroexpand*', or `defmacro:load'.
|
||
|
||
Defmacroexpand
|
||
--------------
|
||
|
||
`(require 'defmacroexpand)'
|
||
|
||
- Function: defmacro:expand* e
|
||
Returns the result of expanding all defmacros in scheme expression
|
||
E.
|
||
|
||
|
||
File: slib.info, Node: R4RS Macros, Next: Macro by Example, Prev: Defmacro, Up: Scheme Syntax Extension Packages
|
||
|
||
R4RS Macros
|
||
===========
|
||
|
||
`(require 'macro)' is the appropriate call if you want R4RS
|
||
high-level macros but don't care about the low level implementation. If
|
||
an SLIB R4RS macro implementation is already loaded it will be used.
|
||
Otherwise, one of the R4RS macros implemetations is loaded.
|
||
|
||
The SLIB R4RS macro implementations support the following uniform
|
||
interface:
|
||
|
||
- Function: macro:expand sexpression
|
||
Takes an R4RS expression, macro-expands it, and returns the result
|
||
of the macro expansion.
|
||
|
||
- Function: macro:eval sexpression
|
||
Takes an R4RS expression, macro-expands it, evals the result of the
|
||
macro expansion, and returns the result of the evaluation.
|
||
|
||
- Procedure: macro:load filename
|
||
FILENAME should be a string. If filename names an existing file,
|
||
the `macro:load' procedure reads Scheme source code expressions and
|
||
definitions from the file and evaluates them sequentially. These
|
||
source code expressions and definitions may contain macro
|
||
definitions. The `macro:load' procedure does not affect the
|
||
values returned by `current-input-port' and `current-output-port'.
|
||
|
||
|
||
File: slib.info, Node: Macro by Example, Next: Macros That Work, Prev: R4RS Macros, Up: Scheme Syntax Extension Packages
|
||
|
||
Macro by Example
|
||
================
|
||
|
||
`(require 'macro-by-example)'
|
||
|
||
A vanilla implementation of `Macro by Example' (Eugene Kohlbecker,
|
||
R4RS) by Dorai Sitaram, (dorai@cs.rice.edu) using `defmacro'.
|
||
|
||
* generating hygienic global `define-syntax' Macro-by-Example macros
|
||
*cheaply*.
|
||
|
||
* can define macros which use `...'.
|
||
|
||
* needn't worry about a lexical variable in a macro definition
|
||
clashing with a variable from the macro use context
|
||
|
||
* don't suffer the overhead of redefining the repl if `defmacro'
|
||
natively supported (most implementations)
|
||
|
||
|
||
Caveat
|
||
------
|
||
|
||
These macros are not referentially transparent (*note Macros:
|
||
(r4rs)Macros.). Lexically scoped macros (i.e., `let-syntax' and
|
||
`letrec-syntax') are not supported. In any case, the problem of
|
||
referential transparency gains poignancy only when `let-syntax' and
|
||
`letrec-syntax' are used. So you will not be courting large-scale
|
||
disaster unless you're using system-function names as local variables
|
||
with unintuitive bindings that the macro can't use. However, if you
|
||
must have the full `r4rs' macro functionality, look to the more
|
||
featureful (but also more expensive) versions of syntax-rules available
|
||
in slib *Note Macros That Work::, *Note Syntactic Closures::, and *Note
|
||
Syntax-Case Macros::.
|
||
|
||
- Macro: define-syntax keyword transformer-spec
|
||
The KEYWORD is an identifier, and the TRANSFORMER-SPEC should be
|
||
an instance of `syntax-rules'.
|
||
|
||
The top-level syntactic environment is extended by binding the
|
||
KEYWORD to the specified transformer.
|
||
|
||
(define-syntax let*
|
||
(syntax-rules ()
|
||
((let* () body1 body2 ...)
|
||
(let () body1 body2 ...))
|
||
((let* ((name1 val1) (name2 val2) ...)
|
||
body1 body2 ...)
|
||
(let ((name1 val1))
|
||
(let* (( name2 val2) ...)
|
||
body1 body2 ...)))))
|
||
|
||
- Macro: syntax-rules literals syntax-rule ...
|
||
LITERALS is a list of identifiers, and each SYNTAX-RULE should be
|
||
of the form
|
||
|
||
`(PATTERN TEMPLATE)'
|
||
|
||
where the PATTERN and TEMPLATE are as in the grammar above.
|
||
|
||
An instance of `syntax-rules' produces a new macro transformer by
|
||
specifying a sequence of hygienic rewrite rules. A use of a macro
|
||
whose keyword is associated with a transformer specified by
|
||
`syntax-rules' is matched against the patterns contained in the
|
||
SYNTAX-RULEs, beginning with the leftmost SYNTAX-RULE. When a
|
||
match is found, the macro use is trancribed hygienically according
|
||
to the template.
|
||
|
||
Each pattern begins with the keyword for the macro. This keyword
|
||
is not involved in the matching and is not considered a pattern
|
||
variable or literal identifier.
|
||
|
||
|
||
File: slib.info, Node: Macros That Work, Next: Syntactic Closures, Prev: Macro by Example, Up: Scheme Syntax Extension Packages
|
||
|
||
Macros That Work
|
||
================
|
||
|
||
`(require 'macros-that-work)'
|
||
|
||
`Macros That Work' differs from the other R4RS macro implementations
|
||
in that it does not expand derived expression types to primitive
|
||
expression types.
|
||
|
||
- Function: macro:expand expression
|
||
- Function: macwork:expand expression
|
||
Takes an R4RS expression, macro-expands it, and returns the result
|
||
of the macro expansion.
|
||
|
||
- Function: macro:eval expression
|
||
- Function: macwork:eval expression
|
||
`macro:eval' returns the value of EXPRESSION in the current top
|
||
level environment. EXPRESSION can contain macro definitions.
|
||
Side effects of EXPRESSION will affect the top level environment.
|
||
|
||
- Procedure: macro:load filename
|
||
- Procedure: macwork:load filename
|
||
FILENAME should be a string. If filename names an existing file,
|
||
the `macro:load' procedure reads Scheme source code expressions and
|
||
definitions from the file and evaluates them sequentially. These
|
||
source code expressions and definitions may contain macro
|
||
definitions. The `macro:load' procedure does not affect the
|
||
values returned by `current-input-port' and `current-output-port'.
|
||
|
||
References:
|
||
|
||
The `Revised^4 Report on the Algorithmic Language Scheme' Clinger and
|
||
Rees [editors]. To appear in LISP Pointers. Also available as a
|
||
technical report from the University of Oregon, MIT AI Lab, and Cornell.
|
||
|
||
Macros That Work. Clinger and Rees. POPL '91.
|
||
|
||
The supported syntax differs from the R4RS in that vectors are allowed
|
||
as patterns and as templates and are not allowed as pattern or template
|
||
data.
|
||
|
||
transformer spec ==> (syntax-rules literals rules)
|
||
|
||
rules ==> ()
|
||
| (rule . rules)
|
||
|
||
rule ==> (pattern template)
|
||
|
||
pattern ==> pattern_var ; a symbol not in literals
|
||
| symbol ; a symbol in literals
|
||
| ()
|
||
| (pattern . pattern)
|
||
| (ellipsis_pattern)
|
||
| #(pattern*) ; extends R4RS
|
||
| #(pattern* ellipsis_pattern) ; extends R4RS
|
||
| pattern_datum
|
||
|
||
template ==> pattern_var
|
||
| symbol
|
||
| ()
|
||
| (template2 . template2)
|
||
| #(template*) ; extends R4RS
|
||
| pattern_datum
|
||
|
||
template2 ==> template
|
||
| ellipsis_template
|
||
|
||
pattern_datum ==> string ; no vector
|
||
| character
|
||
| boolean
|
||
| number
|
||
|
||
ellipsis_pattern ==> pattern ...
|
||
|
||
ellipsis_template ==> template ...
|
||
|
||
pattern_var ==> symbol ; not in literals
|
||
|
||
literals ==> ()
|
||
| (symbol . literals)
|
||
|
||
Definitions
|
||
-----------
|
||
|
||
Scope of an ellipsis
|
||
Within a pattern or template, the scope of an ellipsis (`...') is
|
||
the pattern or template that appears to its left.
|
||
|
||
Rank of a pattern variable
|
||
The rank of a pattern variable is the number of ellipses within
|
||
whose scope it appears in the pattern.
|
||
|
||
Rank of a subtemplate
|
||
The rank of a subtemplate is the number of ellipses within whose
|
||
scope it appears in the template.
|
||
|
||
Template rank of an occurrence of a pattern variable
|
||
The template rank of an occurrence of a pattern variable within a
|
||
template is the rank of that occurrence, viewed as a subtemplate.
|
||
|
||
Variables bound by a pattern
|
||
The variables bound by a pattern are the pattern variables that
|
||
appear within it.
|
||
|
||
Referenced variables of a subtemplate
|
||
The referenced variables of a subtemplate are the pattern
|
||
variables that appear within it.
|
||
|
||
Variables opened by an ellipsis template
|
||
The variables opened by an ellipsis template are the referenced
|
||
pattern variables whose rank is greater than the rank of the
|
||
ellipsis template.
|
||
|
||
Restrictions
|
||
------------
|
||
|
||
No pattern variable appears more than once within a pattern.
|
||
|
||
For every occurrence of a pattern variable within a template, the
|
||
template rank of the occurrence must be greater than or equal to the
|
||
pattern variable's rank.
|
||
|
||
Every ellipsis template must open at least one variable.
|
||
|
||
For every ellipsis template, the variables opened by an ellipsis
|
||
template must all be bound to sequences of the same length.
|
||
|
||
The compiled form of a RULE is
|
||
|
||
rule ==> (pattern template inserted)
|
||
|
||
pattern ==> pattern_var
|
||
| symbol
|
||
| ()
|
||
| (pattern . pattern)
|
||
| ellipsis_pattern
|
||
| #(pattern)
|
||
| pattern_datum
|
||
|
||
template ==> pattern_var
|
||
| symbol
|
||
| ()
|
||
| (template2 . template2)
|
||
| #(pattern)
|
||
| pattern_datum
|
||
|
||
template2 ==> template
|
||
| ellipsis_template
|
||
|
||
pattern_datum ==> string
|
||
| character
|
||
| boolean
|
||
| number
|
||
|
||
pattern_var ==> #(V symbol rank)
|
||
|
||
ellipsis_pattern ==> #(E pattern pattern_vars)
|
||
|
||
ellipsis_template ==> #(E template pattern_vars)
|
||
|
||
inserted ==> ()
|
||
| (symbol . inserted)
|
||
|
||
pattern_vars ==> ()
|
||
| (pattern_var . pattern_vars)
|
||
|
||
rank ==> exact non-negative integer
|
||
|
||
where V and E are unforgeable values.
|
||
|
||
The pattern variables associated with an ellipsis pattern are the
|
||
variables bound by the pattern, and the pattern variables associated
|
||
with an ellipsis template are the variables opened by the ellipsis
|
||
template.
|
||
|
||
If the template contains a big chunk that contains no pattern
|
||
variables or inserted identifiers, then the big chunk will be copied
|
||
unnecessarily. That shouldn't matter very often.
|
||
|
||
|
||
File: slib.info, Node: Syntactic Closures, Next: Syntax-Case Macros, Prev: Macros That Work, Up: Scheme Syntax Extension Packages
|
||
|
||
Syntactic Closures
|
||
==================
|
||
|
||
`(require 'syntactic-closures)'
|
||
|
||
- Function: macro:expand expression
|
||
- Function: synclo:expand expression
|
||
Returns scheme code with the macros and derived expression types of
|
||
EXPRESSION expanded to primitive expression types.
|
||
|
||
- Function: macro:eval expression
|
||
- Function: synclo:eval expression
|
||
`macro:eval' returns the value of EXPRESSION in the current top
|
||
level environment. EXPRESSION can contain macro definitions.
|
||
Side effects of EXPRESSION will affect the top level environment.
|
||
|
||
- Procedure: macro:load filename
|
||
- Procedure: synclo:load filename
|
||
FILENAME should be a string. If filename names an existing file,
|
||
the `macro:load' procedure reads Scheme source code expressions and
|
||
definitions from the file and evaluates them sequentially. These
|
||
source code expressions and definitions may contain macro
|
||
definitions. The `macro:load' procedure does not affect the
|
||
values returned by `current-input-port' and `current-output-port'.
|
||
|
||
Syntactic Closure Macro Facility
|
||
--------------------------------
|
||
|
||
A Syntactic Closures Macro Facility
|
||
|
||
by Chris Hanson
|
||
|
||
9 November 1991
|
||
|
||
This document describes "syntactic closures", a low-level macro
|
||
facility for the Scheme programming language. The facility is an
|
||
alternative to the low-level macro facility described in the `Revised^4
|
||
Report on Scheme.' This document is an addendum to that report.
|
||
|
||
The syntactic closures facility extends the BNF rule for TRANSFORMER
|
||
SPEC to allow a new keyword that introduces a low-level macro
|
||
transformer:
|
||
TRANSFORMER SPEC := (transformer EXPRESSION)
|
||
|
||
Additionally, the following procedures are added:
|
||
make-syntactic-closure
|
||
capture-syntactic-environment
|
||
identifier?
|
||
identifier=?
|
||
|
||
The description of the facility is divided into three parts. The
|
||
first part defines basic terminology. The second part describes how
|
||
macro transformers are defined. The third part describes the use of
|
||
"identifiers", which extend the syntactic closure mechanism to be
|
||
compatible with `syntax-rules'.
|
||
|
||
Terminology
|
||
...........
|
||
|
||
This section defines the concepts and data types used by the syntactic
|
||
closures facility.
|
||
|
||
* "Forms" are the syntactic entities out of which programs are
|
||
recursively constructed. A form is any expression, any
|
||
definition, any syntactic keyword, or any syntactic closure. The
|
||
variable name that appears in a `set!' special form is also a
|
||
form. Examples of forms:
|
||
17
|
||
#t
|
||
car
|
||
(+ x 4)
|
||
(lambda (x) x)
|
||
(define pi 3.14159)
|
||
if
|
||
define
|
||
|
||
* An "alias" is an alternate name for a given symbol. It can appear
|
||
anywhere in a form that the symbol could be used, and when quoted
|
||
it is replaced by the symbol; however, it does not satisfy the
|
||
predicate `symbol?'. Macro transformers rarely distinguish
|
||
symbols from aliases, referring to both as identifiers.
|
||
|
||
* A "syntactic" environment maps identifiers to their meanings.
|
||
More precisely, it determines whether an identifier is a syntactic
|
||
keyword or a variable. If it is a keyword, the meaning is an
|
||
interpretation for the form in which that keyword appears. If it
|
||
is a variable, the meaning identifies which binding of that
|
||
variable is referenced. In short, syntactic environments contain
|
||
all of the contextual information necessary for interpreting the
|
||
meaning of a particular form.
|
||
|
||
* A "syntactic closure" consists of a form, a syntactic environment,
|
||
and a list of identifiers. All identifiers in the form take their
|
||
meaning from the syntactic environment, except those in the given
|
||
list. The identifiers in the list are to have their meanings
|
||
determined later. A syntactic closure may be used in any context
|
||
in which its form could have been used. Since a syntactic closure
|
||
is also a form, it may not be used in contexts where a form would
|
||
be illegal. For example, a form may not appear as a clause in the
|
||
cond special form. A syntactic closure appearing in a quoted
|
||
structure is replaced by its form.
|
||
|
||
|
||
Transformer Definition
|
||
......................
|
||
|
||
This section describes the `transformer' special form and the
|
||
procedures `make-syntactic-closure' and `capture-syntactic-environment'.
|
||
|
||
- Syntax: transformer expression
|
||
Syntax: It is an error if this syntax occurs except as a
|
||
TRANSFORMER SPEC.
|
||
|
||
Semantics: The EXPRESSION is evaluated in the standard transformer
|
||
environment to yield a macro transformer as described below. This
|
||
macro transformer is bound to a macro keyword by the special form
|
||
in which the `transformer' expression appears (for example,
|
||
`let-syntax').
|
||
|
||
A "macro transformer" is a procedure that takes two arguments, a
|
||
form and a syntactic environment, and returns a new form. The
|
||
first argument, the "input form", is the form in which the macro
|
||
keyword occurred. The second argument, the "usage environment",
|
||
is the syntactic environment in which the input form occurred.
|
||
The result of the transformer, the "output form", is automatically
|
||
closed in the "transformer environment", which is the syntactic
|
||
environment in which the `transformer' expression occurred.
|
||
|
||
For example, here is a definition of a push macro using
|
||
`syntax-rules':
|
||
(define-syntax push
|
||
(syntax-rules ()
|
||
((push item list)
|
||
(set! list (cons item list)))))
|
||
|
||
Here is an equivalent definition using `transformer':
|
||
(define-syntax push
|
||
(transformer
|
||
(lambda (exp env)
|
||
(let ((item
|
||
(make-syntactic-closure env '() (cadr exp)))
|
||
(list
|
||
(make-syntactic-closure env '() (caddr exp))))
|
||
`(set! ,list (cons ,item ,list))))))
|
||
|
||
In this example, the identifiers `set!' and `cons' are closed in
|
||
the transformer environment, and thus will not be affected by the
|
||
meanings of those identifiers in the usage environment `env'.
|
||
|
||
Some macros may be non-hygienic by design. For example, the
|
||
following defines a loop macro that implicitly binds `exit' to an
|
||
escape procedure. The binding of `exit' is intended to capture
|
||
free references to `exit' in the body of the loop, so `exit' must
|
||
be left free when the body is closed:
|
||
(define-syntax loop
|
||
(transformer
|
||
(lambda (exp env)
|
||
(let ((body (cdr exp)))
|
||
`(call-with-current-continuation
|
||
(lambda (exit)
|
||
(let f ()
|
||
,@(map (lambda (exp)
|
||
(make-syntactic-closure env '(exit)
|
||
exp))
|
||
body)
|
||
(f))))))))
|
||
|
||
To assign meanings to the identifiers in a form, use
|
||
`make-syntactic-closure' to close the form in a syntactic
|
||
environment.
|
||
|
||
- Function: make-syntactic-closure environment free-names form
|
||
ENVIRONMENT must be a syntactic environment, FREE-NAMES must be a
|
||
list of identifiers, and FORM must be a form.
|
||
`make-syntactic-closure' constructs and returns a syntactic closure
|
||
of FORM in ENVIRONMENT, which can be used anywhere that FORM could
|
||
have been used. All the identifiers used in FORM, except those
|
||
explicitly excepted by FREE-NAMES, obtain their meanings from
|
||
ENVIRONMENT.
|
||
|
||
Here is an example where FREE-NAMES is something other than the
|
||
empty list. It is instructive to compare the use of FREE-NAMES in
|
||
this example with its use in the `loop' example above: the examples
|
||
are similar except for the source of the identifier being left
|
||
free.
|
||
(define-syntax let1
|
||
(transformer
|
||
(lambda (exp env)
|
||
(let ((id (cadr exp))
|
||
(init (caddr exp))
|
||
(exp (cadddr exp)))
|
||
`((lambda (,id)
|
||
,(make-syntactic-closure env (list id) exp))
|
||
,(make-syntactic-closure env '() init))))))
|
||
|
||
`let1' is a simplified version of `let' that only binds a single
|
||
identifier, and whose body consists of a single expression. When
|
||
the body expression is syntactically closed in its original
|
||
syntactic environment, the identifier that is to be bound by
|
||
`let1' must be left free, so that it can be properly captured by
|
||
the `lambda' in the output form.
|
||
|
||
To obtain a syntactic environment other than the usage
|
||
environment, use `capture-syntactic-environment'.
|
||
|
||
- Function: capture-syntactic-environment procedure
|
||
`capture-syntactic-environment' returns a form that will, when
|
||
transformed, call PROCEDURE on the current syntactic environment.
|
||
PROCEDURE should compute and return a new form to be transformed,
|
||
in that same syntactic environment, in place of the form.
|
||
|
||
An example will make this clear. Suppose we wanted to define a
|
||
simple `loop-until' keyword equivalent to
|
||
(define-syntax loop-until
|
||
(syntax-rules ()
|
||
((loop-until id init test return step)
|
||
(letrec ((loop
|
||
(lambda (id)
|
||
(if test return (loop step)))))
|
||
(loop init)))))
|
||
|
||
The following attempt at defining `loop-until' has a subtle bug:
|
||
(define-syntax loop-until
|
||
(transformer
|
||
(lambda (exp env)
|
||
(let ((id (cadr exp))
|
||
(init (caddr exp))
|
||
(test (cadddr exp))
|
||
(return (cadddr (cdr exp)))
|
||
(step (cadddr (cddr exp)))
|
||
(close
|
||
(lambda (exp free)
|
||
(make-syntactic-closure env free exp))))
|
||
`(letrec ((loop
|
||
(lambda (,id)
|
||
(if ,(close test (list id))
|
||
,(close return (list id))
|
||
(loop ,(close step (list id)))))))
|
||
(loop ,(close init '())))))))
|
||
|
||
This definition appears to take all of the proper precautions to
|
||
prevent unintended captures. It carefully closes the
|
||
subexpressions in their original syntactic environment and it
|
||
leaves the `id' identifier free in the `test', `return', and
|
||
`step' expressions, so that it will be captured by the binding
|
||
introduced by the `lambda' expression. Unfortunately it uses the
|
||
identifiers `if' and `loop' within that `lambda' expression, so if
|
||
the user of `loop-until' just happens to use, say, `if' for the
|
||
identifier, it will be inadvertently captured.
|
||
|
||
The syntactic environment that `if' and `loop' want to be exposed
|
||
to is the one just outside the `lambda' expression: before the
|
||
user's identifier is added to the syntactic environment, but after
|
||
the identifier loop has been added.
|
||
`capture-syntactic-environment' captures exactly that environment
|
||
as follows:
|
||
(define-syntax loop-until
|
||
(transformer
|
||
(lambda (exp env)
|
||
(let ((id (cadr exp))
|
||
(init (caddr exp))
|
||
(test (cadddr exp))
|
||
(return (cadddr (cdr exp)))
|
||
(step (cadddr (cddr exp)))
|
||
(close
|
||
(lambda (exp free)
|
||
(make-syntactic-closure env free exp))))
|
||
`(letrec ((loop
|
||
,(capture-syntactic-environment
|
||
(lambda (env)
|
||
`(lambda (,id)
|
||
(,(make-syntactic-closure env '() `if)
|
||
,(close test (list id))
|
||
,(close return (list id))
|
||
(,(make-syntactic-closure env '()
|
||
`loop)
|
||
,(close step (list id)))))))))
|
||
(loop ,(close init '())))))))
|
||
|
||
In this case, having captured the desired syntactic environment,
|
||
it is convenient to construct syntactic closures of the
|
||
identifiers `if' and the `loop' and use them in the body of the
|
||
`lambda'.
|
||
|
||
A common use of `capture-syntactic-environment' is to get the
|
||
transformer environment of a macro transformer:
|
||
(transformer
|
||
(lambda (exp env)
|
||
(capture-syntactic-environment
|
||
(lambda (transformer-env)
|
||
...))))
|
||
|
||
Identifiers
|
||
...........
|
||
|
||
This section describes the procedures that create and manipulate
|
||
identifiers. Previous syntactic closure proposals did not have an
|
||
identifier data type - they just used symbols. The identifier data
|
||
type extends the syntactic closures facility to be compatible with the
|
||
high-level `syntax-rules' facility.
|
||
|
||
As discussed earlier, an identifier is either a symbol or an "alias".
|
||
An alias is implemented as a syntactic closure whose "form" is an
|
||
identifier:
|
||
(make-syntactic-closure env '() 'a)
|
||
=> an "alias"
|
||
|
||
Aliases are implemented as syntactic closures because they behave just
|
||
like syntactic closures most of the time. The difference is that an
|
||
alias may be bound to a new value (for example by `lambda' or
|
||
`let-syntax'); other syntactic closures may not be used this way. If
|
||
an alias is bound, then within the scope of that binding it is looked
|
||
up in the syntactic environment just like any other identifier.
|
||
|
||
Aliases are used in the implementation of the high-level facility
|
||
`syntax-rules'. A macro transformer created by `syntax-rules' uses a
|
||
template to generate its output form, substituting subforms of the
|
||
input form into the template. In a syntactic closures implementation,
|
||
all of the symbols in the template are replaced by aliases closed in
|
||
the transformer environment, while the output form itself is closed in
|
||
the usage environment. This guarantees that the macro transformation
|
||
is hygienic, without requiring the transformer to know the syntactic
|
||
roles of the substituted input subforms.
|
||
|
||
- Function: identifier? object
|
||
Returns `#t' if OBJECT is an identifier, otherwise returns `#f'.
|
||
Examples:
|
||
(identifier? 'a)
|
||
=> #t
|
||
(identifier? (make-syntactic-closure env '() 'a))
|
||
=> #t
|
||
(identifier? "a")
|
||
=> #f
|
||
(identifier? #\a)
|
||
=> #f
|
||
(identifier? 97)
|
||
=> #f
|
||
(identifier? #f)
|
||
=> #f
|
||
(identifier? '(a))
|
||
=> #f
|
||
(identifier? '#(a))
|
||
=> #f
|
||
|
||
The predicate `eq?' is used to determine if two identifers are
|
||
"the same". Thus `eq?' can be used to compare identifiers exactly
|
||
as it would be used to compare symbols. Often, though, it is
|
||
useful to know whether two identifiers "mean the same thing". For
|
||
example, the `cond' macro uses the symbol `else' to identify the
|
||
final clause in the conditional. A macro transformer for `cond'
|
||
cannot just look for the symbol `else', because the `cond' form
|
||
might be the output of another macro transformer that replaced the
|
||
symbol `else' with an alias. Instead the transformer must look
|
||
for an identifier that "means the same thing" in the usage
|
||
environment as the symbol `else' means in the transformer
|
||
environment.
|
||
|
||
- Function: identifier=? environment1 identifier1 environment2
|
||
identifier2
|
||
ENVIRONMENT1 and ENVIRONMENT2 must be syntactic environments, and
|
||
IDENTIFIER1 and IDENTIFIER2 must be identifiers. `identifier=?'
|
||
returns `#t' if the meaning of IDENTIFIER1 in ENVIRONMENT1 is the
|
||
same as that of IDENTIFIER2 in ENVIRONMENT2, otherwise it returns
|
||
`#f'. Examples:
|
||
|
||
(let-syntax
|
||
((foo
|
||
(transformer
|
||
(lambda (form env)
|
||
(capture-syntactic-environment
|
||
(lambda (transformer-env)
|
||
(identifier=? transformer-env 'x env 'x)))))))
|
||
(list (foo)
|
||
(let ((x 3))
|
||
(foo))))
|
||
=> (#t #f)
|
||
|
||
(let-syntax ((bar foo))
|
||
(let-syntax
|
||
((foo
|
||
(transformer
|
||
(lambda (form env)
|
||
(capture-syntactic-environment
|
||
(lambda (transformer-env)
|
||
(identifier=? transformer-env 'foo
|
||
env (cadr form))))))))
|
||
(list (foo foo)
|
||
(foobar))))
|
||
=> (#f #t)
|
||
|
||
Acknowledgements
|
||
................
|
||
|
||
The syntactic closures facility was invented by Alan Bawden and
|
||
Jonathan Rees. The use of aliases to implement `syntax-rules' was
|
||
invented by Alan Bawden (who prefers to call them "synthetic names").
|
||
Much of this proposal is derived from an earlier proposal by Alan
|
||
Bawden.
|
||
|
||
|
||
File: slib.info, Node: Syntax-Case Macros, Next: Fluid-Let, Prev: Syntactic Closures, Up: Scheme Syntax Extension Packages
|
||
|
||
Syntax-Case Macros
|
||
==================
|
||
|
||
`(require 'syntax-case)'
|
||
|
||
- Function: macro:expand expression
|
||
- Function: syncase:expand expression
|
||
Returns scheme code with the macros and derived expression types of
|
||
EXPRESSION expanded to primitive expression types.
|
||
|
||
- Function: macro:eval expression
|
||
- Function: syncase:eval expression
|
||
`macro:eval' returns the value of EXPRESSION in the current top
|
||
level environment. EXPRESSION can contain macro definitions.
|
||
Side effects of EXPRESSION will affect the top level environment.
|
||
|
||
- Procedure: macro:load filename
|
||
- Procedure: syncase:load filename
|
||
FILENAME should be a string. If filename names an existing file,
|
||
the `macro:load' procedure reads Scheme source code expressions and
|
||
definitions from the file and evaluates them sequentially. These
|
||
source code expressions and definitions may contain macro
|
||
definitions. The `macro:load' procedure does not affect the
|
||
values returned by `current-input-port' and `current-output-port'.
|
||
|
||
This is version 2.1 of `syntax-case', the low-level macro facility
|
||
proposed and implemented by Robert Hieb and R. Kent Dybvig.
|
||
|
||
This version is further adapted by Harald Hanche-Olsen
|
||
<hanche@imf.unit.no> to make it compatible with, and easily usable
|
||
with, SLIB. Mainly, these adaptations consisted of:
|
||
|
||
* Removing white space from `expand.pp' to save space in the
|
||
distribution. This file is not meant for human readers anyway...
|
||
|
||
* Removed a couple of Chez scheme dependencies.
|
||
|
||
* Renamed global variables used to minimize the possibility of name
|
||
conflicts.
|
||
|
||
* Adding an SLIB-specific initialization file.
|
||
|
||
* Removing a couple extra files, most notably the documentation (but
|
||
see below).
|
||
|
||
If you wish, you can see exactly what changes were done by reading the
|
||
shell script in the file `syncase.sh'.
|
||
|
||
The two PostScript files were omitted in order to not burden the SLIB
|
||
distribution with them. If you do intend to use `syntax-case',
|
||
however, you should get these files and print them out on a PostScript
|
||
printer. They are available with the original `syntax-case'
|
||
distribution by anonymous FTP in
|
||
`cs.indiana.edu:/pub/scheme/syntax-case'.
|
||
|
||
In order to use syntax-case from an interactive top level, execute:
|
||
(require 'syntax-case)
|
||
(require 'repl)
|
||
(repl:top-level macro:eval)
|
||
See the section Repl (*note Repl::) for more information.
|
||
|
||
To check operation of syntax-case get
|
||
`cs.indiana.edu:/pub/scheme/syntax-case', and type
|
||
(require 'syntax-case)
|
||
(syncase:sanity-check)
|
||
|
||
Beware that `syntax-case' takes a long time to load - about 20s on a
|
||
SPARCstation SLC (with SCM) and about 90s on a Macintosh SE/30 (with
|
||
Gambit).
|
||
|
||
Notes
|
||
-----
|
||
|
||
All R4RS syntactic forms are defined, including `delay'. Along with
|
||
`delay' are simple definitions for `make-promise' (into which `delay'
|
||
expressions expand) and `force'.
|
||
|
||
`syntax-rules' and `with-syntax' (described in `TR356') are defined.
|
||
|
||
`syntax-case' is actually defined as a macro that expands into calls
|
||
to the procedure `syntax-dispatch' and the core form `syntax-lambda';
|
||
do not redefine these names.
|
||
|
||
Several other top-level bindings not documented in TR356 are created:
|
||
* the "hooks" in `hooks.ss'
|
||
|
||
* the `build-' procedures in `output.ss'
|
||
|
||
* `expand-syntax' (the expander)
|
||
|
||
The syntax of define has been extended to allow `(define ID)', which
|
||
assigns ID to some unspecified value.
|
||
|
||
We have attempted to maintain R4RS compatibility where possible. The
|
||
incompatibilities should be confined to `hooks.ss'. Please let us know
|
||
if there is some incompatibility that is not flagged as such.
|
||
|
||
Send bug reports, comments, suggestions, and questions to Kent Dybvig
|
||
(dyb@iuvax.cs.indiana.edu).
|
||
|
||
Note from maintainer
|
||
--------------------
|
||
|
||
Included with the `syntax-case' files was `structure.scm' which
|
||
defines a macro `define-structure'. There is no documentation for this
|
||
macro and it is not used by any code in SLIB.
|
||
|
||
|
||
File: slib.info, Node: Fluid-Let, Next: Yasos, Prev: Syntax-Case Macros, Up: Scheme Syntax Extension Packages
|
||
|
||
Fluid-Let
|
||
=========
|
||
|
||
`(require 'fluid-let)'
|
||
|
||
- Syntax: fluid-let `(BINDINGS ...)' FORMS...
|
||
|
||
(fluid-let ((VARIABLE INIT) ...)
|
||
EXPRESSION EXPRESSION ...)
|
||
|
||
The INITs are evaluated in the current environment (in some
|
||
unspecified order), the current values of the VARIABLEs are saved, the
|
||
results are assigned to the VARIABLEs, the EXPRESSIONs are evaluated
|
||
sequentially in the current environment, the VARIABLEs are restored to
|
||
their original values, and the value of the last EXPRESSION is returned.
|
||
|
||
The syntax of this special form is similar to that of `let', but
|
||
`fluid-let' temporarily rebinds existing VARIABLEs. Unlike `let',
|
||
`fluid-let' creates no new bindings; instead it _assigns_ the values of
|
||
each INIT to the binding (determined by the rules of lexical scoping)
|
||
of its corresponding VARIABLE.
|
||
|
||
|
||
File: slib.info, Node: Yasos, Prev: Fluid-Let, Up: Scheme Syntax Extension Packages
|
||
|
||
Yasos
|
||
=====
|
||
|
||
`(require 'oop)' or `(require 'yasos)'
|
||
|
||
`Yet Another Scheme Object System' is a simple object system for
|
||
Scheme based on the paper by Norman Adams and Jonathan Rees: `Object
|
||
Oriented Programming in Scheme', Proceedings of the 1988 ACM Conference
|
||
on LISP and Functional Programming, July 1988 [ACM #552880].
|
||
|
||
Another reference is:
|
||
|
||
Ken Dickey. Scheming with Objects `AI Expert' Volume 7, Number 10
|
||
(October 1992), pp. 24-33.
|
||
|
||
* Menu:
|
||
|
||
* Yasos terms:: Definitions and disclaimer.
|
||
* Yasos interface:: The Yasos macros and procedures.
|
||
* Setters:: Dylan-like setters in Yasos.
|
||
* Yasos examples:: Usage of Yasos and setters.
|
||
|
||
|
||
File: slib.info, Node: Yasos terms, Next: Yasos interface, Prev: Yasos, Up: Yasos
|
||
|
||
Terms
|
||
-----
|
||
|
||
"Object"
|
||
Any Scheme data object.
|
||
|
||
"Instance"
|
||
An instance of the OO system; an "object".
|
||
|
||
"Operation"
|
||
A METHOD.
|
||
|
||
_Notes:_
|
||
The object system supports multiple inheritance. An instance can
|
||
inherit from 0 or more ancestors. In the case of multiple
|
||
inherited operations with the same identity, the operation used is
|
||
that from the first ancestor which contains it (in the ancestor
|
||
`let'). An operation may be applied to any Scheme data
|
||
object--not just instances. As code which creates instances is
|
||
just code, there are no "classes" and no meta-ANYTHING. Method
|
||
dispatch is by a procedure call a la CLOS rather than by `send'
|
||
syntax a la Smalltalk.
|
||
|
||
_Disclaimer:_
|
||
There are a number of optimizations which can be made. This
|
||
implementation is expository (although performance should be quite
|
||
reasonable). See the L&FP paper for some suggestions.
|
||
|
||
|
||
File: slib.info, Node: Yasos interface, Next: Setters, Prev: Yasos terms, Up: Yasos
|
||
|
||
Interface
|
||
---------
|
||
|
||
- Syntax: define-operation `('opname self arg ...`)' DEFAULT-BODY
|
||
Defines a default behavior for data objects which don't handle the
|
||
operation OPNAME. The default behavior (for an empty
|
||
DEFAULT-BODY) is to generate an error.
|
||
|
||
- Syntax: define-predicate opname?
|
||
Defines a predicate OPNAME?, usually used for determining the
|
||
"type" of an object, such that `(OPNAME? OBJECT)' returns `#t' if
|
||
OBJECT has an operation OPNAME? and `#f' otherwise.
|
||
|
||
- Syntax: object `((NAME SELF ARG ...) BODY)' ...
|
||
Returns an object (an instance of the object system) with
|
||
operations. Invoking `(NAME OBJECT ARG ...' executes the BODY of
|
||
the OBJECT with SELF bound to OBJECT and with argument(s) ARG....
|
||
|
||
- Syntax: object-with-ancestors `(('ancestor1 init1`)' ...`)'
|
||
operation ...
|
||
A `let'-like form of `object' for multiple inheritance. It
|
||
returns an object inheriting the behaviour of ANCESTOR1 etc. An
|
||
operation will be invoked in an ancestor if the object itself does
|
||
not provide such a method. In the case of multiple inherited
|
||
operations with the same identity, the operation used is the one
|
||
found in the first ancestor in the ancestor list.
|
||
|
||
- Syntax: operate-as component operation self arg ...
|
||
Used in an operation definition (of SELF) to invoke the OPERATION
|
||
in an ancestor COMPONENT but maintain the object's identity. Also
|
||
known as "send-to-super".
|
||
|
||
- Procedure: print obj port
|
||
A default `print' operation is provided which is just `(format
|
||
PORT OBJ)' (*note Format::) for non-instances and prints OBJ
|
||
preceded by `#<INSTANCE>' for instances.
|
||
|
||
- Function: size obj
|
||
The default method returns the number of elements in OBJ if it is
|
||
a vector, string or list, `2' for a pair, `1' for a character and
|
||
by default id an error otherwise. Objects such as collections
|
||
(*note Collections::) may override the default in an obvious way.
|
||
|
||
|
||
File: slib.info, Node: Setters, Next: Yasos examples, Prev: Yasos interface, Up: Yasos
|
||
|
||
Setters
|
||
-------
|
||
|
||
"Setters" implement "generalized locations" for objects associated
|
||
with some sort of mutable state. A "getter" operation retrieves a
|
||
value from a generalized location and the corresponding setter
|
||
operation stores a value into the location. Only the getter is named -
|
||
the setter is specified by a procedure call as below. (Dylan uses
|
||
special syntax.) Typically, but not necessarily, getters are access
|
||
operations to extract values from Yasos objects (*note Yasos::).
|
||
Several setters are predefined, corresponding to getters `car', `cdr',
|
||
`string-ref' and `vector-ref' e.g., `(setter car)' is equivalent to
|
||
`set-car!'.
|
||
|
||
This implementation of setters is similar to that in Dylan(TM)
|
||
(`Dylan: An object-oriented dynamic language', Apple Computer Eastern
|
||
Research and Technology). Common LISP provides similar facilities
|
||
through `setf'.
|
||
|
||
- Function: setter getter
|
||
Returns the setter for the procedure GETTER. E.g., since
|
||
`string-ref' is the getter corresponding to a setter which is
|
||
actually `string-set!':
|
||
(define foo "foo")
|
||
((setter string-ref) foo 0 #\F) ; set element 0 of foo
|
||
foo => "Foo"
|
||
|
||
- Syntax: set place new-value
|
||
If PLACE is a variable name, `set' is equivalent to `set!'.
|
||
Otherwise, PLACE must have the form of a procedure call, where the
|
||
procedure name refers to a getter and the call indicates an
|
||
accessible generalized location, i.e., the call would return a
|
||
value. The return value of `set' is usually unspecified unless
|
||
used with a setter whose definition guarantees to return a useful
|
||
value.
|
||
(set (string-ref foo 2) #\O) ; generalized location with getter
|
||
foo => "FoO"
|
||
(set foo "foo") ; like set!
|
||
foo => "foo"
|
||
|
||
- Procedure: add-setter getter setter
|
||
Add procedures GETTER and SETTER to the (inaccessible) list of
|
||
valid setter/getter pairs. SETTER implements the store operation
|
||
corresponding to the GETTER access operation for the relevant
|
||
state. The return value is unspecified.
|
||
|
||
- Procedure: remove-setter-for getter
|
||
Removes the setter corresponding to the specified GETTER from the
|
||
list of valid setters. The return value is unspecified.
|
||
|
||
- Syntax: define-access-operation getter-name
|
||
Shorthand for a Yasos `define-operation' defining an operation
|
||
GETTER-NAME that objects may support to return the value of some
|
||
mutable state. The default operation is to signal an error. The
|
||
return value is unspecified.
|
||
|
||
|
||
File: slib.info, Node: Yasos examples, Prev: Setters, Up: Yasos
|
||
|
||
Examples
|
||
--------
|
||
|
||
;;; These definitions for PRINT and SIZE are
|
||
;;; already supplied by
|
||
(require 'yasos)
|
||
|
||
(define-operation (print obj port)
|
||
(format port
|
||
(if (instance? obj) "#<instance>" "~s")
|
||
obj))
|
||
|
||
(define-operation (size obj)
|
||
(cond
|
||
((vector? obj) (vector-length obj))
|
||
((list? obj) (length obj))
|
||
((pair? obj) 2)
|
||
((string? obj) (string-length obj))
|
||
((char? obj) 1)
|
||
(else
|
||
(error "Operation not supported: size" obj))))
|
||
|
||
(define-predicate cell?)
|
||
(define-operation (fetch obj))
|
||
(define-operation (store! obj newValue))
|
||
|
||
(define (make-cell value)
|
||
(object
|
||
((cell? self) #t)
|
||
((fetch self) value)
|
||
((store! self newValue)
|
||
(set! value newValue)
|
||
newValue)
|
||
((size self) 1)
|
||
((print self port)
|
||
(format port "#<Cell: ~s>" (fetch self)))))
|
||
|
||
(define-operation (discard obj value)
|
||
(format #t "Discarding ~s~%" value))
|
||
|
||
(define (make-filtered-cell value filter)
|
||
(object-with-ancestors
|
||
((cell (make-cell value)))
|
||
((store! self newValue)
|
||
(if (filter newValue)
|
||
(store! cell newValue)
|
||
(discard self newValue)))))
|
||
|
||
(define-predicate array?)
|
||
(define-operation (array-ref array index))
|
||
(define-operation (array-set! array index value))
|
||
|
||
(define (make-array num-slots)
|
||
(let ((anArray (make-vector num-slots)))
|
||
(object
|
||
((array? self) #t)
|
||
((size self) num-slots)
|
||
((array-ref self index)
|
||
(vector-ref anArray index))
|
||
((array-set! self index newValue)
|
||
(vector-set! anArray index newValue))
|
||
((print self port)
|
||
(format port "#<Array ~s>" (size self))))))
|
||
|
||
(define-operation (position obj))
|
||
(define-operation (discarded-value obj))
|
||
|
||
(define (make-cell-with-history value filter size)
|
||
(let ((pos 0) (most-recent-discard #f))
|
||
(object-with-ancestors
|
||
((cell (make-filtered-call value filter))
|
||
(sequence (make-array size)))
|
||
((array? self) #f)
|
||
((position self) pos)
|
||
((store! self newValue)
|
||
(operate-as cell store! self newValue)
|
||
(array-set! self pos newValue)
|
||
(set! pos (+ pos 1)))
|
||
((discard self value)
|
||
(set! most-recent-discard value))
|
||
((discarded-value self) most-recent-discard)
|
||
((print self port)
|
||
(format port "#<Cell-with-history ~s>"
|
||
(fetch self))))))
|
||
|
||
(define-access-operation fetch)
|
||
(add-setter fetch store!)
|
||
(define foo (make-cell 1))
|
||
(print foo #f)
|
||
=> "#<Cell: 1>"
|
||
(set (fetch foo) 2)
|
||
=>
|
||
(print foo #f)
|
||
=> "#<Cell: 2>"
|
||
(fetch foo)
|
||
=> 2
|
||
|
||
|
||
File: slib.info, Node: Textual Conversion Packages, Next: Mathematical Packages, Prev: Scheme Syntax Extension Packages, Up: Top
|
||
|
||
Textual Conversion Packages
|
||
***************************
|
||
|
||
* Menu:
|
||
|
||
* Precedence Parsing::
|
||
* Format:: Common-Lisp Format
|
||
* Standard Formatted I/O:: Posix printf and scanf
|
||
* Programs and Arguments::
|
||
* HTML::
|
||
* HTML Tables:: Databases meet HTML
|
||
* HTTP and CGI:: Serve WWW sites
|
||
* URI:: Uniform Resource Identifier |
|
||
* Printing Scheme:: Nicely
|
||
* Time and Date::
|
||
* Vector Graphics::
|
||
* Schmooz:: Documentation markup for Scheme programs
|
||
|
||
|
||
File: slib.info, Node: Precedence Parsing, Next: Format, Prev: Textual Conversion Packages, Up: Textual Conversion Packages
|
||
|
||
Precedence Parsing
|
||
==================
|
||
|
||
`(require 'precedence-parse)' or `(require 'parse)'
|
||
|
||
This package implements:
|
||
|
||
* a Pratt style precedence parser;
|
||
|
||
* a "tokenizer" which congeals tokens according to assigned classes
|
||
of constituent characters;
|
||
|
||
* procedures giving direct control of parser rulesets;
|
||
|
||
* procedures for higher level specification of rulesets.
|
||
|
||
* Menu:
|
||
|
||
* Precedence Parsing Overview::
|
||
* Ruleset Definition and Use::
|
||
* Token definition::
|
||
* Nud and Led Definition::
|
||
* Grammar Rule Definition::
|
||
|
||
|
||
File: slib.info, Node: Precedence Parsing Overview, Next: Ruleset Definition and Use, Prev: Precedence Parsing, Up: Precedence Parsing
|
||
|
||
Precedence Parsing Overview
|
||
---------------------------
|
||
|
||
This package offers improvements over previous parsers.
|
||
|
||
* Common computer language constructs are concisely specified.
|
||
|
||
* Grammars can be changed dynamically. Operators can be assigned
|
||
different meanings within a lexical context.
|
||
|
||
* Rulesets don't need compilation. Grammars can be changed
|
||
incrementally.
|
||
|
||
* Operator precedence is specified by integers.
|
||
|
||
* All possibilities of bad input are handled (1) and return as much
|
||
structure as was parsed when the error occured; The symbol `?' is
|
||
substituted for missing input.
|
||
|
||
Here are the higher-level syntax types and an example of each.
|
||
Precedence considerations are omitted for clarity. See *Note Grammar
|
||
Rule Definition:: for full details.
|
||
|
||
- Grammar: nofix bye exit
|
||
bye
|
||
calls the function `exit' with no arguments.
|
||
|
||
- Grammar: prefix - negate
|
||
- 42
|
||
Calls the function `negate' with the argument `42'.
|
||
|
||
- Grammar: infix - difference
|
||
x - y
|
||
Calls the function `difference' with arguments `x' and `y'.
|
||
|
||
- Grammar: nary + sum
|
||
x + y + z
|
||
Calls the function `sum' with arguments `x', `y', and `y'.
|
||
|
||
- Grammar: postfix ! factorial
|
||
5 !
|
||
Calls the function `factorial' with the argument `5'.
|
||
|
||
- Grammar: prestfix set set!
|
||
set foo bar
|
||
Calls the function `set!' with the arguments `foo' and `bar'.
|
||
|
||
- Grammar: commentfix /* */
|
||
/* almost any text here */
|
||
Ignores the comment delimited by `/*' and `*/'.
|
||
|
||
- Grammar: matchfix { list }
|
||
{0, 1, 2}
|
||
Calls the function `list' with the arguments `0', `1', and `2'.
|
||
|
||
- Grammar: inmatchfix ( funcall )
|
||
f(x, y)
|
||
Calls the function `funcall' with the arguments `f', `x', and `y'.
|
||
|
||
- Grammar: delim ;
|
||
set foo bar;
|
||
delimits the extent of the restfix operator `set'.
|
||
|
||
---------- Footnotes ----------
|
||
|
||
(1) How do I know this? I parsed 250kbyte of random input (an e-mail
|
||
file) with a non-trivial grammar utilizing all constructs.
|
||
|
||
|
||
File: slib.info, Node: Ruleset Definition and Use, Next: Token definition, Prev: Precedence Parsing Overview, Up: Precedence Parsing
|
||
|
||
Ruleset Definition and Use
|
||
--------------------------
|
||
|
||
- Variable: *syn-defs*
|
||
A grammar is built by one or more calls to `prec:define-grammar'.
|
||
The rules are appended to *SYN-DEFS*. The value of *SYN-DEFS* is
|
||
the grammar suitable for passing as an argument to `prec:parse'.
|
||
|
||
- Constant: *syn-ignore-whitespace*
|
||
Is a nearly empty grammar with whitespace characters set to group
|
||
0, which means they will not be made into tokens. Most rulesets
|
||
will want to start with `*syn-ignore-whitespace*'
|
||
|
||
In order to start defining a grammar, either
|
||
|
||
(set! *syn-defs* '())
|
||
|
||
or
|
||
|
||
(set! *syn-defs* *syn-ignore-whitespace*)
|
||
|
||
- Function: prec:define-grammar rule1 ...
|
||
Appends RULE1 ... to *SYN-DEFS*. `prec:define-grammar' is used to
|
||
define both the character classes and rules for tokens.
|
||
|
||
Once your grammar is defined, save the value of `*syn-defs*' in a
|
||
variable (for use when calling `prec:parse').
|
||
|
||
(define my-ruleset *syn-defs*)
|
||
|
||
- Function: prec:parse ruleset delim
|
||
- Function: prec:parse ruleset delim port
|
||
The RULESET argument must be a list of rules as constructed by
|
||
`prec:define-grammar' and extracted from *SYN-DEFS*.
|
||
|
||
The token DELIM may be a character, symbol, or string. A
|
||
character DELIM argument will match only a character token; i.e. a
|
||
character for which no token-group is assigned. A symbols or
|
||
string will match only a token string; i.e. a token resulting from
|
||
a token group.
|
||
|
||
`prec:parse' reads a RULESET grammar expression delimited by DELIM
|
||
from the given input PORT. `prec:parse' returns the next object
|
||
parsable from the given input PORT, updating PORT to point to the
|
||
first character past the end of the external representation of the
|
||
object.
|
||
|
||
If an end of file is encountered in the input before any
|
||
characters are found that can begin an object, then an end of file
|
||
object is returned. If a delimiter (such as DELIM) is found
|
||
before any characters are found that can begin an object, then
|
||
`#f' is returned.
|
||
|
||
The PORT argument may be omitted, in which case it defaults to the
|
||
value returned by `current-input-port'. It is an error to parse
|
||
from a closed port.
|
||
|
||
|
||
File: slib.info, Node: Token definition, Next: Nud and Led Definition, Prev: Ruleset Definition and Use, Up: Precedence Parsing
|
||
|
||
Token definition
|
||
----------------
|
||
|
||
- Function: tok:char-group group chars chars-proc
|
||
The argument CHARS may be a single character, a list of
|
||
characters, or a string. Each character in CHARS is treated as
|
||
though `tok:char-group' was called with that character alone.
|
||
|
||
The argument CHARS-PROC must be a procedure of one argument, a
|
||
list of characters. After `tokenize' has finished accumulating
|
||
the characters for a token, it calls CHARS-PROC with the list of
|
||
characters. The value returned is the token which `tokenize'
|
||
returns.
|
||
|
||
The argument GROUP may be an exact integer or a procedure of one
|
||
character argument. The following discussion concerns the
|
||
treatment which the tokenizing routine, `tokenize', will accord to
|
||
characters on the basis of their groups.
|
||
|
||
When GROUP is a non-zero integer, characters whose group number is
|
||
equal to or exactly one less than GROUP will continue to
|
||
accumulate. Any other character causes the accumulation to stop
|
||
(until a new token is to be read).
|
||
|
||
The GROUP of zero is special. These characters are ignored when
|
||
parsed pending a token, and stop the accumulation of token
|
||
characters when the accumulation has already begun. Whitespace
|
||
characters are usually put in group 0.
|
||
|
||
If GROUP is a procedure, then, when triggerd by the occurence of
|
||
an initial (no accumulation) CHARS character, this procedure will
|
||
be repeatedly called with each successive character from the input
|
||
stream until the GROUP procedure returns a non-false value.
|
||
|
||
The following convenient constants are provided for use with
|
||
`tok:char-group'.
|
||
|
||
- Constant: tok:decimal-digits
|
||
Is the string `"0123456789"'.
|
||
|
||
- Constant: tok:upper-case
|
||
Is the string consisting of all upper-case letters
|
||
("ABCDEFGHIJKLMNOPQRSTUVWXYZ").
|
||
|
||
- Constant: tok:lower-case
|
||
Is the string consisting of all lower-case letters
|
||
("abcdefghijklmnopqrstuvwxyz").
|
||
|
||
- Constant: tok:whitespaces
|
||
Is the string consisting of all characters between 0 and 255 for
|
||
which `char-whitespace?' returns true.
|
||
|
||
|
||
File: slib.info, Node: Nud and Led Definition, Next: Grammar Rule Definition, Prev: Token definition, Up: Precedence Parsing
|
||
|
||
Nud and Led Definition
|
||
----------------------
|
||
|
||
This section describes advanced features. You can skip this section
|
||
on first reading.
|
||
|
||
The "Null Denotation" (or "nud") of a token is the procedure and
|
||
arguments applying for that token when "Left", an unclaimed parsed
|
||
expression is not extant.
|
||
|
||
The "Left Denotation" (or "led") of a token is the procedure,
|
||
arguments, and lbp applying for that token when there is a "Left", an
|
||
unclaimed parsed expression.
|
||
|
||
In his paper,
|
||
|
||
Pratt, V. R. Top Down Operator Precendence. `SIGACT/SIGPLAN
|
||
Symposium on Principles of Programming Languages', Boston, 1973,
|
||
pages 41-51
|
||
|
||
the "left binding power" (or "lbp") was an independent property of
|
||
tokens. I think this was done in order to allow tokens with NUDs but
|
||
not LEDs to also be used as delimiters, which was a problem for
|
||
statically defined syntaxes. It turns out that _dynamically binding_
|
||
NUDs and LEDs allows them independence.
|
||
|
||
For the rule-defining procedures that follow, the variable TK may be a
|
||
character, string, or symbol, or a list composed of characters,
|
||
strings, and symbols. Each element of TK is treated as though the
|
||
procedure were called for each element.
|
||
|
||
Character TK arguments will match only character tokens; i.e.
|
||
characters for which no token-group is assigned. Symbols and strings
|
||
will both match token strings; i.e. tokens resulting from token groups.
|
||
|
||
- Function: prec:make-nud tk sop arg1 ...
|
||
Returns a rule specifying that SOP be called when TK is parsed.
|
||
If SOP is a procedure, it is called with TK and ARG1 ... as its
|
||
arguments; the resulting value is incorporated into the expression
|
||
being built. Otherwise, `(list SOP ARG1 ...)' is incorporated.
|
||
|
||
If no NUD has been defined for a token; then if that token is a string,
|
||
it is converted to a symbol and returned; if not a string, the token is
|
||
returned.
|
||
|
||
- Function: prec:make-led tk sop arg1 ...
|
||
Returns a rule specifying that SOP be called when TK is parsed and
|
||
LEFT has an unclaimed parsed expression. If SOP is a procedure,
|
||
it is called with LEFT, TK, and ARG1 ... as its arguments; the
|
||
resulting value is incorporated into the expression being built.
|
||
Otherwise, LEFT is incorporated.
|
||
|
||
If no LED has been defined for a token, and LEFT is set, the parser
|
||
issues a warning.
|
||
|
||
|
||
File: slib.info, Node: Grammar Rule Definition, Prev: Nud and Led Definition, Up: Precedence Parsing
|
||
|
||
Grammar Rule Definition
|
||
-----------------------
|
||
|
||
Here are procedures for defining rules for the syntax types introduced
|
||
in *Note Precedence Parsing Overview::.
|
||
|
||
For the rule-defining procedures that follow, the variable TK may be a
|
||
character, string, or symbol, or a list composed of characters,
|
||
strings, and symbols. Each element of TK is treated as though the
|
||
procedure were called for each element.
|
||
|
||
For procedures prec:delim, ..., prec:prestfix, if the SOP argument is
|
||
`#f', then the token which triggered this rule is converted to a symbol
|
||
and returned. A false SOP argument to the procedures prec:commentfix,
|
||
prec:matchfix, or prec:inmatchfix has a different meaning.
|
||
|
||
Character TK arguments will match only character tokens; i.e.
|
||
characters for which no token-group is assigned. Symbols and strings
|
||
will both match token strings; i.e. tokens resulting from token groups.
|
||
|
||
- Function: prec:delim tk
|
||
Returns a rule specifying that TK should not be returned from
|
||
parsing; i.e. TK's function is purely syntactic. The end-of-file
|
||
is always treated as a delimiter.
|
||
|
||
- Function: prec:nofix tk sop
|
||
Returns a rule specifying the following actions take place when TK
|
||
is parsed:
|
||
* If SOP is a procedure, it is called with no arguments; the
|
||
resulting value is incorporated into the expression being
|
||
built. Otherwise, the list of SOP is incorporated.
|
||
|
||
- Function: prec:prefix tk sop bp rule1 ...
|
||
Returns a rule specifying the following actions take place when TK
|
||
is parsed:
|
||
* The rules RULE1 ... augment and, in case of conflict, override
|
||
rules currently in effect.
|
||
|
||
* `prec:parse1' is called with binding-power BP.
|
||
|
||
* If SOP is a procedure, it is called with the expression
|
||
returned from `prec:parse1'; the resulting value is
|
||
incorporated into the expression being built. Otherwise, the
|
||
list of SOP and the expression returned from `prec:parse1' is
|
||
incorporated.
|
||
|
||
* The ruleset in effect before TK was parsed is restored; RULE1
|
||
... are forgotten.
|
||
|
||
- Function: prec:infix tk sop lbp bp rule1 ...
|
||
Returns a rule declaring the left-binding-precedence of the token
|
||
TK is LBP and specifying the following actions take place when TK
|
||
is parsed:
|
||
* The rules RULE1 ... augment and, in case of conflict, override
|
||
rules currently in effect.
|
||
|
||
* One expression is parsed with binding-power LBP. If instead a
|
||
delimiter is encountered, a warning is issued.
|
||
|
||
* If SOP is a procedure, it is applied to the list of LEFT and
|
||
the parsed expression; the resulting value is incorporated
|
||
into the expression being built. Otherwise, the list of SOP,
|
||
the LEFT expression, and the parsed expression is
|
||
incorporated.
|
||
|
||
* The ruleset in effect before TK was parsed is restored; RULE1
|
||
... are forgotten.
|
||
|
||
- Function: prec:nary tk sop bp
|
||
Returns a rule declaring the left-binding-precedence of the token
|
||
TK is BP and specifying the following actions take place when TK
|
||
is parsed:
|
||
* Expressions are parsed with binding-power BP as far as they
|
||
are interleaved with the token TK.
|
||
|
||
* If SOP is a procedure, it is applied to the list of LEFT and
|
||
the parsed expressions; the resulting value is incorporated
|
||
into the expression being built. Otherwise, the list of SOP,
|
||
the LEFT expression, and the parsed expressions is
|
||
incorporated.
|
||
|
||
- Function: prec:postfix tk sop lbp
|
||
Returns a rule declaring the left-binding-precedence of the token
|
||
TK is LBP and specifying the following actions take place when TK
|
||
is parsed:
|
||
* If SOP is a procedure, it is called with the LEFT expression;
|
||
the resulting value is incorporated into the expression being
|
||
built. Otherwise, the list of SOP and the LEFT expression is
|
||
incorporated.
|
||
|
||
- Function: prec:prestfix tk sop bp rule1 ...
|
||
Returns a rule specifying the following actions take place when TK
|
||
is parsed:
|
||
* The rules RULE1 ... augment and, in case of conflict, override
|
||
rules currently in effect.
|
||
|
||
* Expressions are parsed with binding-power BP until a
|
||
delimiter is reached.
|
||
|
||
* If SOP is a procedure, it is applied to the list of parsed
|
||
expressions; the resulting value is incorporated into the
|
||
expression being built. Otherwise, the list of SOP and the
|
||
parsed expressions is incorporated.
|
||
|
||
* The ruleset in effect before TK was parsed is restored; RULE1
|
||
... are forgotten.
|
||
|
||
- Function: prec:commentfix tk stp match rule1 ...
|
||
Returns rules specifying the following actions take place when TK
|
||
is parsed:
|
||
* The rules RULE1 ... augment and, in case of conflict, override
|
||
rules currently in effect.
|
||
|
||
* Characters are read until and end-of-file or a sequence of
|
||
characters is read which matches the _string_ MATCH.
|
||
|
||
* If STP is a procedure, it is called with the string of all
|
||
that was read between the TK and MATCH (exclusive).
|
||
|
||
* The ruleset in effect before TK was parsed is restored; RULE1
|
||
... are forgotten.
|
||
|
||
Parsing of commentfix syntax differs from the others in several
|
||
ways. It reads directly from input without tokenizing; It calls
|
||
STP but does not return its value; nay any value. I added the STP
|
||
argument so that comment text could be echoed.
|
||
|
||
- Function: prec:matchfix tk sop sep match rule1 ...
|
||
Returns a rule specifying the following actions take place when TK
|
||
is parsed:
|
||
* The rules RULE1 ... augment and, in case of conflict, override
|
||
rules currently in effect.
|
||
|
||
* A rule declaring the token MATCH a delimiter takes effect.
|
||
|
||
* Expressions are parsed with binding-power `0' until the token
|
||
MATCH is reached. If the token SEP does not appear between
|
||
each pair of expressions parsed, a warning is issued.
|
||
|
||
* If SOP is a procedure, it is applied to the list of parsed
|
||
expressions; the resulting value is incorporated into the
|
||
expression being built. Otherwise, the list of SOP and the
|
||
parsed expressions is incorporated.
|
||
|
||
* The ruleset in effect before TK was parsed is restored; RULE1
|
||
... are forgotten.
|
||
|
||
- Function: prec:inmatchfix tk sop sep match lbp rule1 ...
|
||
Returns a rule declaring the left-binding-precedence of the token
|
||
TK is LBP and specifying the following actions take place when TK
|
||
is parsed:
|
||
* The rules RULE1 ... augment and, in case of conflict, override
|
||
rules currently in effect.
|
||
|
||
* A rule declaring the token MATCH a delimiter takes effect.
|
||
|
||
* Expressions are parsed with binding-power `0' until the token
|
||
MATCH is reached. If the token SEP does not appear between
|
||
each pair of expressions parsed, a warning is issued.
|
||
|
||
* If SOP is a procedure, it is applied to the list of LEFT and
|
||
the parsed expressions; the resulting value is incorporated
|
||
into the expression being built. Otherwise, the list of SOP,
|
||
the LEFT expression, and the parsed expressions is
|
||
incorporated.
|
||
|
||
* The ruleset in effect before TK was parsed is restored; RULE1
|
||
... are forgotten.
|
||
|
||
|
||
File: slib.info, Node: Format, Next: Standard Formatted I/O, Prev: Precedence Parsing, Up: Textual Conversion Packages
|
||
|
||
Format (version 3.0)
|
||
====================
|
||
|
||
`(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 "old fashioned" 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.
|
||
|
||
`~'<newline>
|
||
Continuation Line.
|
||
`~:'<newline>
|
||
newline is ignored, white space left.
|
||
|
||
`~@'<newline>
|
||
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: Standard Formatted I/O, Next: Programs and Arguments, Prev: Format, Up: Textual Conversion Packages
|
||
|
||
Standard Formatted I/O
|
||
======================
|
||
|
||
* Menu:
|
||
|
||
* Standard Formatted Output:: 'printf
|
||
* Standard Formatted Input:: 'scanf
|
||
|
||
stdio
|
||
-----
|
||
|
||
`(require 'stdio)'
|
||
|
||
`require's `printf' and `scanf' and additionally defines the symbols:
|
||
|
||
- Variable: stdin
|
||
Defined to be `(current-input-port)'.
|
||
|
||
- Variable: stdout
|
||
Defined to be `(current-output-port)'.
|
||
|
||
- Variable: stderr
|
||
Defined to be `(current-error-port)'.
|
||
|
||
|
||
File: slib.info, Node: Standard Formatted Output, Next: Standard Formatted Input, Prev: Standard Formatted I/O, Up: Standard Formatted I/O
|
||
|
||
Standard Formatted Output
|
||
-------------------------
|
||
|
||
`(require 'printf)'
|
||
|
||
- Procedure: printf format arg1 ...
|
||
- Procedure: fprintf port format arg1 ...
|
||
- Procedure: sprintf str format arg1 ...
|
||
- Procedure: sprintf #f format arg1 ...
|
||
- Procedure: sprintf k format arg1 ...
|
||
Each function converts, formats, and outputs its ARG1 ...
|
||
arguments according to the control string FORMAT argument and
|
||
returns the number of characters output.
|
||
|
||
`printf' sends its output to the port `(current-output-port)'.
|
||
`fprintf' sends its output to the port PORT. `sprintf'
|
||
`string-set!'s locations of the non-constant string argument STR
|
||
to the output characters.
|
||
|
||
Two extensions of `sprintf' return new strings. If the first
|
||
argument is `#f', then the returned string's length is as many
|
||
characters as specified by the FORMAT and data; if the first
|
||
argument is a non-negative integer K, then the length of the
|
||
returned string is also bounded by K.
|
||
|
||
The string FORMAT contains plain characters which are copied to
|
||
the output stream, and conversion specifications, each of which
|
||
results in fetching zero or more of the arguments ARG1 .... The
|
||
results are undefined if there are an insufficient number of
|
||
arguments for the format. If FORMAT is exhausted while some of the
|
||
ARG1 ... arguments remain unused, the excess ARG1 ... arguments
|
||
are ignored.
|
||
|
||
The conversion specifications in a format string have the form:
|
||
|
||
% [ FLAGS ] [ WIDTH ] [ . PRECISION ] [ TYPE ] CONVERSION
|
||
|
||
An output conversion specifications consist of an initial `%'
|
||
character followed in sequence by:
|
||
|
||
* Zero or more "flag characters" that modify the normal
|
||
behavior of the conversion specification.
|
||
|
||
`-'
|
||
Left-justify the result in the field. Normally the
|
||
result is right-justified.
|
||
|
||
`+'
|
||
For the signed `%d' and `%i' conversions and all inexact
|
||
conversions, prefix a plus sign if the value is positive.
|
||
|
||
` '
|
||
For the signed `%d' and `%i' conversions, if the result
|
||
doesn't start with a plus or minus sign, prefix it with
|
||
a space character instead. Since the `+' flag ensures
|
||
that the result includes a sign, this flag is ignored if
|
||
both are specified.
|
||
|
||
`#'
|
||
For inexact conversions, `#' specifies that the result
|
||
should always include a decimal point, even if no digits
|
||
follow it. For the `%g' and `%G' conversions, this also
|
||
forces trailing zeros after the decimal point to be
|
||
printed where they would otherwise be elided.
|
||
|
||
For the `%o' conversion, force the leading digit to be
|
||
`0', as if by increasing the precision. For `%x' or
|
||
`%X', prefix a leading `0x' or `0X' (respectively) to
|
||
the result. This doesn't do anything useful for the
|
||
`%d', `%i', or `%u' conversions. Using this flag
|
||
produces output which can be parsed by the `scanf'
|
||
functions with the `%i' conversion (*note Standard
|
||
Formatted Input::).
|
||
|
||
`0'
|
||
Pad the field with zeros instead of spaces. The zeros
|
||
are placed after any indication of sign or base. This
|
||
flag is ignored if the `-' flag is also specified, or if
|
||
a precision is specified for an exact converson.
|
||
|
||
* An optional decimal integer specifying the "minimum field
|
||
width". If the normal conversion produces fewer characters
|
||
than this, the field is padded (with spaces or zeros per the
|
||
`0' flag) to the specified width. This is a _minimum_ width;
|
||
if the normal conversion produces more characters than this,
|
||
the field is _not_ truncated.
|
||
|
||
Alternatively, if the field width is `*', the next argument
|
||
in the argument list (before the actual value to be printed)
|
||
is used as the field width. The width value must be an
|
||
integer. If the value is negative it is as though the `-'
|
||
flag is set (see above) and the absolute value is used as the
|
||
field width.
|
||
|
||
* An optional "precision" to specify the number of digits to be
|
||
written for numeric conversions and the maximum field width
|
||
for string conversions. The precision is specified by a
|
||
period (`.') followed optionally by a decimal integer (which
|
||
defaults to zero if omitted).
|
||
|
||
Alternatively, if the precision is `.*', the next argument in
|
||
the argument list (before the actual value to be printed) is
|
||
used as the precision. The value must be an integer, and is
|
||
ignored if negative. If you specify `*' for both the field
|
||
width and precision, the field width argument precedes the
|
||
precision argument. The `.*' precision is an enhancement. C
|
||
library versions may not accept this syntax.
|
||
|
||
For the `%f', `%e', and `%E' conversions, the precision
|
||
specifies how many digits follow the decimal-point character.
|
||
The default precision is `6'. If the precision is
|
||
explicitly `0', the decimal point character is suppressed.
|
||
|
||
For the `%g' and `%G' conversions, the precision specifies how
|
||
many significant digits to print. Significant digits are the
|
||
first digit before the decimal point, and all the digits
|
||
after it. If the precision is `0' or not specified for `%g'
|
||
or `%G', it is treated like a value of `1'. If the value
|
||
being printed cannot be expressed accurately in the specified
|
||
number of digits, the value is rounded to the nearest number
|
||
that fits.
|
||
|
||
For exact conversions, if a precision is supplied it
|
||
specifies the minimum number of digits to appear; leading
|
||
zeros are produced if necessary. If a precision is not
|
||
supplied, the number is printed with as many digits as
|
||
necessary. Converting an exact `0' with an explicit
|
||
precision of zero produces no characters.
|
||
|
||
* An optional one of `l', `h' or `L', which is ignored for
|
||
numeric conversions. It is an error to specify these
|
||
modifiers for non-numeric conversions.
|
||
|
||
* A character that specifies the conversion to be applied.
|
||
|
||
Exact Conversions
|
||
.................
|
||
|
||
`d', `i'
|
||
Print an integer as a signed decimal number. `%d' and `%i'
|
||
are synonymous for output, but are different when used with
|
||
`scanf' for input (*note Standard Formatted Input::).
|
||
|
||
`o'
|
||
Print an integer as an unsigned octal number.
|
||
|
||
`u'
|
||
Print an integer as an unsigned decimal number.
|
||
|
||
`x', `X'
|
||
Print an integer as an unsigned hexadecimal number. `%x'
|
||
prints using the digits `0123456789abcdef'. `%X' prints
|
||
using the digits `0123456789ABCDEF'.
|
||
|
||
Inexact Conversions
|
||
...................
|
||
|
||
`f'
|
||
Print a floating-point number in fixed-point notation.
|
||
|
||
`e', `E'
|
||
Print a floating-point number in exponential notation. `%e'
|
||
prints `e' between mantissa and exponont. `%E' prints `E'
|
||
between mantissa and exponont.
|
||
|
||
`g', `G'
|
||
Print a floating-point number in either fixed or exponential
|
||
notation, whichever is more appropriate for its magnitude.
|
||
Unless an `#' flag has been supplied, trailing zeros after a
|
||
decimal point will be stripped off. `%g' prints `e' between
|
||
mantissa and exponont. `%G' prints `E' between mantissa and
|
||
exponent.
|
||
|
||
`k', `K'
|
||
Print a number like `%g', except that an SI prefix is output
|
||
after the number, which is scaled accordingly. `%K' outputs
|
||
a space between number and prefix, `%k' does not.
|
||
|
||
Other Conversions
|
||
.................
|
||
|
||
`c'
|
||
Print a single character. The `-' flag is the only one which
|
||
can be specified. It is an error to specify a precision.
|
||
|
||
`s'
|
||
Print a string. The `-' flag is the only one which can be
|
||
specified. A precision specifies the maximum number of
|
||
characters to output; otherwise all characters in the string
|
||
are output.
|
||
|
||
`a', `A'
|
||
Print a scheme expression. The `-' flag left-justifies the
|
||
output. The `#' flag specifies that strings and characters
|
||
should be quoted as by `write' (which can be read using
|
||
`read'); otherwise, output is as `display' prints. A
|
||
precision specifies the maximum number of characters to
|
||
output; otherwise as many characters as needed are output.
|
||
|
||
_Note:_ `%a' and `%A' are SLIB extensions.
|
||
|
||
`%'
|
||
Print a literal `%' character. No argument is consumed. It
|
||
is an error to specifiy flags, field width, precision, or
|
||
type modifiers with `%%'.
|
||
|
||
|
||
File: slib.info, Node: Standard Formatted Input, Prev: Standard Formatted Output, Up: Standard Formatted I/O
|
||
|
||
Standard Formatted Input
|
||
------------------------
|
||
|
||
`(require 'scanf)'
|
||
|
||
- Function: scanf-read-list format
|
||
- Function: scanf-read-list format port
|
||
- Function: scanf-read-list format string
|
||
|
||
- Macro: scanf format arg1 ...
|
||
- Macro: fscanf port format arg1 ...
|
||
- Macro: sscanf str format arg1 ...
|
||
Each function reads characters, interpreting them according to the
|
||
control string FORMAT argument.
|
||
|
||
`scanf-read-list' returns a list of the items specified as far as
|
||
the input matches FORMAT. `scanf', `fscanf', and `sscanf' return
|
||
the number of items successfully matched and stored. `scanf',
|
||
`fscanf', and `sscanf' also set the location corresponding to ARG1
|
||
... using the methods:
|
||
|
||
symbol
|
||
`set!'
|
||
|
||
car expression
|
||
`set-car!'
|
||
|
||
cdr expression
|
||
`set-cdr!'
|
||
|
||
vector-ref expression
|
||
`vector-set!'
|
||
|
||
substring expression
|
||
`substring-move-left!'
|
||
|
||
The argument to a `substring' expression in ARG1 ... must be a
|
||
non-constant string. Characters will be stored starting at the
|
||
position specified by the second argument to `substring'. The
|
||
number of characters stored will be limited by either the position
|
||
specified by the third argument to `substring' or the length of the
|
||
matched string, whichever is less.
|
||
|
||
The control string, FORMAT, contains conversion specifications and
|
||
other characters used to direct interpretation of input sequences.
|
||
The control string contains:
|
||
|
||
* White-space characters (blanks, tabs, newlines, or formfeeds)
|
||
that cause input to be read (and discarded) up to the next
|
||
non-white-space character.
|
||
|
||
* An ordinary character (not `%') that must match the next
|
||
character of the input stream.
|
||
|
||
* Conversion specifications, consisting of the character `%', an
|
||
optional assignment suppressing character `*', an optional
|
||
numerical maximum-field width, an optional `l', `h' or `L'
|
||
which is ignored, and a conversion code.
|
||
|
||
|
||
Unless the specification contains the `n' conversion character
|
||
(described below), a conversion specification directs the
|
||
conversion of the next input field. The result of a conversion
|
||
specification is returned in the position of the corresponding
|
||
argument points, unless `*' indicates assignment suppression.
|
||
Assignment suppression provides a way to describe an input field
|
||
to be skipped. An input field is defined as a string of
|
||
characters; it extends to the next inappropriate character or
|
||
until the field width, if specified, is exhausted.
|
||
|
||
_Note:_ This specification of format strings differs from the
|
||
`ANSI C' and `POSIX' specifications. In SLIB, white space
|
||
before an input field is not skipped unless white space
|
||
appears before the conversion specification in the format
|
||
string. In order to write format strings which work
|
||
identically with `ANSI C' and SLIB, prepend whitespace to all
|
||
conversion specifications except `[' and `c'.
|
||
|
||
The conversion code indicates the interpretation of the input
|
||
field; For a suppressed field, no value is returned. The
|
||
following conversion codes are legal:
|
||
|
||
`%'
|
||
A single % is expected in the input at this point; no value
|
||
is returned.
|
||
|
||
`d', `D'
|
||
A decimal integer is expected.
|
||
|
||
`u', `U'
|
||
An unsigned decimal integer is expected.
|
||
|
||
`o', `O'
|
||
An octal integer is expected.
|
||
|
||
`x', `X'
|
||
A hexadecimal integer is expected.
|
||
|
||
`i'
|
||
An integer is expected. Returns the value of the next input
|
||
item, interpreted according to C conventions; a leading `0'
|
||
implies octal, a leading `0x' implies hexadecimal; otherwise,
|
||
decimal is assumed.
|
||
|
||
`n'
|
||
Returns the total number of bytes (including white space)
|
||
read by `scanf'. No input is consumed by `%n'.
|
||
|
||
`f', `F', `e', `E', `g', `G'
|
||
A floating-point number is expected. The input format for
|
||
floating-point numbers is an optionally signed string of
|
||
digits, possibly containing a radix character `.', followed
|
||
by an optional exponent field consisting of an `E' or an `e',
|
||
followed by an optional `+', `-', or space, followed by an
|
||
integer.
|
||
|
||
`c', `C'
|
||
WIDTH characters are expected. The normal
|
||
skip-over-white-space is suppressed in this case; to read the
|
||
next non-space character, use `%1s'. If a field width is
|
||
given, a string is returned; up to the indicated number of
|
||
characters is read.
|
||
|
||
`s', `S'
|
||
A character string is expected The input field is terminated
|
||
by a white-space character. `scanf' cannot read a null
|
||
string.
|
||
|
||
`['
|
||
Indicates string data and the normal
|
||
skip-over-leading-white-space is suppressed. The left
|
||
bracket is followed by a set of characters, called the
|
||
scanset, and a right bracket; the input field is the maximal
|
||
sequence of input characters consisting entirely of
|
||
characters in the scanset. `^', when it appears as the first
|
||
character in the scanset, serves as a complement operator and
|
||
redefines the scanset as the set of all characters not
|
||
contained in the remainder of the scanset string.
|
||
Construction of the scanset follows certain conventions. A
|
||
range of characters may be represented by the construct
|
||
first-last, enabling `[0123456789]' to be expressed `[0-9]'.
|
||
Using this convention, first must be lexically less than or
|
||
equal to last; otherwise, the dash stands for itself. The
|
||
dash also stands for itself when it is the first or the last
|
||
character in the scanset. To include the right square
|
||
bracket as an element of the scanset, it must appear as the
|
||
first character (possibly preceded by a `^') of the scanset,
|
||
in which case it will not be interpreted syntactically as the
|
||
closing bracket. At least one character must match for this
|
||
conversion to succeed.
|
||
|
||
The `scanf' functions terminate their conversions at end-of-file,
|
||
at the end of the control string, or when an input character
|
||
conflicts with the control string. In the latter case, the
|
||
offending character is left unread in the input stream.
|
||
|
||
|
||
File: slib.info, Node: Programs and Arguments, Next: HTML, Prev: Standard Formatted I/O, Up: Textual Conversion Packages
|
||
|
||
Program and Arguments
|
||
=====================
|
||
|
||
* Menu:
|
||
|
||
* Getopt:: Command Line option parsing
|
||
* Command Line:: A command line reader for Scheme shells
|
||
* Parameter lists:: 'parameters
|
||
* Getopt Parameter lists:: 'getopt-parameters
|
||
* Filenames:: 'glob or 'filename
|
||
* Batch:: 'batch
|
||
|
||
|
||
File: slib.info, Node: Getopt, Next: Command Line, Prev: Programs and Arguments, Up: Programs and Arguments
|
||
|
||
Getopt
|
||
------
|
||
|
||
`(require 'getopt)'
|
||
|
||
This routine implements Posix command line argument parsing. Notice
|
||
that returning values through global variables means that `getopt' is
|
||
_not_ reentrant.
|
||
|
||
- Variable: *optind*
|
||
Is the index of the current element of the command line. It is
|
||
initially one. In order to parse a new command line or reparse an
|
||
old one, *OPTING* must be reset.
|
||
|
||
- Variable: *optarg*
|
||
Is set by getopt to the (string) option-argument of the current
|
||
option.
|
||
|
||
- Procedure: getopt argc argv optstring
|
||
Returns the next option letter in ARGV (starting from `(vector-ref
|
||
argv *optind*)') that matches a letter in OPTSTRING. ARGV is a
|
||
vector or list of strings, the 0th of which getopt usually
|
||
ignores. ARGC is the argument count, usually the length of ARGV.
|
||
OPTSTRING is a string of recognized option characters; if a
|
||
character is followed by a colon, the option takes an argument
|
||
which may be immediately following it in the string or in the next
|
||
element of ARGV.
|
||
|
||
*OPTIND* is the index of the next element of the ARGV vector to be
|
||
processed. It is initialized to 1 by `getopt.scm', and `getopt'
|
||
updates it when it finishes with each element of ARGV.
|
||
|
||
`getopt' returns the next option character from ARGV that matches
|
||
a character in OPTSTRING, if there is one that matches. If the
|
||
option takes an argument, `getopt' sets the variable *OPTARG* to
|
||
the option-argument as follows:
|
||
|
||
* If the option was the last character in the string pointed to
|
||
by an element of ARGV, then *OPTARG* contains the next
|
||
element of ARGV, and *OPTIND* is incremented by 2. If the
|
||
resulting value of *OPTIND* is greater than or equal to ARGC,
|
||
this indicates a missing option argument, and `getopt'
|
||
returns an error indication.
|
||
|
||
* Otherwise, *OPTARG* is set to the string following the option
|
||
character in that element of ARGV, and *OPTIND* is
|
||
incremented by 1.
|
||
|
||
If, when `getopt' is called, the string `(vector-ref argv
|
||
*optind*)' either does not begin with the character `#\-' or is
|
||
just `"-"', `getopt' returns `#f' without changing *OPTIND*. If
|
||
`(vector-ref argv *optind*)' is the string `"--"', `getopt'
|
||
returns `#f' after incrementing *OPTIND*.
|
||
|
||
If `getopt' encounters an option character that is not contained in
|
||
OPTSTRING, it returns the question-mark `#\?' character. If it
|
||
detects a missing option argument, it returns the colon character
|
||
`#\:' if the first character of OPTSTRING was a colon, or a
|
||
question-mark character otherwise. In either case, `getopt' sets
|
||
the variable GETOPT:OPT to the option character that caused the
|
||
error.
|
||
|
||
The special option `"--"' can be used to delimit the end of the
|
||
options; `#f' is returned, and `"--"' is skipped.
|
||
|
||
RETURN VALUE
|
||
|
||
`getopt' returns the next option character specified on the command
|
||
line. A colon `#\:' is returned if `getopt' detects a missing
|
||
argument and the first character of OPTSTRING was a colon `#\:'.
|
||
|
||
A question-mark `#\?' is returned if `getopt' encounters an option
|
||
character not in OPTSTRING or detects a missing argument and the
|
||
first character of OPTSTRING was not a colon `#\:'.
|
||
|
||
Otherwise, `getopt' returns `#f' when all command line options
|
||
have been parsed.
|
||
|
||
Example:
|
||
#! /usr/local/bin/scm
|
||
;;;This code is SCM specific.
|
||
(define argv (program-arguments))
|
||
(require 'getopt)
|
||
|
||
(define opts ":a:b:cd")
|
||
(let loop ((opt (getopt (length argv) argv opts)))
|
||
(case opt
|
||
((#\a) (print "option a: " *optarg*))
|
||
((#\b) (print "option b: " *optarg*))
|
||
((#\c) (print "option c"))
|
||
((#\d) (print "option d"))
|
||
((#\?) (print "error" getopt:opt))
|
||
((#\:) (print "missing arg" getopt:opt))
|
||
((#f) (if (< *optind* (length argv))
|
||
(print "argv[" *optind* "]="
|
||
(list-ref argv *optind*)))
|
||
(set! *optind* (+ *optind* 1))))
|
||
(if (< *optind* (length argv))
|
||
(loop (getopt (length argv) argv opts))))
|
||
|
||
(slib:exit)
|
||
|
||
Getopt-
|
||
-------
|
||
|
||
- Function: getopt- argc argv optstring
|
||
The procedure `getopt--' is an extended version of `getopt' which
|
||
parses "long option names" of the form `--hold-the-onions' and
|
||
`--verbosity-level=extreme'. `Getopt--' behaves as `getopt'
|
||
except for non-empty options beginning with `--'.
|
||
|
||
Options beginning with `--' are returned as strings rather than
|
||
characters. If a value is assigned (using `=') to a long option,
|
||
`*optarg*' is set to the value. The `=' and value are not
|
||
returned as part of the option string.
|
||
|
||
No information is passed to `getopt--' concerning which long
|
||
options should be accepted or whether such options can take
|
||
arguments. If a long option did not have an argument, `*optarg'
|
||
will be set to `#f'. The caller is responsible for detecting and
|
||
reporting errors.
|
||
|
||
(define opts ":-:b:")
|
||
(define argc 5)
|
||
(define argv '("foo" "-b9" "--f1" "--2=" "--g3=35234.342" "--"))
|
||
(define *optind* 1)
|
||
(define *optarg* #f)
|
||
(require 'qp)
|
||
(do ((i 5 (+ -1 i)))
|
||
((zero? i))
|
||
(define opt (getopt-- argc argv opts))
|
||
(print *optind* opt *optarg*)))
|
||
-|
|
||
2 #\b "9"
|
||
3 "f1" #f
|
||
4 "2" ""
|
||
5 "g3" "35234.342"
|
||
5 #f "35234.342"
|
||
|
||
|
||
File: slib.info, Node: Command Line, Next: Parameter lists, Prev: Getopt, Up: Programs and Arguments
|
||
|
||
Command Line
|
||
------------
|
||
|
||
`(require 'read-command)'
|
||
|
||
- Function: read-command port
|
||
- Function: read-command
|
||
`read-command' converts a "command line" into a list of strings
|
||
suitable for parsing by `getopt'. The syntax of command lines
|
||
supported resembles that of popular "shell"s. `read-command'
|
||
updates PORT to point to the first character past the command
|
||
delimiter.
|
||
|
||
If an end of file is encountered in the input before any
|
||
characters are found that can begin an object or comment, then an
|
||
end of file object is returned.
|
||
|
||
The PORT argument may be omitted, in which case it defaults to the
|
||
value returned by `current-input-port'.
|
||
|
||
The fields into which the command line is split are delimited by
|
||
whitespace as defined by `char-whitespace?'. The end of a command
|
||
is delimited by end-of-file or unescaped semicolon (<;>) or
|
||
<newline>. Any character can be literally included in a field by
|
||
escaping it with a backslach (<\>).
|
||
|
||
The initial character and types of fields recognized are:
|
||
`\'
|
||
The next character has is taken literally and not interpreted
|
||
as a field delimiter. If <\> is the last character before a
|
||
<newline>, that <newline> is just ignored. Processing
|
||
continues from the characters after the <newline> as though
|
||
the backslash and <newline> were not there.
|
||
|
||
`"'
|
||
The characters up to the next unescaped <"> are taken
|
||
literally, according to [R4RS] rules for literal strings
|
||
(*note Strings: (r4rs)Strings.).
|
||
|
||
`(', `%''
|
||
One scheme expression is `read' starting with this character.
|
||
The `read' expression is evaluated, converted to a string
|
||
(using `display'), and replaces the expression in the returned
|
||
field.
|
||
|
||
`;'
|
||
Semicolon delimits a command. Using semicolons more than one
|
||
command can appear on a line. Escaped semicolons and
|
||
semicolons inside strings do not delimit commands.
|
||
|
||
The comment field differs from the previous fields in that it must
|
||
be the first character of a command or appear after whitespace in
|
||
order to be recognized. <#> can be part of fields if these
|
||
conditions are not met. For instance, `ab#c' is just the field
|
||
ab#c.
|
||
|
||
`#'
|
||
Introduces a comment. The comment continues to the end of
|
||
the line on which the semicolon appears. Comments are
|
||
treated as whitespace by `read-dommand-line' and backslashes
|
||
before <newline>s in comments are also ignored.
|
||
|
||
- Function: read-options-file filename
|
||
`read-options-file' converts an "options file" into a list of
|
||
strings suitable for parsing by `getopt'. The syntax of options
|
||
files is the same as the syntax for command lines, except that
|
||
<newline>s do not terminate reading (only <;> or end of file).
|
||
|
||
If an end of file is encountered before any characters are found
|
||
that can begin an object or comment, then an end of file object is
|
||
returned.
|
||
|
||
|
||
File: slib.info, Node: Parameter lists, Next: Getopt Parameter lists, Prev: Command Line, Up: Programs and Arguments
|
||
|
||
Parameter lists
|
||
---------------
|
||
|
||
`(require 'parameters)'
|
||
|
||
Arguments to procedures in scheme are distinguished from each other by
|
||
their position in the procedure call. This can be confusing when a
|
||
procedure takes many arguments, many of which are not often used.
|
||
|
||
A "parameter-list" is a way of passing named information to a
|
||
procedure. Procedures are also defined to set unused parameters to
|
||
default values, check parameters, and combine parameter lists.
|
||
|
||
A PARAMETER has the form `(parameter-name value1 ...)'. This format
|
||
allows for more than one value per parameter-name.
|
||
|
||
A PARAMETER-LIST is a list of PARAMETERs, each with a different
|
||
PARAMETER-NAME.
|
||
|
||
- Function: make-parameter-list parameter-names
|
||
Returns an empty parameter-list with slots for PARAMETER-NAMES.
|
||
|
||
- Function: parameter-list-ref parameter-list parameter-name
|
||
PARAMETER-NAME must name a valid slot of PARAMETER-LIST.
|
||
`parameter-list-ref' returns the value of parameter PARAMETER-NAME
|
||
of PARAMETER-LIST.
|
||
|
||
- Function: remove-parameter parameter-name parameter-list
|
||
Removes the parameter PARAMETER-NAME from PARAMETER-LIST.
|
||
`remove-parameter' does not alter the argument PARAMETER-LIST.
|
||
|
||
If there are more than one PARAMETER-NAME parameters, an error is
|
||
signaled.
|
||
|
||
- Procedure: adjoin-parameters! parameter-list parameter1 ...
|
||
Returns PARAMETER-LIST with PARAMETER1 ... merged in.
|
||
|
||
- Procedure: parameter-list-expand expanders parameter-list
|
||
EXPANDERS is a list of procedures whose order matches the order of
|
||
the PARAMETER-NAMEs in the call to `make-parameter-list' which
|
||
created PARAMETER-LIST. For each non-false element of EXPANDERS
|
||
that procedure is mapped over the corresponding parameter value
|
||
and the returned parameter lists are merged into PARAMETER-LIST.
|
||
|
||
This process is repeated until PARAMETER-LIST stops growing. The
|
||
value returned from `parameter-list-expand' is unspecified.
|
||
|
||
- Function: fill-empty-parameters defaulters parameter-list
|
||
DEFAULTERS is a list of procedures whose order matches the order
|
||
of the PARAMETER-NAMEs in the call to `make-parameter-list' which
|
||
created PARAMETER-LIST. `fill-empty-parameters' returns a new
|
||
parameter-list with each empty parameter replaced with the list
|
||
returned by calling the corresponding DEFAULTER with
|
||
PARAMETER-LIST as its argument.
|
||
|
||
- Function: check-parameters checks parameter-list
|
||
CHECKS is a list of procedures whose order matches the order of
|
||
the PARAMETER-NAMEs in the call to `make-parameter-list' which
|
||
created PARAMETER-LIST.
|
||
|
||
`check-parameters' returns PARAMETER-LIST if each CHECK of the
|
||
corresponding PARAMETER-LIST returns non-false. If some CHECK
|
||
returns `#f' a warning is signaled. |
|
||
|
||
In the following procedures ARITIES is a list of symbols. The elements
|
||
of `arities' can be:
|
||
|
||
`single'
|
||
Requires a single parameter.
|
||
|
||
`optional'
|
||
A single parameter or no parameter is acceptable.
|
||
|
||
`boolean'
|
||
A single boolean parameter or zero parameters is acceptable.
|
||
|
||
`nary'
|
||
Any number of parameters are acceptable.
|
||
|
||
`nary1'
|
||
One or more of parameters are acceptable.
|
||
|
||
- Function: parameter-list->arglist positions arities parameter-list |
|
||
Returns PARAMETER-LIST converted to an argument list. Parameters
|
||
of ARITY type `single' and `boolean' are converted to the single
|
||
value associated with them. The other ARITY types are converted
|
||
to lists of the value(s). |
|
||
|
||
POSITIONS is a list of positive integers whose order matches the
|
||
order of the PARAMETER-NAMEs in the call to `make-parameter-list'
|
||
which created PARAMETER-LIST. The integers specify in which
|
||
argument position the corresponding parameter should appear.
|
||
|
||
|
||
File: slib.info, Node: Getopt Parameter lists, Next: Filenames, Prev: Parameter lists, Up: Programs and Arguments
|
||
|
||
Getopt Parameter lists
|
||
----------------------
|
||
|
||
`(require 'getopt-parameters)'
|
||
|
||
- Function: getopt->parameter-list argc argv optnames arities types
|
||
aliases desc ... |
|
||
Returns ARGV converted to a parameter-list. OPTNAMES are the
|
||
parameter-names. ARITIES and TYPES are lists of symbols |
|
||
corresponding to OPTNAMES. |
|
||
|
|
||
ALIASES is a list of lists of strings or integers paired with |
|
||
elements of OPTNAMES. Each one-character string will be treated |
|
||
as a single `-' option by `getopt'. Longer strings will be |
|
||
treated as long-named options (*note getopt-: Getopt.). |
|
||
|
|
||
If the ALIASES association list has only strings as its `car's, |
|
||
then all the option-arguments after an option (and before the next |
|
||
option) are adjoined to that option. |
|
||
|
|
||
If the ALIASES association list has integers, then each (string) |
|
||
option will take at most one option-argument. Unoptioned |
|
||
arguments are collected in a list. A `-1' alias will take the |
|
||
last argument in this list; `+1' will take the first argument in |
|
||
the list. The aliases -2 then +2; -3 then +3; ... are tried so |
|
||
long as a positive or negative consecutive alias is found and |
|
||
arguments remain in the list. Finally a `0' alias, if found, |
|
||
absorbs any remaining arguments. |
|
||
|
|
||
In all cases, if unclaimed arguments remain after processing, a |
|
||
warning is signaled and #f is returned. |
|
||
|
||
- Function: getopt->arglist argc argv optnames positions arities types
|
||
defaulters checks aliases desc ... |
|
||
Like `getopt->parameter-list', but converts ARGV to an
|
||
argument-list as specified by OPTNAMES, POSITIONS, ARITIES, TYPES,
|
||
DEFAULTERS, CHECKS, and ALIASES. If the options supplied violate |
|
||
the ARITIES or CHECKS constraints, then a warning is signaled and |
|
||
#f is returned. |
|
||
|
||
These `getopt' functions can be used with SLIB relational databases.
|
||
For an example, *Note make-command-server: Database Utilities.
|
||
|
||
If errors are encountered while processing options, directions for using
|
||
the options (and argument strings DESC ...) are printed to |
|
||
`current-error-port'. |
|
||
|
||
(begin
|
||
(set! *optind* 1)
|
||
(getopt->parameter-list
|
||
2
|
||
'("cmd" "-?")
|
||
'(flag number symbols symbols string flag2 flag3 num2 num3)
|
||
'(boolean optional nary1 nary single boolean boolean nary nary)
|
||
'(boolean integer symbol symbol string boolean boolean integer integer)
|
||
'(("flag" flag)
|
||
("f" flag)
|
||
("Flag" flag2)
|
||
("B" flag3)
|
||
("optional" number)
|
||
("o" number)
|
||
("nary1" symbols)
|
||
("N" symbols)
|
||
("nary" symbols)
|
||
("n" symbols)
|
||
("single" string)
|
||
("s" string)
|
||
("a" num2)
|
||
("Abs" num3))))
|
||
-|
|
||
Usage: cmd [OPTION ARGUMENT ...] ...
|
||
|
||
-f, --flag
|
||
-o, --optional=<number>
|
||
-n, --nary=<symbols> ...
|
||
-N, --nary1=<symbols> ...
|
||
-s, --single=<string>
|
||
--Flag
|
||
-B
|
||
-a <num2> ...
|
||
--Abs=<num3> ...
|
||
|
||
ERROR: getopt->parameter-list "unrecognized option" "-?"
|
||
|
||
|
||
File: slib.info, Node: Filenames, Next: Batch, Prev: Getopt Parameter lists, Up: Programs and Arguments
|
||
|
||
Filenames
|
||
---------
|
||
|
||
`(require 'filename)' or `(require 'glob)'
|
||
|
||
- Function: filename:match?? pattern
|
||
- Function: filename:match-ci?? pattern
|
||
Returns a predicate which returns a non-false value if its string
|
||
argument matches (the string) PATTERN, false otherwise. Filename
|
||
matching is like "glob" expansion described the bash manpage,
|
||
except that names beginning with `.' are matched and `/'
|
||
characters are not treated specially.
|
||
|
||
These functions interpret the following characters specially in
|
||
PATTERN strings:
|
||
`*'
|
||
Matches any string, including the null string.
|
||
|
||
`?'
|
||
Matches any single character.
|
||
|
||
`[...]'
|
||
Matches any one of the enclosed characters. A pair of
|
||
characters separated by a minus sign (-) denotes a range; any
|
||
character lexically between those two characters, inclusive,
|
||
is matched. If the first character following the `[' is a
|
||
`!' or a `^' then any character not enclosed is matched. A
|
||
`-' or `]' may be matched by including it as the first or
|
||
last character in the set.
|
||
|
||
|
||
- Function: filename:substitute?? pattern template
|
||
- Function: filename:substitute-ci?? pattern template
|
||
Returns a function transforming a single string argument according
|
||
to glob patterns PATTERN and TEMPLATE. PATTERN and TEMPLATE must
|
||
have the same number of wildcard specifications, which need not be
|
||
identical. PATTERN and TEMPLATE may have a different number of
|
||
literal sections. If an argument to the function matches PATTERN
|
||
in the sense of `filename:match??' then it returns a copy of
|
||
TEMPLATE in which each wildcard specification is replaced by the
|
||
part of the argument matched by the corresponding wildcard
|
||
specification in PATTERN. A `*' wildcard matches the longest
|
||
leftmost string possible. If the argument does not match PATTERN
|
||
then false is returned.
|
||
|
||
TEMPLATE may be a function accepting the same number of string
|
||
arguments as there are wildcard specifications in PATTERN. In the
|
||
case of a match the result of applying TEMPLATE to a list of the
|
||
substrings matched by wildcard specifications will be returned,
|
||
otherwise TEMPLATE will not be called and `#f' will be returned.
|
||
|
||
((filename:substitute?? "scm_[0-9]*.html" "scm5c4_??.htm")
|
||
"scm_10.html")
|
||
=> "scm5c4_10.htm"
|
||
((filename:substitute?? "??" "beg?mid?end") "AZ")
|
||
=> "begAmidZend"
|
||
((filename:substitute?? "*na*" "?NA?") "banana")
|
||
=> "banaNA"
|
||
((filename:substitute?? "?*?" (lambda (s1 s2 s3) (string-append s3 s1))) "ABZ")
|
||
=> "ZA"
|
||
|
||
- Function: replace-suffix str old new
|
||
STR can be a string or a list of strings. Returns a new string
|
||
(or strings) 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.
|
||
|
||
(replace-suffix "/usr/local/lib/slib/batch.scm" ".scm" ".c")
|
||
=> "/usr/local/lib/slib/batch.c"
|
||
|
||
|
||
File: slib.info, Node: Batch, Prev: Filenames, Up: Programs and Arguments
|
||
|
||
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
|
||
|
||
* amigados
|
||
|
||
* 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.
|
||
|
||
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:command parms string1 string2 ...
|
||
Calls `batch:try-command' (below) with arguments, but signals an
|
||
error if `batch:try-command' 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-command parms string1 string2 ...
|
||
Writes a command to the `batch-port' in PARMS which executes the
|
||
program named STRING1 with arguments STRING2 ....
|
||
|
||
- Function: batch:try-chopped-command parms arg1 arg2 ... list
|
||
breaks the last argument LIST into chunks small enough so that the
|
||
command:
|
||
|
||
ARG1 ARG2 ... CHUNK
|
||
|
||
fits withing the platform's maximum command-line length.
|
||
|
||
`batch:try-chopped-command' calls `batch:try-command' with the
|
||
command and returns non-false only if the commands all fit and
|
||
`batch:try-command' of each command line returned non-false.
|
||
|
||
- 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-command' 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: truncate-up-to path char
|
||
- Function: truncate-up-to path string
|
||
- Function: truncate-up-to path charlist
|
||
PATH can be a string or a list of strings. Returns PATH sans any
|
||
prefixes ending with a character of the second argument. This can
|
||
be used to derive a filename moved locally from elsewhere.
|
||
|
||
(truncate-up-to "/usr/local/lib/slib/batch.scm" "/")
|
||
=> "batch.scm"
|
||
|
||
- 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)
|
||
(require 'glob)
|
||
|
||
(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 <stdio.h>"
|
||
"int main(int argc, char **argv)"
|
||
"{"
|
||
" printf(\"hello world\\n\");"
|
||
" return 0;"
|
||
"}" )
|
||
(batch:command my-parameters "cc" "-c" "hello.c")
|
||
(batch:command my-parameters "cc" "-o" "hello"
|
||
(replace-suffix "hello.c" ".c" ".o"))
|
||
(batch:command 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" script created by SLIB/batch Sun Oct 31 18:24:10 1999
|
||
# ================ Write file with C program.
|
||
mv -f hello.c hello.c~
|
||
rm -f hello.c
|
||
echo '#include <stdio.h>'>>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: HTML, Next: HTML Tables, Prev: Programs and Arguments, Up: Textual Conversion Packages
|
||
|
||
HTML
|
||
====
|
||
|
||
`(require 'html-form)'
|
||
|
||
- Function: html:atval txt
|
||
Returns a string with character substitutions appropriate to send
|
||
TXT as an "attribute-value".
|
||
|
||
- Function: html:plain txt
|
||
Returns a string with character substitutions appropriate to send
|
||
TXT as an "plain-text".
|
||
|
||
- Function: html:meta name content |
|
||
Returns a tag of meta-information suitable for passing as the |
|
||
third argument to `html:head'. The tag produced is `<META |
|
||
NAME="NAME" CONTENT="CONTENT">'. The string or symbol NAME can be |
|
||
`author', `copyright', `keywords', `description', `date', |
|
||
`robots', .... |
|
||
|
|
||
- Function: html:http-equiv name content |
|
||
Returns a tag of HTTP information suitable for passing as the |
|
||
third argument to `html:head'. The tag produced is `<META |
|
||
HTTP-EQUIV="NAME" CONTENT="CONTENT">'. The string or symbol NAME |
|
||
can be `Expires', `PICS-Label', `Content-Type', `Refresh', .... |
|
||
|
|
||
- Function: html:meta-refresh delay uri |
|
||
- Function: html:meta-refresh delay |
|
||
Returns a tag suitable for passing as the third argument to |
|
||
`html:head'. If URI argument is supplied, then DELAY seconds after |
|
||
displaying the page with this tag, Netscape or IE browsers will |
|
||
fetch and display URI. Otherwise, DELAY seconds after displaying |
|
||
the page with this tag, Netscape or IE browsers will fetch and |
|
||
redisplay this page. |
|
||
|
|
||
- Function: html:head title backlink tags ...
|
||
- Function: html:head title backlink
|
||
- Function: html:head title
|
||
Returns header string for an HTML page named TITLE. If BACKLINK |
|
||
is a string, it is used verbatim between the `H1' tags; otherwise |
|
||
TITLE is used. If string arguments TAGS ... are supplied, then |
|
||
they are included verbatim within the <HEAD> section. |
|
||
|
||
- Function: html:body body ...
|
||
Returns HTML string to end a page.
|
||
|
||
- Function: html:pre line1 line ...
|
||
Returns the strings LINE1, LINES as "PRE"formmated plain text
|
||
(rendered in fixed-width font). Newlines are inserted between
|
||
LINE1, LINES. HTML tags (`<tag>') within LINES will be visible
|
||
verbatim.
|
||
|
||
- Function: html:comment line1 line ...
|
||
Returns the strings LINE1 as HTML comments.
|
||
|
||
HTML Forms
|
||
==========
|
||
|
||
- Function: html:form method action body ... |
|
||
The symbol METHOD is either `get', `head', `post', `put', or
|
||
`delete'. The strings BODY form the body of the form. |
|
||
`html:form' returns the HTML "form".
|
||
|
||
- Function: html:hidden name value |
|
||
Returns HTML string which will cause NAME=VALUE in form. |
|
||
|
|
||
- Function: html:checkbox pname default |
|
||
Returns HTML string for check box. |
|
||
|
|
||
- Function: html:text pname default size ... |
|
||
Returns HTML string for one-line text box. |
|
||
|
|
||
- Function: html:text-area pname default-list |
|
||
Returns HTML string for multi-line text box. |
|
||
|
|
||
- Function: html:select pname arity default-list foreign-values |
|
||
Returns HTML string for pull-down menu selector. |
|
||
|
|
||
- Function: html:buttons pname arity default-list foreign-values |
|
||
Returns HTML string for any-of selector. |
|
||
|
|
||
- Function: form:submit submit-label command |
|
||
- Function: form:submit submit-label |
|
||
The string or symbol SUBMIT-LABEL appears on the button which |
|
||
submits the form. If the optional second argument COMMAND is |
|
||
given, then `*command*=COMMAND' and `*button*=SUBMIT-LABEL' are |
|
||
set in the query. Otherwise, `*command*=SUBMIT-LABEL' is set in |
|
||
the query. |
|
||
|
|
||
- Function: form:image submit-label image-src |
|
||
The IMAGE-SRC appears on the button which submits the form. |
|
||
|
|
||
- Function: form:reset |
|
||
Returns a string which generates a "reset" button. |
|
||
|
|
||
- Function: form:element pname arity default-list foreign-values |
|
||
Returns a string which generates an INPUT element for the field |
|
||
named PNAME. The element appears in the created form with its |
|
||
representation determined by its ARITY and domain. For domains |
|
||
which are foreign-keys: |
|
||
|
|
||
`single' |
|
||
select menu |
|
||
|
|
||
`optional' |
|
||
select menu |
|
||
|
|
||
`nary' |
|
||
check boxes |
|
||
|
|
||
`nary1' |
|
||
check boxes |
|
||
|
|
||
If the foreign-key table has a field named `visible-name', then |
|
||
the contents of that field are the names visible to the user for |
|
||
those choices. Otherwise, the foreign-key itself is visible. |
|
||
|
|
||
For other types of domains: |
|
||
|
|
||
`single' |
|
||
text area |
|
||
|
|
||
`optional' |
|
||
text area |
|
||
|
|
||
`boolean' |
|
||
check box |
|
||
|
|
||
`nary' |
|
||
text area |
|
||
|
|
||
`nary1' |
|
||
text area |
|
||
|
|
||
- Function: form:delimited pname doc aliat arity default-list |
|
||
foreign-values |
|
||
Returns a HTML string for a form element embedded in a line of a |
|
||
delimited list. Apply map `form:delimited' to the list returned by |
|
||
`command->p-specs'. |
|
||
|
|
||
- Function: command->p-specs rdb command-table command |
|
||
The symbol COMMAND-TABLE names a command table in the RDB
|
||
relational database. The symbol COMMAND names a key in |
|
||
COMMAND-TABLE. |
|
||
|
||
`command->p-specs' returns a list of lists of PNAME, DOC, ALIAT, |
|
||
ARITY, DEFAULT-LIST, and FOREIGN-VALUES. The returned list has |
|
||
one element for each parameter of command COMMAND. |
|
||
|
||
This example demonstrates how to create a HTML-form for the `build'
|
||
command.
|
||
|
||
(require (in-vicinity (implementation-vicinity) "build.scm"))
|
||
(call-with-output-file "buildscm.html"
|
||
(lambda (port)
|
||
(display
|
||
(string-append
|
||
(html:head 'commands)
|
||
(html:body
|
||
(sprintf #f "<H2>%s:</H2><BLOCKQUOTE>%s</BLOCKQUOTE>\\n" |
|
||
(html:plain 'build) |
|
||
(html:plain ((comtab 'get 'documentation) 'build))) |
|
||
(html:form |
|
||
'post |
|
||
(or "http://localhost:8081/buildscm" "/cgi-bin/build.cgi") |
|
||
(apply html:delimited-list |
|
||
(apply map form:delimited |
|
||
(command->p-specs build '*commands* 'build))) |
|
||
(form:submit 'build) |
|
||
(form:reset)))) |
|
||
port)))
|
||
|
||
|
||
File: slib.info, Node: HTML Tables, Next: HTTP and CGI, Prev: HTML, Up: Textual Conversion Packages
|
||
|
||
HTML Tables
|
||
===========
|
||
|
||
`(require 'db->html)'
|
||
|
||
- Function: html:table options row ... |
|
||
|
|
||
- Function: html:caption caption align |
|
||
- Function: html:caption caption |
|
||
ALIGN can be `top' or `bottom'. |
|
||
|
||
- Function: html:heading columns
|
||
Outputs a heading row for the currently-started table.
|
||
|
||
- Function: html:href-heading columns uris |
|
||
Outputs a heading row with column-names COLUMNS linked to URIs |
|
||
URIS. |
|
||
|
||
- Function: html:linked-row-converter k foreigns |
|
||
The positive integer K is the primary-key-limit (number of
|
||
primary-keys) of the table. FOREIGNS is a list of the filenames of
|
||
foreign-key field pages and #f for non foreign-key fields.
|
||
|
||
`html:linked-row-converter' returns a procedure taking a row for |
|
||
its single argument. This returned procedure returns the html |
|
||
string for that table row. |
|
||
|
||
- Function: table-name->filename table-name
|
||
Returns the symbol TABLE-NAME converted to a filename.
|
||
|
||
- Function: table->linked-html caption db table-name match-key1 ... |
|
||
Returns HTML string for DB table TABLE-NAME. Every foreign-key |
|
||
value is linked to the page (of the table) defining that key. |
|
||
|
||
The optional MATCH-KEY1 ... arguments restrict actions to a subset
|
||
of the table. *Note match-key: Table Operations.
|
||
|
||
- Function: table->linked-page db table-name index-filename arg ... |
|
||
Returns a complete HTML page. The string INDEX-FILENAME names the
|
||
page which refers to this one.
|
||
|
||
The optional ARGS ... arguments restrict actions to a subset of
|
||
the table. *Note match-key: Table Operations.
|
||
|
||
- Function: catalog->html db caption arg ...
|
||
Returns HTML string for the catalog table of DB.
|
||
|
||
HTML editing tables |
|
||
------------------- |
|
||
|
|
||
A client can modify one row of an editable table at a time. For any |
|
||
change submitted, these routines check if that row has been modified |
|
||
during the time the user has been editing the form. If so, an error |
|
||
page results. |
|
||
|
|
||
The behavior of edited rows is: |
|
||
|
|
||
* If no fields are changed, then no change is made to the table. |
|
||
|
|
||
* If the primary keys equal null-keys (parameter defaults), and no |
|
||
other user has modified that row, then that row is deleted. |
|
||
|
|
||
* If only primary keys are changed, there are non-key fields, and no |
|
||
row with the new keys is in the table, then the old row is deleted |
|
||
and one with the new keys is inserted. |
|
||
|
|
||
* If only non-key fields are changed, and that row has not been |
|
||
modified by another user, then the row is changed to reflect the |
|
||
fields. |
|
||
|
|
||
* If both keys and non-key fields are changed, and no row with the |
|
||
new keys is in the table, then a row is created with the new keys |
|
||
and fields. |
|
||
|
|
||
* If fields are changed, all fields are primary keys, and no row with |
|
||
the new keys is in the table, then a row is created with the new |
|
||
keys. |
|
||
|
|
||
After any change to the table, a `sync-database' of the database is |
|
||
performed. |
|
||
|
|
||
- Function: command:modify-table table-name null-keys update delete |
|
||
retrieve |
|
||
- Function: command:modify-table table-name null-keys update delete |
|
||
- Function: command:modify-table table-name null-keys update |
|
||
- Function: command:modify-table table-name null-keys |
|
||
Returns procedure (of DB) which returns procedure to modify row of |
|
||
TABLE-NAME. NULL-KEYS is the list of "null" keys which indicate |
|
||
that the row is to be deleted. Optional arguments UPDATE, DELETE, |
|
||
and RETRIEVE default to the `row:update', `row:delete', and |
|
||
`row:retrieve' of TABLE-NAME in DB. |
|
||
|
|
||
- Function: command:make-editable-table rdb table-name arg ... |
|
||
Given TABLE-NAME in RDB, creates parameter and `*command*' tables |
|
||
for editing one row of TABLE-NAME at a time. |
|
||
`command:make-editable-table' returns a procedure taking a row |
|
||
argument which returns the HTML string for editing that row. |
|
||
|
|
||
Optional ARGS are expressions (lists) added to the call to |
|
||
`command:modify-table'. |
|
||
|
|
||
The domain name of a column determines the expected arity of the |
|
||
data stored in that column. Domain names ending in: |
|
||
|
|
||
`*' |
|
||
have arity `nary'; |
|
||
|
|
||
`+' |
|
||
have arity `nary1'. |
|
||
|
|
||
- Function: html:editable-row-converter k names edit-point |
|
||
edit-converter |
|
||
The positive integer K is the primary-key-limit (number of |
|
||
primary-keys) of the table. NAMES is a list of the field-names. |
|
||
EDIT-POINT is the list of primary-keys denoting the row to edit |
|
||
(or #f). EDIT-CONVERTER is the procedure called with K, NAMES, |
|
||
and the row to edit. |
|
||
|
|
||
`html:editable-row-converter' returns a procedure taking a row for |
|
||
its single argument. This returned procedure returns the html |
|
||
string for that table row. |
|
||
|
|
||
Each HTML table constructed using `html:editable-row-converter' |
|
||
has first K fields (typically the primary key fields) of each row |
|
||
linked to a text encoding of these fields (the result of calling |
|
||
`row->anchor'). The page so referenced typically allows the user |
|
||
to edit fields of that row. |
|
||
|
||
HTML databases
|
||
--------------
|
||
|
||
- Function: db->html-files db dir index-filename caption |
|
||
DB must be a relational database. DIR must be #f or a non-empty
|
||
string naming an existing sub-directory of the current directory.
|
||
|
||
`db->html-files' creates an html page for each table in the |
|
||
database DB in the sub-directory named DIR, or the current |
|
||
directory if DIR is #f. The top level page with the catalog of |
|
||
tables (captioned CAPTION) is written to a file named |
|
||
INDEX-FILENAME. |
|
||
|
||
- Function: db->html-directory db dir index-filename |
|
||
- Function: db->html-directory db dir |
|
||
DB must be a relational database. DIR must be a non-empty string
|
||
naming an existing sub-directory of the current directory or one
|
||
to be created. The optional string INDEX-FILENAME names the
|
||
filename of the top page, which defaults to `index.html'.
|
||
|
||
`db->html-directory' creates sub-directory DIR if neccessary, and |
|
||
calls `(db->html-files DB DIR INDEX-FILENAME DIR)'. The `file:' |
|
||
URI of INDEX-FILENAME is returned. |
|
||
|
||
- Function: db->netscape db dir index-filename
|
||
- Function: db->netscape db dir
|
||
`db->netscape' is just like `db->html-directory', but calls |
|
||
`browse-url-netscape' with the uri for the top page after the |
|
||
pages are created.
|
||
|
||
|
||
File: slib.info, Node: HTTP and CGI, Next: URI, Prev: HTML Tables, Up: Textual Conversion Packages
|
||
|
|
||
HTTP and CGI
|
||
============
|
||
|
||
`(require 'http)' or `(require 'cgi)'
|
||
|
|
||
- Function: http:header alist
|
||
Returns a string containing lines for each element of ALIST; the
|
||
`car' of which is followed by `: ', then the `cdr'.
|
||
|
||
- Function: http:content alist body ...
|
||
Returns the concatenation of strings BODY with the `(http:header
|
||
ALIST)' and the `Content-Length' prepended.
|
||
|
||
- Variable: *http:byline*
|
||
String appearing at the bottom of error pages.
|
||
|
||
- Function: http:error-page status-code reason-phrase html-string ...
|
||
STATUS-CODE and REASON-PHRASE should be an integer and string as
|
||
specified in `RFC 2068'. The returned page (string) will show the
|
||
STATUS-CODE and REASON-PHRASE and any additional HTML-STRINGS ...;
|
||
with *HTTP:BYLINE* or SLIB's default at the bottom.
|
||
|
||
- Function: http:forwarding-page title delay uri html-string ... |
|
||
The string or symbol TITLE is the page title. DELAY is a |
|
||
non-negative integer. The HTML-STRINGS ... are typically used to |
|
||
explain to the user why this page is being forwarded. |
|
||
|
|
||
`http:forwarding-page' returns an HTML string for a page which |
|
||
automatically forwards to URI after DELAY seconds. The returned |
|
||
page (string) contains any HTML-STRINGS ... followed by a manual |
|
||
link to URI, in case the browser does not forward automatically. |
|
||
|
|
||
- Function: http:serve-query serve-proc input-port output-port
|
||
reads the "URI" and "query-string" from INPUT-PORT. If the query
|
||
is a valid `"POST"' or `"GET"' query, then `http:serve-query' calls
|
||
SERVE-PROC with three arguments, the REQUEST-LINE, QUERY-STRING,
|
||
and HEADER-ALIST. Otherwise, `http:serve-query' calls SERVE-PROC
|
||
with the REQUEST-LINE, #f, and HEADER-ALIST.
|
||
|
||
If SERVE-PROC returns a string, it is sent to OUTPUT-PORT. If
|
||
SERVE-PROC returns a list, then an error page with number 525 and
|
||
strings from the list. If SERVE-PROC returns #f, then a `Bad
|
||
Request' (400) page is sent to OUTPUT-PORT.
|
||
|
||
Otherwise, `http:serve-query' replies (to OUTPUT-PORT) with
|
||
appropriate HTML describing the problem.
|
||
|
||
This example services HTTP queries from PORT-NUMBER:
|
||
|
||
(define socket (make-stream-socket AF_INET 0))
|
||
(and (socket:bind socket port-number) ; AF_INET INADDR_ANY
|
||
(socket:listen socket 10) ; Queue up to 10 requests.
|
||
(dynamic-wind
|
||
(lambda () #f)
|
||
(lambda ()
|
||
(do ((port (socket:accept socket) (socket:accept socket)))
|
||
(#f)
|
||
(let ((iport (duplicate-port port "r"))
|
||
(oport (duplicate-port port "w")))
|
||
(http:serve-query build:serve iport oport)
|
||
(close-port iport)
|
||
(close-port oport))
|
||
(close-port port)))
|
||
(lambda () (close-port socket))))
|
||
|
||
- Function: cgi:serve-query serve-proc
|
||
reads the "URI" and "query-string" from `(current-input-port)'.
|
||
If the query is a valid `"POST"' or `"GET"' query, then
|
||
`cgi:serve-query' calls SERVE-PROC with three arguments, the
|
||
REQUEST-LINE, QUERY-STRING, and HEADER-ALIST. Otherwise,
|
||
`cgi:serve-query' calls SERVE-PROC with the REQUEST-LINE, #f, and
|
||
HEADER-ALIST.
|
||
|
||
If SERVE-PROC returns a string, it is sent to
|
||
`(current-input-port)'. If SERVE-PROC returns a list, then an
|
||
error page with number 525 and strings from the list. If
|
||
SERVE-PROC returns #f, then a `Bad Request' (400) page is sent to
|
||
`(current-input-port)'.
|
||
|
||
Otherwise, `cgi:serve-query' replies (to `(current-input-port)')
|
||
with appropriate HTML describing the problem.
|
||
|
||
- Function: make-query-alist-command-server rdb command-table |
|
||
- Function: make-query-alist-command-server rdb command-table #t |
|
||
Returns a procedure of one argument. When that procedure is called
|
||
with a QUERY-ALIST (as returned by `uri:decode-query', the value |
|
||
of the `*command*' association will be the command invoked in |
|
||
COMMAND-TABLE. If `*command*' is not in the QUERY-ALIST then the |
|
||
value of `*suggest*' is tried. If neither name is in the |
|
||
QUERY-ALIST, then the literal value `*default*' is tried in |
|
||
COMMAND-TABLE. |
|
||
|
|
||
If optional third argument is non-false, then the command is called |
|
||
with just the parameter-list; otherwise, command is called with the |
|
||
arguments described in its table. |
|
||
|
|
||
|
||
File: slib.info, Node: URI, Next: Printing Scheme, Prev: HTTP and CGI, Up: Textual Conversion Packages
|
||
|
|
||
URI |
|
||
=== |
|
||
|
|
||
`(require 'uri)' |
|
||
|
|
||
Implements "Uniform Resource Identifiers" (URI) as described in RFC |
|
||
2396. |
|
||
|
|
||
- Function: make-uri |
|
||
- Function: make-uri fragment |
|
||
- Function: make-uri query fragment |
|
||
- Function: make-uri path query fragment |
|
||
- Function: make-uri authority path query fragment |
|
||
- Function: make-uri scheme authority path query fragment |
|
||
Returns a Uniform Resource Identifier string from component |
|
||
arguments. |
|
||
|
|
||
- Function: html:anchor name |
|
||
Returns a string which defines this location in the (HTML) file as |
|
||
NAME. The hypertext `<A HREF="#NAME">' will link to this point. |
|
||
|
|
||
(html:anchor "(section 7)") |
|
||
=> |
|
||
"<A NAME=\"(section%207)\"></A>" |
|
||
|
|
||
- Function: html:link uri highlighted |
|
||
Returns a string which links the HIGHLIGHTED text to URI. |
|
||
|
|
||
(html:link (make-uri "(section 7)") "section 7") |
|
||
=> |
|
||
"<A HREF=\"#(section%207)\">section 7</A>" |
|
||
|
|
||
- Function: html:base uri |
|
||
Returns a string specifying the "base" URI of a document, for |
|
||
inclusion in the HEAD of the document (*note head: HTML.). |
|
||
|
|
||
- Function: html:isindex prompt |
|
||
Returns a string specifying the search PROMPT of a document, for |
|
||
inclusion in the HEAD of the document (*note head: HTML.). |
|
||
|
|
||
- Function: uri->tree uri-reference base-tree ... |
|
||
Returns a list of 5 elements corresponding to the parts (SCHEME |
|
||
AUTHORITY PATH QUERY FRAGMENT) of string URI-REFERENCE. Elements |
|
||
corresponding to absent parts are #f. |
|
||
|
|
||
The PATH is a list of strings. If the first string is empty, then |
|
||
the path is absolute; otherwise relative. |
|
||
|
|
||
If the AUTHORITY component is a "Server-based Naming Authority", |
|
||
then it is a list of the USERINFO, HOST, and PORT strings (or #f). |
|
||
For other types of AUTHORITY components the AUTHORITY will be a |
|
||
string. |
|
||
|
|
||
(uri->tree "http://www.ics.uci.edu/pub/ietf/uri/#Related") |
|
||
=> |
|
||
(http "www.ics.uci.edu" ("" "pub" "ietf" "uri" "") #f "Related") |
|
||
|
|
||
`uric:' prefixes indicate procedures dealing with URI-components. |
|
||
|
|
||
- Function: uric:encode uri-component allows |
|
||
Returns a copy of the string URI-COMPONENT in which all "unsafe" |
|
||
octets (as defined in RFC 2396) have been `%' "escaped". |
|
||
`uric:decode' decodes strings encoded by `uric:encode'. |
|
||
|
|
||
- Function: uric:decode uri-component |
|
||
Returns a copy of the string URI-COMPONENT in which each `%' |
|
||
escaped characters in URI-COMPONENT is replaced with the character |
|
||
it encodes. This routine is useful for showing URI contents on |
|
||
error pages. |
|
||
|
||
|
||
File: slib.info, Node: Printing Scheme, Next: Time and Date, Prev: URI, Up: Textual Conversion Packages
|
||
|
|
||
Printing Scheme
|
||
===============
|
||
|
||
* Menu:
|
||
|
||
* Generic-Write:: 'generic-write
|
||
* Object-To-String:: 'object->string
|
||
* Pretty-Print:: 'pretty-print, 'pprint-file
|
||
|
||
|
||
File: slib.info, Node: Generic-Write, Next: Object-To-String, Prev: Printing Scheme, Up: Printing Scheme
|
||
|
||
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: Object-To-String, Next: Pretty-Print, Prev: Generic-Write, Up: Printing Scheme
|
||
|
||
Object-To-String
|
||
----------------
|
||
|
||
`(require 'object->string)'
|
||
|
||
- Function: object->string obj
|
||
Returns the textual representation of OBJ as a string.
|
||
|
||
- Function: object->limited-string obj limit
|
||
Returns the textual representation of OBJ as a string of length at
|
||
most LIMIT.
|
||
|
||
|
||
File: slib.info, Node: Pretty-Print, Prev: Object-To-String, Up: Printing Scheme
|
||
|
||
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))
|
||
|
||
- Procedure: pretty-print->string obj |
|
||
- Procedure: pretty-print->string obj width |
|
||
Returns the string of OBJ `pretty-print'ed in WIDTH columns. If |
|
||
WIDTH is not specified, `(output-port-width)' is used. |
|
||
|
|
||
Example: |
|
||
(pretty-print->string '((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)) |
|
||
" |
|
||
(pretty-print->string '((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)) |
|
||
16) |
|
||
=> |
|
||
"((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")
|
||
|
||
|
||
File: slib.info, Node: Time and Date, Next: Vector Graphics, Prev: Printing Scheme, Up: Textual Conversion Packages
|
||
|
||
Time and Date
|
||
=============
|
||
|
||
* Menu:
|
||
|
||
* Time Zone::
|
||
* Posix Time:: 'posix-time
|
||
* Common-Lisp Time:: 'common-lisp-time
|
||
|
||
If `(provided? 'current-time)':
|
||
|
||
The procedures `current-time', `difftime', and `offset-time' deal with
|
||
a "calendar time" datatype which may or may not be disjoint from other
|
||
Scheme datatypes.
|
||
|
||
- Function: current-time
|
||
Returns the time since 00:00:00 GMT, January 1, 1970, measured in
|
||
seconds. Note that the reference time is different from the
|
||
reference time for `get-universal-time' in *Note Common-Lisp
|
||
Time::.
|
||
|
||
- Function: difftime caltime1 caltime0
|
||
Returns the difference (number of seconds) between twe calendar
|
||
times: CALTIME1 - CALTIME0. CALTIME0 may also be a number.
|
||
|
||
- Function: offset-time caltime offset
|
||
Returns the calendar time of CALTIME offset by OFFSET number of
|
||
seconds `(+ caltime offset)'.
|
||
|
||
|
||
File: slib.info, Node: Time Zone, Next: Posix Time, Prev: Time and Date, Up: Time and Date
|
||
|
||
Time Zone
|
||
---------
|
||
|
||
(require 'time-zone)
|
||
|
||
- Data Format: TZ-string
|
||
POSIX standards specify several formats for encoding time-zone
|
||
rules.
|
||
|
||
:<pathname>
|
||
If the first character of <pathname> is `/', then <pathname>
|
||
specifies the absolute pathname of a tzfile(5) format
|
||
time-zone file. Otherwise, <pathname> is interpreted as a
|
||
pathname within TZFILE:VICINITY (/usr/lib/zoneinfo/) naming a
|
||
tzfile(5) format time-zone file.
|
||
|
||
<std><offset>
|
||
The string <std> consists of 3 or more alphabetic characters.
|
||
<offset> specifies the time difference from GMT. The <offset>
|
||
is positive if the local time zone is west of the Prime
|
||
Meridian and negative if it is east. <offset> can be the
|
||
number of hours or hours and minutes (and optionally seconds)
|
||
separated by `:'. For example, `-4:30'.
|
||
|
||
<std><offset><dst>
|
||
<dst> is the at least 3 alphabetic characters naming the local
|
||
daylight-savings-time.
|
||
|
||
<std><offset><dst><doffset>
|
||
<doffset> specifies the offset from the Prime Meridian when
|
||
daylight-savings-time is in effect.
|
||
|
||
The non-tzfile formats can optionally be followed by transition
|
||
times specifying the day and time when a zone changes from
|
||
standard to daylight-savings and back again.
|
||
|
||
,<date>/<time>,<date>/<time>
|
||
The <time>s are specified like the <offset>s above, except
|
||
that leading `+' and `-' are not allowed.
|
||
|
||
Each <date> has one of the formats:
|
||
|
||
J<day>
|
||
specifies the Julian day with <day> between 1 and 365.
|
||
February 29 is never counted and cannot be referenced.
|
||
|
||
<day>
|
||
This specifies the Julian day with n between 0 and 365.
|
||
February 29 is counted in leap years and can be
|
||
specified.
|
||
|
||
M<month>.<week>.<day>
|
||
This specifies day <day> (0 <= <day> <= 6) of week
|
||
<week> (1 <= <week> <= 5) of month <month> (1 <= <month>
|
||
<= 12). Week 1 is the first week in which day d occurs
|
||
and week 5 is the last week in which day <day> occurs.
|
||
Day 0 is a Sunday.
|
||
|
||
|
||
- Data Type: time-zone
|
||
is a datatype encoding how many hours from Greenwich Mean Time the
|
||
local time is, and the "Daylight Savings Time" rules for changing
|
||
it.
|
||
|
||
- Function: time-zone TZ-string
|
||
Creates and returns a time-zone object specified by the string
|
||
TZ-STRING. If `time-zone' cannot interpret TZ-STRING, `#f' is
|
||
returned.
|
||
|
||
- Function: tz:params caltime tz
|
||
TZ is a time-zone object. `tz:params' returns a list of three
|
||
items:
|
||
0. An integer. 0 if standard time is in effect for timezone TZ
|
||
at CALTIME; 1 if daylight savings time is in effect for
|
||
timezone TZ at CALTIME.
|
||
|
||
1. The number of seconds west of the Prime Meridian timezone TZ
|
||
is at CALTIME.
|
||
|
||
2. The name for timezone TZ at CALTIME.
|
||
|
||
`tz:params' is unaffected by the default timezone; inquiries can be
|
||
made of any timezone at any calendar time.
|
||
|
||
|
||
The rest of these procedures and variables are provided for POSIX
|
||
compatability. Because of shared state they are not thread-safe.
|
||
|
||
- Function: tzset
|
||
Returns the default time-zone.
|
||
|
||
- Function: tzset tz
|
||
Sets (and returns) the default time-zone to TZ.
|
||
|
||
- Function: tzset TZ-string
|
||
Sets (and returns) the default time-zone to that specified by
|
||
TZ-STRING.
|
||
|
||
`tzset' also sets the variables *TIMEZONE*, DAYLIGHT?, and TZNAME.
|
||
This function is automatically called by the time conversion
|
||
procedures which depend on the time zone (*note Time and Date::).
|
||
|
||
- Variable: *timezone*
|
||
Contains the difference, in seconds, between Greenwich Mean Time
|
||
and local standard time (for example, in the U.S. Eastern time
|
||
zone (EST), timezone is 5*60*60). `*timezone*' is initialized by
|
||
`tzset'.
|
||
|
||
- Variable: daylight?
|
||
is `#t' if the default timezone has rules for "Daylight Savings
|
||
Time". _Note:_ DAYLIGHT? does not tell you when Daylight Savings
|
||
Time is in effect, just that the default zone sometimes has
|
||
Daylight Savings Time.
|
||
|
||
- Variable: tzname
|
||
is a vector of strings. Index 0 has the abbreviation for the
|
||
standard timezone; If DAYLIGHT?, then index 1 has the abbreviation
|
||
for the Daylight Savings timezone.
|
||
|
||
|
||
File: slib.info, Node: Posix Time, Next: Common-Lisp Time, Prev: Time Zone, Up: Time and Date
|
||
|
||
Posix Time
|
||
----------
|
||
|
||
(require 'posix-time)
|
||
|
||
- Data Type: Calendar-Time
|
||
is a datatype encapsulating time.
|
||
|
||
- Data Type: Coordinated Universal Time
|
||
(abbreviated "UTC") is a vector of integers representing time:
|
||
|
||
0. seconds (0 - 61)
|
||
|
||
1. minutes (0 - 59)
|
||
|
||
2. hours since midnight (0 - 23)
|
||
|
||
3. day of month (1 - 31)
|
||
|
||
4. month (0 - 11). Note difference from
|
||
`decode-universal-time'.
|
||
|
||
5. the number of years since 1900. Note difference from
|
||
`decode-universal-time'.
|
||
|
||
6. day of week (0 - 6)
|
||
|
||
7. day of year (0 - 365)
|
||
|
||
8. 1 for daylight savings, 0 for regular time
|
||
|
||
- Function: gmtime caltime
|
||
Converts the calendar time CALTIME to UTC and returns it.
|
||
|
||
- Function: localtime caltime tz
|
||
Returns CALTIME converted to UTC relative to timezone TZ.
|
||
|
||
- Function: localtime caltime
|
||
converts the calendar time CALTIME to a vector of integers
|
||
expressed relative to the user's time zone. `localtime' sets the
|
||
variable *TIMEZONE* with the difference between Coordinated
|
||
Universal Time (UTC) and local standard time in seconds (*note
|
||
tzset: Time Zone.).
|
||
|
||
|
||
- Function: gmktime univtime
|
||
Converts a vector of integers in GMT Coordinated Universal Time
|
||
(UTC) format to a calendar time.
|
||
|
||
- Function: mktime univtime
|
||
Converts a vector of integers in local Coordinated Universal Time
|
||
(UTC) format to a calendar time.
|
||
|
||
- Function: mktime univtime tz
|
||
Converts a vector of integers in Coordinated Universal Time (UTC)
|
||
format (relative to time-zone TZ) to calendar time.
|
||
|
||
- Function: asctime univtime
|
||
Converts the vector of integers CALTIME in Coordinated Universal
|
||
Time (UTC) format into a string of the form `"Wed Jun 30 21:49:08
|
||
1993"'.
|
||
|
||
- Function: gtime caltime
|
||
- Function: ctime caltime
|
||
- Function: ctime caltime tz
|
||
Equivalent to `(asctime (gmtime CALTIME))', `(asctime (localtime
|
||
CALTIME))', and `(asctime (localtime CALTIME TZ))', respectively.
|
||
|
||
|
||
File: slib.info, Node: Common-Lisp Time, Prev: Posix Time, Up: Time and Date
|
||
|
||
Common-Lisp Time
|
||
----------------
|
||
|
||
- Function: get-decoded-time
|
||
Equivalent to `(decode-universal-time (get-universal-time))'.
|
||
|
||
- Function: get-universal-time
|
||
Returns the current time as "Universal Time", number of seconds
|
||
since 00:00:00 Jan 1, 1900 GMT. Note that the reference time is
|
||
different from `current-time'.
|
||
|
||
- Function: decode-universal-time univtime
|
||
Converts UNIVTIME to "Decoded Time" format. Nine values are
|
||
returned:
|
||
0. seconds (0 - 61)
|
||
|
||
1. minutes (0 - 59)
|
||
|
||
2. hours since midnight
|
||
|
||
3. day of month
|
||
|
||
4. month (1 - 12). Note difference from `gmtime' and
|
||
`localtime'.
|
||
|
||
5. year (A.D.). Note difference from `gmtime' and `localtime'.
|
||
|
||
6. day of week (0 - 6)
|
||
|
||
7. #t for daylight savings, #f otherwise
|
||
|
||
8. hours west of GMT (-24 - +24)
|
||
|
||
Notice that the values returned by `decode-universal-time' do not
|
||
match the arguments to `encode-universal-time'.
|
||
|
||
- Function: encode-universal-time second minute hour date month year
|
||
- Function: encode-universal-time second minute hour date month year
|
||
time-zone
|
||
Converts the arguments in Decoded Time format to Universal Time
|
||
format. If TIME-ZONE is not specified, the returned time is
|
||
adjusted for daylight saving time. Otherwise, no adjustment is
|
||
performed.
|
||
|
||
Notice that the values returned by `decode-universal-time' do not
|
||
match the arguments to `encode-universal-time'.
|
||
|
||
|
||
File: slib.info, Node: Vector Graphics, Next: Schmooz, Prev: Time and Date, Up: Textual Conversion Packages
|
||
|
||
Vector Graphics
|
||
===============
|
||
|
||
* Menu:
|
||
|
||
* Tektronix Graphics Support::
|
||
|
||
|
||
File: slib.info, Node: Tektronix Graphics Support, Prev: Vector Graphics, Up: Vector Graphics
|
||
|
||
Tektronix Graphics Support
|
||
--------------------------
|
||
|
||
_Note:_ The Tektronix graphics support files need more work, and are
|
||
not complete.
|
||
|
||
Tektronix 4000 Series Graphics
|
||
..............................
|
||
|
||
The Tektronix 4000 series graphics protocol gives the user a 1024 by
|
||
1024 square drawing area. The origin is in the lower left corner of the
|
||
screen. Increasing y is up and increasing x is to the right.
|
||
|
||
The graphics control codes are sent over the current-output-port and
|
||
can be mixed with regular text and ANSI or other terminal control
|
||
sequences.
|
||
|
||
- Procedure: tek40:init
|
||
|
||
- Procedure: tek40:graphics
|
||
|
||
- Procedure: tek40:text
|
||
|
||
- Procedure: tek40:linetype linetype
|
||
|
||
- Procedure: tek40:move x y
|
||
|
||
- Procedure: tek40:draw x y
|
||
|
||
- Procedure: tek40:put-text x y str
|
||
|
||
- Procedure: tek40:reset
|
||
|
||
Tektronix 4100 Series Graphics
|
||
..............................
|
||
|
||
The graphics control codes are sent over the current-output-port and
|
||
can be mixed with regular text and ANSI or other terminal control
|
||
sequences.
|
||
|
||
- Procedure: tek41:init
|
||
|
||
- Procedure: tek41:reset
|
||
|
||
- Procedure: tek41:graphics
|
||
|
||
- Procedure: tek41:move x y
|
||
|
||
- Procedure: tek41:draw x y
|
||
|
||
- Procedure: tek41:point x y number
|
||
|
||
- Procedure: tek41:encode-x-y x y
|
||
|
||
- Procedure: tek41:encode-int number
|
||
|
||
|
||
File: slib.info, Node: Schmooz, Prev: Vector Graphics, Up: Textual Conversion Packages
|
||
|
||
Schmooz
|
||
=======
|
||
|
||
"Schmooz" is a simple, lightweight markup language for interspersing
|
||
Texinfo documentation with Scheme source code. Schmooz does not create
|
||
the top level Texinfo file; it creates `txi' files which can be
|
||
imported into the documentation using the Texinfo command `@include'.
|
||
|
||
`(require 'schmooz)' defines the function `schmooz', which is used to
|
||
process files. Files containing schmooz documentation should not
|
||
contain `(require 'schmooz)'.
|
||
|
||
- Procedure: schmooz filenamescm ...
|
||
FILENAMEscm should be a string ending with `scm' naming an
|
||
existing file containing Scheme source code. `schmooz' extracts
|
||
top-level comments containing schmooz commands from FILENAMEscm
|
||
and writes the converted Texinfo source to a file named
|
||
FILENAMEtxi.
|
||
|
||
- Procedure: schmooz filenametexi ...
|
||
- Procedure: schmooz filenametex ...
|
||
- Procedure: schmooz filenametxi ...
|
||
FILENAME should be a string naming an existing file containing
|
||
Texinfo source code. For every occurrence of the string `@include
|
||
FILENAMEtxi' within that file, `schmooz' calls itself with the
|
||
argument `FILENAMEscm'.
|
||
|
||
Schmooz comments are distinguished (from non-schmooz comments) by
|
||
their first line, which must start with an at-sign (@) preceded by one
|
||
or more semicolons (;). A schmooz comment ends at the first subsequent
|
||
line which does _not_ start with a semicolon. Currently schmooz
|
||
comments are recognized only at top level.
|
||
|
||
Schmooz comments are copied to the Texinfo output file with the
|
||
leading contiguous semicolons removed. Certain character sequences
|
||
starting with at-sign are treated specially. Others are copied
|
||
unchanged.
|
||
|
||
A schmooz comment starting with `@body' must be followed by a Scheme
|
||
definition. All comments between the `@body' line and the definition
|
||
will be included in a Texinfo definition, either a `@defun' or a
|
||
`@defvar', depending on whether a procedure or a variable is being
|
||
defined.
|
||
|
||
Within the text of that schmooz comment, at-sign followed by `0' will
|
||
be replaced by `@code{procedure-name}' if the following definition is
|
||
of a procedure; or `@var{variable}' if defining a variable.
|
||
|
||
An at-sign followed by a non-zero digit will expand to the variable
|
||
citation of that numbered argument: `@var{argument-name}'.
|
||
|
||
If more than one definition follows a `@body' comment line without an
|
||
intervening blank or comment line, then those definitions will be
|
||
included in the same Texinfo definition using `@defvarx' or `@defunx',
|
||
depending on whether the first definition is of a variable or of a
|
||
procedure.
|
||
|
||
Schmooz can figure out whether a definition is of a procedure if it
|
||
is of the form:
|
||
|
||
`(define (<identifier> <arg> ...) <expression>)'
|
||
|
||
or if the left hand side of the definition is some form ending in a
|
||
lambda expression. Obviously, it can be fooled. In order to force
|
||
recognition of a procedure definition, start the documentation with
|
||
`@args' instead of `@body'. `@args' should be followed by the argument
|
||
list of the function being defined, which may be enclosed in
|
||
parentheses and delimited by whitespace, (as in Scheme), enclosed in
|
||
braces and separated by commas, (as in Texinfo), or consist of the
|
||
remainder of the line, separated by whitespace.
|
||
|
||
For example:
|
||
|
||
;;@args arg1 args ...
|
||
;;@0 takes argument @1 and any number of @2
|
||
(define myfun (some-function-returning-magic))
|
||
|
||
Will result in:
|
||
|
||
@defun myfun arg1 args @dots{}
|
||
|
||
@code{myfun} takes argument @var{arg1} and any number of @var{args}
|
||
@end defun
|
||
|
||
`@args' may also be useful for indicating optional arguments by name.
|
||
If `@args' occurs inside a schmooz comment section, rather than at the
|
||
beginning, then it will generate a `@defunx' line with the arguments
|
||
supplied.
|
||
|
||
If the first at-sign in a schmooz comment is immediately followed by
|
||
whitespace, then the comment will be expanded to whatever follows that
|
||
whitespace. If the at-sign is followed by a non-whitespace character
|
||
then the at-sign will be included as the first character of the
|
||
expansion. This feature is intended to make it easy to include Texinfo
|
||
directives in schmooz comments.
|
||
|
||
|
||
File: slib.info, Node: Mathematical Packages, Next: Database Packages, Prev: Textual Conversion Packages, Up: Top
|
||
|
||
Mathematical Packages
|
||
*********************
|
||
|
||
* Menu:
|
||
|
||
* Bit-Twiddling:: 'logical
|
||
* Modular Arithmetic:: 'modular
|
||
* Prime Numbers:: 'factor
|
||
* Random Numbers:: 'random
|
||
* Fast Fourier Transform:: 'fft
|
||
* Cyclic Checksum:: 'make-crc
|
||
* Plotting:: 'charplot
|
||
* Root Finding:: 'root
|
||
* Minimizing:: 'minimize
|
||
* Commutative Rings:: 'commutative-ring
|
||
* Determinant:: 'determinant
|
||
|
||
|
||
File: slib.info, Node: Bit-Twiddling, Next: Modular Arithmetic, Prev: Mathematical Packages, Up: Mathematical Packages
|
||
|
||
Bit-Twiddling
|
||
=============
|
||
|
||
`(require 'logical)'
|
||
|
||
The bit-twiddling functions are made available through the use of the
|
||
`logical' package. `logical' is loaded by inserting `(require
|
||
'logical)' before the code that uses these functions. These functions
|
||
behave as though operating on integers in two's-complement
|
||
representation.
|
||
|
||
Bitwise Operations
|
||
------------------
|
||
|
||
- Function: logand n1 n1
|
||
Returns the integer which is the bit-wise AND of the two integer
|
||
arguments.
|
||
|
||
Example:
|
||
(number->string (logand #b1100 #b1010) 2)
|
||
=> "1000"
|
||
|
||
- Function: logior n1 n2
|
||
Returns the integer which is the bit-wise OR of the two integer
|
||
arguments.
|
||
|
||
Example:
|
||
(number->string (logior #b1100 #b1010) 2)
|
||
=> "1110"
|
||
|
||
- Function: logxor n1 n2
|
||
Returns the integer which is the bit-wise XOR of the two integer
|
||
arguments.
|
||
|
||
Example:
|
||
(number->string (logxor #b1100 #b1010) 2)
|
||
=> "110"
|
||
|
||
- Function: lognot n
|
||
Returns the integer which is the 2s-complement of the integer
|
||
argument.
|
||
|
||
Example:
|
||
(number->string (lognot #b10000000) 2)
|
||
=> "-10000001"
|
||
(number->string (lognot #b0) 2)
|
||
=> "-1"
|
||
|
||
- Function: bitwise-if mask n0 n1
|
||
Returns an integer composed of some bits from integer N0 and some
|
||
from integer N1. A bit of the result is taken from N0 if the
|
||
corresponding bit of integer MASK is 1 and from N1 if that bit of
|
||
MASK is 0.
|
||
|
||
- Function: logtest j k
|
||
(logtest j k) == (not (zero? (logand j k)))
|
||
|
||
(logtest #b0100 #b1011) => #f
|
||
(logtest #b0100 #b0111) => #t
|
||
|
||
- Function: logcount n
|
||
Returns the number of bits in integer N. If integer is positive,
|
||
the 1-bits in its binary representation are counted. If negative,
|
||
the 0-bits in its two's-complement binary representation are
|
||
counted. If 0, 0 is returned.
|
||
|
||
Example:
|
||
(logcount #b10101010)
|
||
=> 4
|
||
(logcount 0)
|
||
=> 0
|
||
(logcount -2)
|
||
=> 1
|
||
|
||
Bit Within Word
|
||
---------------
|
||
|
||
- Function: logbit? index j
|
||
(logbit? index j) == (logtest (integer-expt 2 index) j)
|
||
|
||
(logbit? 0 #b1101) => #t
|
||
(logbit? 1 #b1101) => #f
|
||
(logbit? 2 #b1101) => #t
|
||
(logbit? 3 #b1101) => #t
|
||
(logbit? 4 #b1101) => #f
|
||
|
||
- Function: copy-bit index from bit
|
||
Returns an integer the same as FROM except in the INDEXth bit,
|
||
which is 1 if BIT is `#t' and 0 if BIT is `#f'.
|
||
|
||
Example:
|
||
(number->string (copy-bit 0 0 #t) 2) => "1"
|
||
(number->string (copy-bit 2 0 #t) 2) => "100"
|
||
(number->string (copy-bit 2 #b1111 #f) 2) => "1011"
|
||
|
||
Fields of Bits
|
||
--------------
|
||
|
||
- Function: bit-field n start end
|
||
Returns the integer composed of the START (inclusive) through END
|
||
(exclusive) bits of N. The STARTth bit becomes the 0-th bit in
|
||
the result.
|
||
|
||
This function was called `bit-extract' in previous versions of
|
||
SLIB.
|
||
|
||
Example:
|
||
(number->string (bit-field #b1101101010 0 4) 2)
|
||
=> "1010"
|
||
(number->string (bit-field #b1101101010 4 9) 2)
|
||
=> "10110"
|
||
|
||
- Function: copy-bit-field to start end from
|
||
Returns an integer the same as TO except possibly in the START
|
||
(inclusive) through END (exclusive) bits, which are the same as
|
||
those of FROM. The 0-th bit of FROM becomes the STARTth bit of
|
||
the result.
|
||
|
||
Example:
|
||
(number->string (copy-bit-field #b1101101010 0 4 0) 2)
|
||
=> "1101100000"
|
||
(number->string (copy-bit-field #b1101101010 0 4 -1) 2)
|
||
=> "1101101111"
|
||
|
||
- Function: ash int count
|
||
Returns an integer equivalent to `(inexact->exact (floor (* INT
|
||
(expt 2 COUNT))))'.
|
||
|
||
Example:
|
||
(number->string (ash #b1 3) 2)
|
||
=> "1000"
|
||
(number->string (ash #b1010 -1) 2)
|
||
=> "101"
|
||
|
||
- Function: integer-length n
|
||
Returns the number of bits neccessary to represent N.
|
||
|
||
Example:
|
||
(integer-length #b10101010)
|
||
=> 8
|
||
(integer-length 0)
|
||
=> 0
|
||
(integer-length #b1111)
|
||
=> 4
|
||
|
||
- Function: integer-expt n k
|
||
Returns N raised to the non-negative integer exponent K.
|
||
|
||
Example:
|
||
(integer-expt 2 5)
|
||
=> 32
|
||
(integer-expt -3 3)
|
||
=> -27
|
||
|
||
|
||
File: slib.info, Node: Modular Arithmetic, Next: Prime Numbers, Prev: Bit-Twiddling, Up: Mathematical Packages
|
||
|
||
Modular Arithmetic
|
||
==================
|
||
|
||
`(require 'modular)'
|
||
|
||
- Function: extended-euclid n1 n2
|
||
Returns a list of 3 integers `(d x y)' such that d = gcd(N1, N2) =
|
||
N1 * x + N2 * y.
|
||
|
||
- Function: symmetric:modulus n
|
||
Returns `(quotient (+ -1 n) -2)' for positive odd integer N.
|
||
|
||
- Function: modulus->integer modulus
|
||
Returns the non-negative integer characteristic of the ring formed
|
||
when MODULUS is used with `modular:' procedures.
|
||
|
||
- Function: modular:normalize modulus n
|
||
Returns the integer `(modulo N (modulus->integer MODULUS))' in the
|
||
representation specified by MODULUS.
|
||
|
||
The rest of these functions assume normalized arguments; That is, the
|
||
arguments are constrained by the following table:
|
||
|
||
For all of these functions, if the first argument (MODULUS) is:
|
||
`positive?'
|
||
Work as before. The result is between 0 and MODULUS.
|
||
|
||
`zero?'
|
||
The arguments are treated as integers. An integer is returned.
|
||
|
||
`negative?'
|
||
The arguments and result are treated as members of the integers
|
||
modulo `(+ 1 (* -2 MODULUS))', but with "symmetric"
|
||
representation; i.e. `(<= (- MODULUS) N MODULUS)'.
|
||
|
||
If all the arguments are fixnums the computation will use only fixnums.
|
||
|
||
- Function: modular:invertable? modulus k
|
||
Returns `#t' if there exists an integer n such that K * n == 1 mod
|
||
MODULUS, and `#f' otherwise.
|
||
|
||
- Function: modular:invert modulus k2
|
||
Returns an integer n such that 1 = (n * K2) mod MODULUS. If K2
|
||
has no inverse mod MODULUS an error is signaled.
|
||
|
||
- Function: modular:negate modulus k2
|
||
Returns (-K2) mod MODULUS.
|
||
|
||
- Function: modular:+ modulus k2 k3
|
||
Returns (K2 + K3) mod MODULUS.
|
||
|
||
- Function: modular:- modulus k2 k3
|
||
Returns (K2 - K3) mod MODULUS.
|
||
|
||
- Function: modular:* modulus k2 k3
|
||
Returns (K2 * K3) mod MODULUS.
|
||
|
||
The Scheme code for `modular:*' with negative MODULUS is not
|
||
completed for fixnum-only implementations.
|
||
|
||
- Function: modular:expt modulus k2 k3
|
||
Returns (K2 ^ K3) mod MODULUS.
|
||
|
||
|
||
File: slib.info, Node: Prime Numbers, Next: Random Numbers, Prev: Modular Arithmetic, Up: Mathematical Packages
|
||
|
||
Prime Numbers
|
||
=============
|
||
|
||
`(require 'factor)'
|
||
|
||
- Variable: prime:prngs
|
||
PRIME:PRNGS is the random-state (*note Random Numbers::) used by
|
||
these procedures. If you call these procedures from more than one
|
||
thread (or from interrupt), `random' may complain about reentrant
|
||
calls.
|
||
_Note:_ The prime test and generation procedures implement (or use)
|
||
the Solovay-Strassen primality test. See
|
||
|
||
* Robert Solovay and Volker Strassen, `A Fast Monte-Carlo Test for
|
||
Primality', SIAM Journal on Computing, 1977, pp 84-85.
|
||
|
||
- Function: jacobi-symbol p q
|
||
Returns the value (+1, -1, or 0) of the Jacobi-Symbol of exact
|
||
non-negative integer P and exact positive odd integer Q.
|
||
|
||
- Variable: prime:trials
|
||
PRIME:TRIALS the maxinum number of iterations of Solovay-Strassen
|
||
that will be done to test a number for primality.
|
||
|
||
- Function: prime? n
|
||
Returns `#f' if N is composite; `#t' if N is prime. There is a
|
||
slight chance `(expt 2 (- prime:trials))' that a composite will
|
||
return `#t'.
|
||
|
||
- Function: primes< start count
|
||
Returns a list of the first COUNT prime numbers less than START.
|
||
If there are fewer than COUNT prime numbers less than START, then
|
||
the returned list will have fewer than START elements.
|
||
|
||
- Function: primes> start count
|
||
Returns a list of the first COUNT prime numbers greater than START.
|
||
|
||
- Function: factor k
|
||
Returns a list of the prime factors of K. The order of the
|
||
factors is unspecified. In order to obtain a sorted list do
|
||
`(sort! (factor K) <)'.
|
||
|
||
|
||
File: slib.info, Node: Random Numbers, Next: Fast Fourier Transform, Prev: Prime Numbers, Up: Mathematical Packages
|
||
|
||
Random Numbers
|
||
==============
|
||
|
||
`(require 'random)'
|
||
|
||
A pseudo-random number generator is only as good as the tests it
|
||
passes. George Marsaglia of Florida State University developed a
|
||
battery of tests named "DIEHARD"
|
||
(<http://stat.fsu.edu/~geo/diehard.html>). `diehard.c' has a bug which
|
||
the patch
|
||
<http://swissnet.ai.mit.edu/ftpdir/users/jaffer/diehard.c.pat> corrects.
|
||
|
||
SLIB's new PRNG generates 8 bits at a time. With the degenerate seed
|
||
`0', the numbers generated pass DIEHARD; but when bits are combined
|
||
from sequential bytes, tests fail. With the seed
|
||
`http://swissnet.ai.mit.edu/~jaffer/SLIB.html', all of those tests pass.
|
||
|
||
- Function: random n
|
||
- Function: random n state
|
||
Accepts a positive integer or real N and returns a number of the
|
||
same type between zero (inclusive) and N (exclusive). The values
|
||
returned by `random' are uniformly distributed from 0 to N.
|
||
|
||
The optional argument STATE must be of the type returned by
|
||
`(seed->random-state)' or `(make-random-state)'. It defaults to
|
||
the value of the variable `*random-state*'. This object is used
|
||
to maintain the state of the pseudo-random-number generator and is
|
||
altered as a side effect of calls to `random'.
|
||
|
||
- Variable: *random-state*
|
||
Holds a data structure that encodes the internal state of the
|
||
random-number generator that `random' uses by default. The nature
|
||
of this data structure is implementation-dependent. It may be
|
||
printed out and successfully read back in, but may or may not
|
||
function correctly as a random-number state object in another
|
||
implementation.
|
||
|
||
- Function: copy-random-state state
|
||
Returns a new copy of argument STATE.
|
||
|
||
- Function: copy-random-state
|
||
Returns a new copy of `*random-state*'.
|
||
|
||
- Function: seed->random-state seed
|
||
Returns a new object of type suitable for use as the value of the
|
||
variable `*random-state*' or as a second argument to `random'.
|
||
The number or string SEED is used to initialize the state. If
|
||
`seed->random-state' is called twice with arguments which are
|
||
`equal?', then the returned data structures will be `equal?'.
|
||
Calling `seed->random-state' with unequal arguments will nearly
|
||
always return unequal states.
|
||
|
||
- Function: make-random-state
|
||
- Function: make-random-state obj
|
||
Returns a new object of type suitable for use as the value of the
|
||
variable `*random-state*' or as a second argument to `random'. If
|
||
the optional argument OBJ is given, it should be a printable
|
||
Scheme object; the first 50 characters of its printed
|
||
representation will be used as the seed. Otherwise the value of
|
||
`*random-state*' is used as the seed.
|
||
|
||
If inexact numbers are supported by the Scheme implementation,
|
||
`randinex.scm' will be loaded as well. `randinex.scm' contains
|
||
procedures for generating inexact distributions.
|
||
|
||
- Function: random:uniform
|
||
- Function: random:uniform state
|
||
Returns an uniformly distributed inexact real random number in the
|
||
range between 0 and 1.
|
||
|
||
- Function: random:exp
|
||
- Function: random:exp state
|
||
Returns an inexact real in an exponential distribution with mean
|
||
1. For an exponential distribution with mean U use
|
||
`(* U (random:exp))'.
|
||
|
||
- Function: random:normal
|
||
- Function: random:normal state
|
||
Returns an inexact real in a normal distribution with mean 0 and
|
||
standard deviation 1. For a normal distribution with mean M and
|
||
standard deviation D use `(+ M (* D (random:normal)))'.
|
||
|
||
- Function: random:normal-vector! vect
|
||
- Function: random:normal-vector! vect state
|
||
Fills VECT with inexact real random numbers which are independent
|
||
and standard normally distributed (i.e., with mean 0 and variance
|
||
1).
|
||
|
||
- Function: random:hollow-sphere! vect
|
||
- Function: random:hollow-sphere! vect state
|
||
Fills VECT with inexact real random numbers the sum of whose
|
||
squares is equal to 1.0. Thinking of VECT as coordinates in space
|
||
of dimension n = `(vector-length VECT)', the coordinates are
|
||
uniformly distributed over the surface of the unit n-shere.
|
||
|
||
- Function: random:solid-sphere! vect
|
||
- Function: random:solid-sphere! vect state
|
||
Fills VECT with inexact real random numbers the sum of whose
|
||
squares is less than 1.0. Thinking of VECT as coordinates in
|
||
space of dimension N = `(vector-length VECT)', the coordinates are
|
||
uniformly distributed within the unit N-shere. The sum of the
|
||
squares of the numbers is returned.
|
||
|
||
|
||
File: slib.info, Node: Fast Fourier Transform, Next: Cyclic Checksum, Prev: Random Numbers, Up: Mathematical Packages
|
||
|
||
Fast Fourier Transform
|
||
======================
|
||
|
||
`(require 'fft)'
|
||
|
||
- Function: fft array
|
||
ARRAY is an array of `(expt 2 n)' numbers. `fft' returns an array
|
||
of complex numbers comprising the "Discrete Fourier Transform" of
|
||
ARRAY.
|
||
|
||
- Function: fft-1 array
|
||
`fft-1' returns an array of complex numbers comprising the inverse
|
||
Discrete Fourier Transform of ARRAY.
|
||
|
||
`(fft-1 (fft ARRAY))' will return an array of values close to ARRAY.
|
||
|
||
(fft '#(1 0+i -1 0-i 1 0+i -1 0-i)) =>
|
||
|
||
#(0.0 0.0 0.0+628.0783185208527e-18i 0.0
|
||
0.0 0.0 8.0-628.0783185208527e-18i 0.0)
|
||
|
||
(fft-1 '#(0 0 0 0 0 0 8 0)) =>
|
||
|
||
#(1.0 -61.23031769111886e-18+1.0i -1.0 61.23031769111886e-18-1.0i
|
||
1.0 -61.23031769111886e-18+1.0i -1.0 61.23031769111886e-18-1.0i)
|
||
|
||
|
||
File: slib.info, Node: Cyclic Checksum, Next: Plotting, Prev: Fast Fourier Transform, Up: Mathematical Packages
|
||
|
||
Cyclic Checksum
|
||
===============
|
||
|
||
`(require 'make-crc)'
|
||
|
||
- Function: make-port-crc
|
||
- Function: make-port-crc degree |
|
||
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.
|
||
|
||
- Function: make-port-crc generator |
|
||
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 value of GENERATOR must be larger than 127. |
|
||
|
|
||
- Function: make-port-crc degree generator |
|
||
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"))
|
||
|
||
=> 157103930 |
|
||
|
||
|
||
File: slib.info, Node: Plotting, Next: Root Finding, Prev: Cyclic Checksum, Up: Mathematical Packages
|
||
|
||
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|- **** |
|
||
| ** ** |
|
||
0.75|- * * |
|
||
| * * |
|
||
0.5|- * * |
|
||
| * |
|
||
0.25|- * |
|
||
| * * |
|
||
0|-------------------*--------------------------|
|
||
| * |
|
||
-0.25|- * * |
|
||
| * * |
|
||
-0.5|- * |
|
||
| * * |
|
||
-0.75|- * * |
|
||
| ** ** |
|
||
-1|- **** |
|
||
|____________:_____._____:_____._____:_________|
|
||
x 2 4 6
|
||
|
||
- Procedure: plot-function! func x1 x2
|
||
- Procedure: plot-function! func x1 x2 npts
|
||
Plots the function of one argument FUNC over the range X1 to X2.
|
||
If the optional integer argument NPTS is supplied, it specifies
|
||
the number of points to evaluate FUNC at.
|
||
|
||
|
||
File: slib.info, Node: Root Finding, Next: Minimizing, Prev: Plotting, Up: Mathematical Packages
|
||
|
||
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.
|
||
|
||
- Function: secant:find-root f x0 x1 prec
|
||
- Function: secant:find-bracketed-root f x0 x1 prec
|
||
Given a real valued procedure F and two real valued starting
|
||
points X0 and X1, 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 X0 and X1 are chosen such that they bracket a root, that is
|
||
(or (< (f x0) 0 (f x1))
|
||
(< (f x1) 0 (f x0)))
|
||
then the root returned will be between X0 and X1, and F will not
|
||
be passed an argument outside of that interval.
|
||
|
||
`secant:find-bracketed-root' will return `#f' unless X0 and X1
|
||
bracket a root.
|
||
|
||
The secant method is used until a bracketing interval is found, at
|
||
which point a modified regula falsi method is used.
|
||
|
||
If PREC is instead a negative integer, `secant:find-root' returns
|
||
the result of -PREC iterations.
|
||
|
||
If PREC is a procedure it should accept 5 arguments: X0 F0 X1 F1
|
||
and COUNT, where F0 will be `(f x0)', F1 `(f x1)', and COUNT the
|
||
number of iterations performed so far. PREC should return
|
||
non-false if the iteration should be stopped.
|
||
|
||
|
||
File: slib.info, Node: Minimizing, Next: Commutative Rings, Prev: Root Finding, Up: Mathematical Packages
|
||
|
||
Minimizing
|
||
==========
|
||
|
||
`(require 'minimize)'
|
||
|
||
The Golden Section Search (1) algorithm finds minima of functions which
|
||
are expensive to compute or for which derivatives are not available.
|
||
Although optimum for the general case, convergence is slow, requiring
|
||
nearly 100 iterations for the example (x^3-2x-5).
|
||
|
||
If the derivative is available, Newton-Raphson is probably a better
|
||
choice. If the function is inexpensive to compute, consider
|
||
approximating the derivative.
|
||
|
||
- Function: golden-section-search f x0 x1 prec
|
||
X_0 are X_1 real numbers. The (single argument) procedure F is
|
||
unimodal over the open interval (X_0, X_1). That is, there is
|
||
exactly one point in the interval for which the derivative of F is
|
||
zero.
|
||
|
||
`golden-section-search' returns a pair (X . F(X)) where F(X) is
|
||
the minimum. The PREC parameter is the stop criterion. If PREC
|
||
is a positive number, then the iteration continues until X is
|
||
within PREC from the true value. If PREC is a negative integer,
|
||
then the procedure will iterate -PREC times or until convergence.
|
||
If PREC is a procedure of seven arguments, X0, X1, A, B, FA, FB,
|
||
and COUNT, then the iterations will stop when the procedure
|
||
returns `#t'.
|
||
|
||
Analytically, the minimum of x^3-2x-5 is 0.816497.
|
||
(define func (lambda (x) (+ (* x (+ (* x x) -2)) -5)))
|
||
(golden-section-search func 0 1 (/ 10000))
|
||
==> (816.4883855245578e-3 . -6.0886621077391165)
|
||
(golden-section-search func 0 1 -5)
|
||
==> (819.6601125010515e-3 . -6.088637561916407)
|
||
(golden-section-search func 0 1
|
||
(lambda (a b c d e f g ) (= g 500)))
|
||
==> (816.4965933140557e-3 . -6.088662107903635)
|
||
|
||
---------- Footnotes ----------
|
||
|
||
(1) David Kahaner, Cleve Moler, and Stephen Nash `Numerical Methods
|
||
and Software' Prentice-Hall, 1989, ISBN 0-13-627258-4
|
||
|
||
|
||
File: slib.info, Node: Commutative Rings, Next: Determinant, Prev: Minimizing, Up: Mathematical Packages
|
||
|
||
Commutative Rings
|
||
=================
|
||
|
||
Scheme provides a consistent and capable set of numeric functions.
|
||
Inexacts implement a field; integers a commutative ring (and Euclidean
|
||
domain). This package allows one to use basic Scheme numeric functions
|
||
with symbols and non-numeric elements of commutative rings.
|
||
|
||
`(require 'commutative-ring)'
|
||
|
||
The "commutative-ring" package makes the procedures `+', `-', `*',
|
||
`/', and `^' "careful" in the sense that any non-numeric arguments they
|
||
do not reduce appear in the expression output. In order to see what
|
||
working with this package is like, self-set all the single letter
|
||
identifiers (to their corresponding symbols).
|
||
|
||
(define a 'a)
|
||
...
|
||
(define z 'z)
|
||
|
||
Or just `(require 'self-set)'. Now try some sample expressions:
|
||
|
||
(+ (+ a b) (- a b)) => (* a 2)
|
||
(* (+ a b) (+ a b)) => (^ (+ a b) 2)
|
||
(* (+ a b) (- a b)) => (* (+ a b) (- a b))
|
||
(* (- a b) (- a b)) => (^ (- a b) 2)
|
||
(* (- a b) (+ a b)) => (* (+ a b) (- a b))
|
||
(/ (+ a b) (+ c d)) => (/ (+ a b) (+ c d))
|
||
(^ (+ a b) 3) => (^ (+ a b) 3)
|
||
(^ (+ a 2) 3) => (^ (+ 2 a) 3)
|
||
|
||
Associative rules have been applied and repeated addition and
|
||
multiplication converted to multiplication and exponentiation.
|
||
|
||
We can enable distributive rules, thus expanding to sum of products
|
||
form:
|
||
(set! *ruleset* (combined-rulesets distribute* distribute/))
|
||
|
||
(* (+ a b) (+ a b)) => (+ (* 2 a b) (^ a 2) (^ b 2))
|
||
(* (+ a b) (- a b)) => (- (^ a 2) (^ b 2))
|
||
(* (- a b) (- a b)) => (- (+ (^ a 2) (^ b 2)) (* 2 a b))
|
||
(* (- a b) (+ a b)) => (- (^ a 2) (^ b 2))
|
||
(/ (+ a b) (+ c d)) => (+ (/ a (+ c d)) (/ b (+ c d)))
|
||
(/ (+ a b) (- c d)) => (+ (/ a (- c d)) (/ b (- c d)))
|
||
(/ (- a b) (- c d)) => (- (/ a (- c d)) (/ b (- c d)))
|
||
(/ (- a b) (+ c d)) => (- (/ a (+ c d)) (/ b (+ c d)))
|
||
(^ (+ a b) 3) => (+ (* 3 a (^ b 2)) (* 3 b (^ a 2)) (^ a 3) (^ b 3))
|
||
(^ (+ a 2) 3) => (+ 8 (* a 12) (* (^ a 2) 6) (^ a 3))
|
||
|
||
Use of this package is not restricted to simple arithmetic
|
||
expressions:
|
||
|
||
(require 'determinant)
|
||
|
||
(determinant '((a b c) (d e f) (g h i))) =>
|
||
(- (+ (* a e i) (* b f g) (* c d h)) (* a f h) (* b d i) (* c e g))
|
||
|
||
Currently, only `+', `-', `*', `/', and `^' support non-numeric
|
||
elements. Expressions with `-' are converted to equivalent expressions
|
||
without `-', so behavior for `-' is not defined separately. `/'
|
||
expressions are handled similarly.
|
||
|
||
This list might be extended to include `quotient', `modulo',
|
||
`remainder', `lcm', and `gcd'; but these work only for the more
|
||
restrictive Euclidean (Unique Factorization) Domain.
|
||
|
||
Rules and Rulesets
|
||
==================
|
||
|
||
The "commutative-ring" package allows control of ring properties
|
||
through the use of "rulesets".
|
||
|
||
- Variable: *ruleset*
|
||
Contains the set of rules currently in effect. Rules defined by
|
||
`cring:define-rule' are stored within the value of *ruleset* at the
|
||
time `cring:define-rule' is called. If *RULESET* is `#f', then no
|
||
rules apply.
|
||
|
||
- Function: make-ruleset rule1 ...
|
||
- Function: make-ruleset name rule1 ...
|
||
Returns a new ruleset containing the rules formed by applying
|
||
`cring:define-rule' to each 4-element list argument RULE. If the
|
||
first argument to `make-ruleset' is a symbol, then the database
|
||
table created for the new ruleset will be named NAME. Calling
|
||
`make-ruleset' with no rule arguments creates an empty ruleset.
|
||
|
||
- Function: combined-rulesets ruleset1 ...
|
||
- Function: combined-rulesets name ruleset1 ...
|
||
Returns a new ruleset containing the rules contained in each
|
||
ruleset argument RULESET. If the first argument to
|
||
`combined-ruleset' is a symbol, then the database table created for
|
||
the new ruleset will be named NAME. Calling `combined-ruleset'
|
||
with no ruleset arguments creates an empty ruleset.
|
||
|
||
Two rulesets are defined by this package.
|
||
|
||
- Constant: distribute*
|
||
Contain the ruleset to distribute multiplication over addition and
|
||
subtraction.
|
||
|
||
- Constant: distribute/
|
||
Contain the ruleset to distribute division over addition and
|
||
subtraction.
|
||
|
||
Take care when using both DISTRIBUTE* and DISTRIBUTE/
|
||
simultaneously. It is possible to put `/' into an infinite loop.
|
||
|
||
You can specify how sum and product expressions containing non-numeric
|
||
elements simplify by specifying the rules for `+' or `*' for cases
|
||
where expressions involving objects reduce to numbers or to expressions
|
||
involving different non-numeric elements.
|
||
|
||
- Function: cring:define-rule op sub-op1 sub-op2 reduction
|
||
Defines a rule for the case when the operation represented by
|
||
symbol OP is applied to lists whose `car's are SUB-OP1 and
|
||
SUB-OP2, respectively. The argument REDUCTION is a procedure
|
||
accepting 2 arguments which will be lists whose `car's are SUB-OP1
|
||
and SUB-OP2.
|
||
|
||
- Function: cring:define-rule op sub-op1 'identity reduction
|
||
Defines a rule for the case when the operation represented by
|
||
symbol OP is applied to a list whose `car' is SUB-OP1, and some
|
||
other argument. REDUCTION will be called with the list whose
|
||
`car' is SUB-OP1 and some other argument.
|
||
|
||
If REDUCTION returns `#f', the reduction has failed and other
|
||
reductions will be tried. If REDUCTION returns a non-false value,
|
||
that value will replace the two arguments in arithmetic (`+', `-',
|
||
and `*') calculations involving non-numeric elements.
|
||
|
||
The operations `+' and `*' are assumed commutative; hence both
|
||
orders of arguments to REDUCTION will be tried if necessary.
|
||
|
||
The following rule is the definition for distributing `*' over `+'.
|
||
|
||
(cring:define-rule
|
||
'* '+ 'identity
|
||
(lambda (exp1 exp2)
|
||
(apply + (map (lambda (trm) (* trm exp2)) (cdr exp1))))))
|
||
|
||
How to Create a Commutative Ring
|
||
================================
|
||
|
||
The first step in creating your commutative ring is to write
|
||
procedures to create elements of the ring. A non-numeric element of
|
||
the ring must be represented as a list whose first element is a symbol
|
||
or string. This first element identifies the type of the object. A
|
||
convenient and clear convention is to make the type-identifying element
|
||
be the same symbol whose top-level value is the procedure to create it.
|
||
|
||
(define (n . list1)
|
||
(cond ((and (= 2 (length list1))
|
||
(eq? (car list1) (cadr list1)))
|
||
0)
|
||
((not (term< (first list1) (last1 list1)))
|
||
(apply n (reverse list1)))
|
||
(else (cons 'n list1))))
|
||
|
||
(define (s x y) (n x y))
|
||
|
||
(define (m . list1)
|
||
(cond ((neq? (first list1) (term_min list1))
|
||
(apply m (cyclicrotate list1)))
|
||
((term< (last1 list1) (cadr list1))
|
||
(apply m (reverse (cyclicrotate list1))))
|
||
(else (cons 'm list1))))
|
||
|
||
Define a procedure to multiply 2 non-numeric elements of the ring.
|
||
Other multiplicatons are handled automatically. Objects for which rules
|
||
have _not_ been defined are not changed.
|
||
|
||
(define (n*n ni nj)
|
||
(let ((list1 (cdr ni)) (list2 (cdr nj)))
|
||
(cond ((null? (intersection list1 list2)) #f)
|
||
((and (eq? (last1 list1) (first list2))
|
||
(neq? (first list1) (last1 list2)))
|
||
(apply n (splice list1 list2)))
|
||
((and (eq? (first list1) (first list2))
|
||
(neq? (last1 list1) (last1 list2)))
|
||
(apply n (splice (reverse list1) list2)))
|
||
((and (eq? (last1 list1) (last1 list2))
|
||
(neq? (first list1) (first list2)))
|
||
(apply n (splice list1 (reverse list2))))
|
||
((and (eq? (last1 list1) (first list2))
|
||
(eq? (first list1) (last1 list2)))
|
||
(apply m (cyclicsplice list1 list2)))
|
||
((and (eq? (first list1) (first list2))
|
||
(eq? (last1 list1) (last1 list2)))
|
||
(apply m (cyclicsplice (reverse list1) list2)))
|
||
(else #f))))
|
||
|
||
Test the procedures to see if they work.
|
||
|
||
;;; where cyclicrotate(list) is cyclic rotation of the list one step
|
||
;;; by putting the first element at the end
|
||
(define (cyclicrotate list1)
|
||
(append (rest list1) (list (first list1))))
|
||
;;; and where term_min(list) is the element of the list which is
|
||
;;; first in the term ordering.
|
||
(define (term_min list1)
|
||
(car (sort list1 term<)))
|
||
(define (term< sym1 sym2)
|
||
(string<? (symbol->string sym1) (symbol->string sym2)))
|
||
(define first car)
|
||
(define rest cdr)
|
||
(define (last1 list1) (car (last-pair list1)))
|
||
(define (neq? obj1 obj2) (not (eq? obj1 obj2)))
|
||
;;; where splice is the concatenation of list1 and list2 except that their
|
||
;;; common element is not repeated.
|
||
(define (splice list1 list2)
|
||
(cond ((eq? (last1 list1) (first list2))
|
||
(append list1 (cdr list2)))
|
||
(else (error 'splice list1 list2))))
|
||
;;; where cyclicsplice is the result of leaving off the last element of
|
||
;;; splice(list1,list2).
|
||
(define (cyclicsplice list1 list2)
|
||
(cond ((and (eq? (last1 list1) (first list2))
|
||
(eq? (first list1) (last1 list2)))
|
||
(butlast (splice list1 list2) 1))
|
||
(else (error 'cyclicsplice list1 list2))))
|
||
|
||
(N*N (S a b) (S a b)) => (m a b)
|
||
|
||
Then register the rule for multiplying type N objects by type N
|
||
objects.
|
||
|
||
(cring:define-rule '* 'N 'N N*N))
|
||
|
||
Now we are ready to compute!
|
||
|
||
(define (t)
|
||
(define detM
|
||
(+ (* (S g b)
|
||
(+ (* (S f d)
|
||
(- (* (S a f) (S d g)) (* (S a g) (S d f))))
|
||
(* (S f f)
|
||
(- (* (S a g) (S d d)) (* (S a d) (S d g))))
|
||
(* (S f g)
|
||
(- (* (S a d) (S d f)) (* (S a f) (S d d))))))
|
||
(* (S g d)
|
||
(+ (* (S f b)
|
||
(- (* (S a g) (S d f)) (* (S a f) (S d g))))
|
||
(* (S f f)
|
||
(- (* (S a b) (S d g)) (* (S a g) (S d b))))
|
||
(* (S f g)
|
||
(- (* (S a f) (S d b)) (* (S a b) (S d f))))))
|
||
(* (S g f)
|
||
(+ (* (S f b)
|
||
(- (* (S a d) (S d g)) (* (S a g) (S d d))))
|
||
(* (S f d)
|
||
(- (* (S a g) (S d b)) (* (S a b) (S d g))))
|
||
(* (S f g)
|
||
(- (* (S a b) (S d d)) (* (S a d) (S d b))))))
|
||
(* (S g g)
|
||
(+ (* (S f b)
|
||
(- (* (S a f) (S d d)) (* (S a d) (S d f))))
|
||
(* (S f d)
|
||
(- (* (S a b) (S d f)) (* (S a f) (S d b))))
|
||
(* (S f f)
|
||
(- (* (S a d) (S d b)) (* (S a b) (S d d))))))))
|
||
(* (S b e) (S c a) (S e c)
|
||
detM
|
||
))
|
||
(pretty-print (t))
|
||
-|
|
||
(- (+ (m a c e b d f g)
|
||
(m a c e b d g f)
|
||
(m a c e b f d g)
|
||
(m a c e b f g d)
|
||
(m a c e b g d f)
|
||
(m a c e b g f d))
|
||
(* 2 (m a b e c) (m d f g))
|
||
(* (m a c e b d) (m f g))
|
||
(* (m a c e b f) (m d g))
|
||
(* (m a c e b g) (m d f)))
|
||
|
||
|
||
File: slib.info, Node: Determinant, Prev: Commutative Rings, Up: Mathematical Packages
|
||
|
||
Determinant
|
||
===========
|
||
|
||
- Function: determinant square-matrix |
|
||
Returns the determinant of SQUARE-MATRIX. |
|
||
|
|
||
(require 'determinant)
|
||
(determinant '((1 2) (3 4))) => -2
|
||
(determinant '((1 2 3) (4 5 6) (7 8 9))) => 0
|
||
(determinant '((1 2 3 4) (5 6 7 8) (9 10 11 12))) => 0
|
||
|
||
|
||
File: slib.info, Node: Database Packages, Next: Other Packages, Prev: Mathematical Packages, Up: Top
|
||
|
||
Database Packages
|
||
*****************
|
||
|
||
* Menu:
|
||
|
||
* Base Table::
|
||
* Relational Database:: 'relational-database
|
||
* Weight-Balanced Trees:: 'wt-tree
|
||
|
||
|
||
File: slib.info, Node: Base Table, Next: Relational Database, Prev: Database Packages, Up: Database Packages
|
||
|
||
Base Table
|
||
==========
|
||
|
||
A base table implementation using Scheme association lists is
|
||
available as the value of the identifier `alist-table' after doing:
|
||
|
||
`(require 'alist-table)'
|
||
|
||
Association list base tables are suitable for small databases and
|
||
support all Scheme types when temporary and readable/writeable Scheme
|
||
types when saved. I hope support for other base table implementations
|
||
will be added in the future.
|
||
|
||
This rest of this section documents the interface for a base table
|
||
implementation from which the *Note Relational Database:: package
|
||
constructs a Relational system. It will be of interest primarily to
|
||
those wishing to port or write new base-table implementations.
|
||
|
||
All of these functions are accessed through a single procedure by
|
||
calling that procedure with the symbol name of the operation. A
|
||
procedure will be returned if that operation is supported and `#f'
|
||
otherwise. For example:
|
||
|
||
(require 'alist-table)
|
||
(define open-base (alist-table 'make-base))
|
||
make-base => *a procedure*
|
||
(define foo (alist-table 'foo))
|
||
foo => #f
|
||
|
||
- Function: make-base filename key-dimension column-types
|
||
Returns a new, open, low-level database (collection of tables)
|
||
associated with FILENAME. This returned database has an empty
|
||
table associated with CATALOG-ID. The positive integer
|
||
KEY-DIMENSION is the number of keys composed to make a PRIMARY-KEY
|
||
for the catalog table. The list of symbols COLUMN-TYPES describes
|
||
the types of each column for that table. If the database cannot
|
||
be created as specified, `#f' is returned.
|
||
|
||
Calling the `close-base' method on this database and possibly other
|
||
operations will cause FILENAME to be written to. If FILENAME is
|
||
`#f' a temporary, non-disk based database will be created if such
|
||
can be supported by the base table implelentation.
|
||
|
||
- Function: open-base filename mutable
|
||
Returns an open low-level database associated with FILENAME. If
|
||
MUTABLE? is `#t', this database will have methods capable of
|
||
effecting change to the database. If MUTABLE? is `#f', only
|
||
methods for inquiring the database will be available. If the
|
||
database cannot be opened as specified `#f' is returned.
|
||
|
||
Calling the `close-base' (and possibly other) method on a MUTABLE?
|
||
database will cause FILENAME to be written to.
|
||
|
||
- Function: write-base lldb filename
|
||
Causes the low-level database LLDB to be written to FILENAME. If
|
||
the write is successful, also causes LLDB to henceforth be
|
||
associated with FILENAME. Calling the `close-database' (and
|
||
possibly other) method on LLDB may cause FILENAME to be written
|
||
to. If FILENAME is `#f' this database will be changed to a
|
||
temporary, non-disk based database if such can be supported by the
|
||
underlying base table implelentation. If the operations completed
|
||
successfully, `#t' is returned. Otherwise, `#f' is returned.
|
||
|
||
- Function: sync-base lldb
|
||
Causes the file associated with the low-level database LLDB to be
|
||
updated to reflect its current state. If the associated filename
|
||
is `#f', no action is taken and `#f' is returned. If this
|
||
operation completes successfully, `#t' is returned. Otherwise,
|
||
`#f' is returned.
|
||
|
||
- Function: close-base lldb
|
||
Causes the low-level database LLDB to be written to its associated
|
||
file (if any). If the write is successful, subsequent operations
|
||
to LLDB will signal an error. If the operations complete
|
||
successfully, `#t' is returned. Otherwise, `#f' is returned.
|
||
|
||
- Function: make-table lldb key-dimension column-types
|
||
Returns the BASE-ID for a new base table, otherwise returns `#f'.
|
||
The base table can then be opened using `(open-table LLDB
|
||
BASE-ID)'. The positive integer KEY-DIMENSION is the number of
|
||
keys composed to make a PRIMARY-KEY for this table. The list of
|
||
symbols COLUMN-TYPES describes the types of each column.
|
||
|
||
- Constant: catalog-id
|
||
A constant BASE-ID suitable for passing as a parameter to
|
||
`open-table'. CATALOG-ID will be used as the base table for the
|
||
system catalog.
|
||
|
||
- Function: open-table lldb base-id key-dimension column-types
|
||
Returns a HANDLE for an existing base table in the low-level
|
||
database LLDB if that table exists and can be opened in the mode
|
||
indicated by MUTABLE?, otherwise returns `#f'.
|
||
|
||
As with `make-table', the positive integer KEY-DIMENSION is the
|
||
number of keys composed to make a PRIMARY-KEY for this table. The
|
||
list of symbols COLUMN-TYPES describes the types of each column.
|
||
|
||
- Function: kill-table lldb base-id key-dimension column-types
|
||
Returns `#t' if the base table associated with BASE-ID was removed
|
||
from the low level database LLDB, and `#f' otherwise.
|
||
|
||
- Function: make-keyifier-1 type
|
||
Returns a procedure which accepts a single argument which must be
|
||
of type TYPE. This returned procedure returns an object suitable
|
||
for being a KEY argument in the functions whose descriptions
|
||
follow.
|
||
|
||
Any 2 arguments of the supported type passed to the returned
|
||
function which are not `equal?' must result in returned values
|
||
which are not `equal?'.
|
||
|
||
- Function: make-list-keyifier key-dimension types
|
||
The list of symbols TYPES must have at least KEY-DIMENSION
|
||
elements. Returns a procedure which accepts a list of length
|
||
KEY-DIMENSION and whose types must corresopond to the types named
|
||
by TYPES. This returned procedure combines the elements of its
|
||
list argument into an object suitable for being a KEY argument in
|
||
the functions whose descriptions follow.
|
||
|
||
Any 2 lists of supported types (which must at least include
|
||
symbols and non-negative integers) passed to the returned function
|
||
which are not `equal?' must result in returned values which are not
|
||
`equal?'.
|
||
|
||
- Function: make-key-extractor key-dimension types column-number
|
||
Returns a procedure which accepts objects produced by application
|
||
of the result of `(make-list-keyifier KEY-DIMENSION TYPES)'. This
|
||
procedure returns a KEY which is `equal?' to the COLUMN-NUMBERth
|
||
element of the list which was passed to create COMBINED-KEY. The
|
||
list TYPES must have at least KEY-DIMENSION elements.
|
||
|
||
- Function: make-key->list key-dimension types
|
||
Returns a procedure which accepts objects produced by application
|
||
of the result of `(make-list-keyifier KEY-DIMENSION TYPES)'. This
|
||
procedure returns a list of KEYs which are elementwise `equal?' to
|
||
the list which was passed to create COMBINED-KEY.
|
||
|
||
In the following functions, the KEY argument can always be assumed to
|
||
be the value returned by a call to a _keyify_ routine.
|
||
|
||
In contrast, a MATCH-KEYS argument is a list of length equal to the
|
||
number of primary keys. The MATCH-KEYS restrict the actions of the
|
||
table command to those records whose primary keys all satisfy the
|
||
corresponding element of the MATCH-KEYS list. The elements and their
|
||
actions are:
|
||
|
||
`#f'
|
||
The false value matches any key in the corresponding position.
|
||
|
||
an object of type procedure
|
||
This procedure must take a single argument, the key in the
|
||
corresponding position. Any key for which the procedure
|
||
returns a non-false value is a match; Any key for which the
|
||
procedure returns a `#f' is not.
|
||
|
||
other values
|
||
Any other value matches only those keys `equal?' to it.
|
||
|
||
The KEY-DIMENSION and COLUMN-TYPES arguments are needed to decode the
|
||
combined-keys for matching with MATCH-KEYS.
|
||
|
||
- Function: for-each-key handle procedure key-dimension column-types
|
||
match-keys
|
||
Calls PROCEDURE once with each KEY in the table opened in HANDLE
|
||
which satisfy MATCH-KEYS in an unspecified order. An unspecified
|
||
value is returned.
|
||
|
||
- Function: map-key handle procedure key-dimension column-types
|
||
match-keys
|
||
Returns a list of the values returned by calling PROCEDURE once
|
||
with each KEY in the table opened in HANDLE which satisfy
|
||
MATCH-KEYS in an unspecified order.
|
||
|
||
- Function: ordered-for-each-key handle procedure key-dimension
|
||
column-types match-keys
|
||
Calls PROCEDURE once with each KEY in the table opened in HANDLE
|
||
which satisfy MATCH-KEYS in the natural order for the types of the
|
||
primary key fields of that table. An unspecified value is
|
||
returned.
|
||
|
||
- Function: delete* handle key-dimension column-types match-keys
|
||
Removes all rows which satisfy MATCH-KEYS from the table opened in
|
||
HANDLE. An unspecified value is returned.
|
||
|
||
- Function: present? handle key
|
||
Returns a non-`#f' value if there is a row associated with KEY in
|
||
the table opened in HANDLE and `#f' otherwise.
|
||
|
||
- Function: delete handle key
|
||
Removes the row associated with KEY from the table opened in
|
||
HANDLE. An unspecified value is returned.
|
||
|
||
- Function: make-getter key-dimension types
|
||
Returns a procedure which takes arguments HANDLE and KEY. This
|
||
procedure returns a list of the non-primary values of the relation
|
||
(in the base table opened in HANDLE) whose primary key is KEY if
|
||
it exists, and `#f' otherwise.
|
||
|
||
- Function: make-putter key-dimension types
|
||
Returns a procedure which takes arguments HANDLE and KEY and
|
||
VALUE-LIST. This procedure associates the primary key KEY with
|
||
the values in VALUE-LIST (in the base table opened in HANDLE) and
|
||
returns an unspecified value.
|
||
|
||
- Function: supported-type? symbol
|
||
Returns `#t' if SYMBOL names a type allowed as a column value by
|
||
the implementation, and `#f' otherwise. At a minimum, an
|
||
implementation must support the types `integer', `symbol',
|
||
`string', `boolean', and `base-id'.
|
||
|
||
- Function: supported-key-type? symbol
|
||
Returns `#t' if SYMBOL names a type allowed as a key value by the
|
||
implementation, and `#f' otherwise. At a minimum, an
|
||
implementation must support the types `integer', and `symbol'.
|
||
|
||
`integer'
|
||
Scheme exact integer.
|
||
|
||
`symbol'
|
||
Scheme symbol.
|
||
|
||
`boolean'
|
||
`#t' or `#f'.
|
||
|
||
`base-id'
|
||
Objects suitable for passing as the BASE-ID parameter to
|
||
`open-table'. The value of CATALOG-ID must be an acceptable
|
||
`base-id'.
|
||
|
||
|
||
File: slib.info, Node: Relational Database, Next: Weight-Balanced Trees, Prev: Base Table, Up: Database Packages
|
||
|
||
Relational Database
|
||
===================
|
||
|
||
`(require 'relational-database)'
|
||
|
||
This package implements a database system inspired by the Relational
|
||
Model (`E. F. Codd, A Relational Model of Data for Large Shared Data
|
||
Banks'). An SLIB relational database implementation can be created
|
||
from any *Note Base Table:: implementation.
|
||
|
||
* Menu:
|
||
|
||
* Motivations:: Database Manifesto
|
||
* Creating and Opening Relational Databases::
|
||
* Relational Database Operations::
|
||
* Table Operations::
|
||
* Catalog Representation::
|
||
* Unresolved Issues::
|
||
* Database Utilities:: 'database-utilities
|
||
* Database Reports::
|
||
* Database Browser:: 'database-browse
|
||
|
||
|
||
File: slib.info, Node: Motivations, Next: Creating and Opening Relational Databases, Prev: Relational Database, Up: Relational Database
|
||
|
||
Motivations
|
||
-----------
|
||
|
||
Most nontrivial programs contain databases: Makefiles, configure
|
||
scripts, file backup, calendars, editors, source revision control, CAD
|
||
systems, display managers, menu GUIs, games, parsers, debuggers,
|
||
profilers, and even error reporting are all rife with databases. Coding
|
||
databases is such a common activity in programming that many may not be
|
||
aware of how often they do it.
|
||
|
||
A database often starts as a dispatch in a program. The author,
|
||
perhaps because of the need to make the dispatch configurable, the need
|
||
for correlating dispatch in other routines, or because of changes or
|
||
growth, devises a data structure to contain the information, a routine
|
||
for interpreting that data structure, and perhaps routines for
|
||
augmenting and modifying the stored data. The dispatch must be
|
||
converted into this form and tested.
|
||
|
||
The programmer may need to devise an interactive program for enabling
|
||
easy examination and modification of the information contained in this
|
||
database. Often, in an attempt to foster modularity and avoid delays in
|
||
release, intermediate file formats for the database information are
|
||
devised. It often turns out that users prefer modifying these
|
||
intermediate files with a text editor to using the interactive program
|
||
in order to do operations (such as global changes) not forseen by the
|
||
program's author.
|
||
|
||
In order to address this need, the conscientious software engineer may
|
||
even provide a scripting language to allow users to make repetitive
|
||
database changes. Users will grumble that they need to read a large
|
||
manual and learn yet another programming language (even if it _almost_
|
||
has language "xyz" syntax) in order to do simple configuration.
|
||
|
||
All of these facilities need to be designed, coded, debugged,
|
||
documented, and supported; often causing what was very simple in concept
|
||
to become a major developement project.
|
||
|
||
This view of databases just outlined is somewhat the reverse of the
|
||
view of the originators of the "Relational Model" of database
|
||
abstraction. The relational model was devised to unify and allow
|
||
interoperation of large multi-user databases running on diverse
|
||
platforms. A fairly general purpose "Comprehensive Language" for
|
||
database manipulations is mandated (but not specified) as part of the
|
||
relational model for databases.
|
||
|
||
One aspect of the Relational Model of some importance is that the
|
||
"Comprehensive Language" must be expressible in some form which can be
|
||
stored in the database. This frees the programmer from having to make
|
||
programs data-driven in order to use a database.
|
||
|
||
This package includes as one of its basic supported types Scheme
|
||
"expression"s. This type allows expressions as defined by the Scheme
|
||
standards to be stored in the database. Using `slib:eval' retrieved
|
||
expressions can be evaluated (in the top-level environment). Scheme's
|
||
`lambda' facilitates closure of environments, modularity, etc. so that
|
||
procedures (which could not be stored directly most databases) can
|
||
still be effectively retrieved. Since `slib:eval' evaluates
|
||
expressions in the top-level environment, built-in and user defined
|
||
procedures can be easily accessed by name.
|
||
|
||
This package's purpose is to standardize (through a common interface)
|
||
database creation and usage in Scheme programs. The relational model's
|
||
provision for inclusion of language expressions as data as well as the
|
||
description (in tables, of course) of all of its tables assures that
|
||
relational databases are powerful enough to assume the roles currently
|
||
played by thousands of ad-hoc routines and data formats.
|
||
|
||
Such standardization to a relational-like model brings many benefits:
|
||
|
||
* Tables, fields, domains, and types can be dealt with by name in
|
||
programs.
|
||
|
||
* The underlying database implementation can be changed (for
|
||
performance or other reasons) by changing a single line of code.
|
||
|
||
* The formats of tables can be easily extended or changed without
|
||
altering code.
|
||
|
||
* Consistency checks are specified as part of the table descriptions.
|
||
Changes in checks need only occur in one place.
|
||
|
||
* All the configuration information which the developer wishes to
|
||
group together is easily grouped, without needing to change
|
||
programs aware of only some of these tables.
|
||
|
||
* Generalized report generators, interactive entry programs, and
|
||
other database utilities can be part of a shared library. The
|
||
burden of adding configurability to a program is greatly reduced.
|
||
|
||
* Scheme is the "comprehensive language" for these databases.
|
||
Scripting for configuration no longer needs to be in a separate
|
||
language with additional documentation.
|
||
|
||
* Scheme's latent types mesh well with the strict typing and logical
|
||
requirements of the relational model.
|
||
|
||
* Portable formats allow easy interchange of data. The included
|
||
table descriptions help prevent misinterpretation of format.
|
||
|
||
|
||
File: slib.info, Node: Creating and Opening Relational Databases, Next: Relational Database Operations, Prev: Motivations, Up: Relational Database
|
||
|
||
Creating and Opening Relational Databases
|
||
-----------------------------------------
|
||
|
||
- Function: make-relational-system base-table-implementation
|
||
Returns a procedure implementing a relational database using the
|
||
BASE-TABLE-IMPLEMENTATION.
|
||
|
||
All of the operations of a base table implementation are accessed
|
||
through a procedure defined by `require'ing that implementation.
|
||
Similarly, all of the operations of the relational database
|
||
implementation are accessed through the procedure returned by
|
||
`make-relational-system'. For instance, a new relational database
|
||
could be created from the procedure returned by
|
||
`make-relational-system' by:
|
||
|
||
(require 'alist-table)
|
||
(define relational-alist-system
|
||
(make-relational-system alist-table))
|
||
(define create-alist-database
|
||
(relational-alist-system 'create-database))
|
||
(define my-database
|
||
(create-alist-database "mydata.db"))
|
||
|
||
What follows are the descriptions of the methods available from
|
||
relational system returned by a call to `make-relational-system'.
|
||
|
||
- Function: create-database filename
|
||
Returns an open, nearly empty relational database associated with
|
||
FILENAME. The only tables defined are the system catalog and
|
||
domain table. Calling the `close-database' method on this database
|
||
and possibly other operations will cause FILENAME to be written
|
||
to. If FILENAME is `#f' a temporary, non-disk based database will
|
||
be created if such can be supported by the underlying base table
|
||
implelentation. If the database cannot be created as specified
|
||
`#f' is returned. For the fields and layout of descriptor tables,
|
||
*Note Catalog Representation::
|
||
|
||
- Function: open-database filename mutable?
|
||
Returns an open relational database associated with FILENAME. If
|
||
MUTABLE? is `#t', this database will have methods capable of
|
||
effecting change to the database. If MUTABLE? is `#f', only
|
||
methods for inquiring the database will be available. Calling the
|
||
`close-database' (and possibly other) method on a MUTABLE?
|
||
database will cause FILENAME to be written to. If the database
|
||
cannot be opened as specified `#f' is returned.
|
||
|
||
|
||
File: slib.info, Node: Relational Database Operations, Next: Table Operations, Prev: Creating and Opening Relational Databases, Up: Relational Database
|
||
|
||
Relational Database Operations
|
||
------------------------------
|
||
|
||
These are the descriptions of the methods available from an open
|
||
relational database. A method is retrieved from a database by calling
|
||
the database with the symbol name of the operation. For example:
|
||
|
||
(define my-database
|
||
(create-alist-database "mydata.db"))
|
||
(define telephone-table-desc
|
||
((my-database 'create-table) 'telephone-table-desc))
|
||
|
||
- Function: close-database
|
||
Causes the relational database to be written to its associated
|
||
file (if any). If the write is successful, subsequent operations
|
||
to this database will signal an error. If the operations completed
|
||
successfully, `#t' is returned. Otherwise, `#f' is returned.
|
||
|
||
- Function: write-database filename
|
||
Causes the relational database to be written to FILENAME. If the
|
||
write is successful, also causes the database to henceforth be
|
||
associated with FILENAME. Calling the `close-database' (and
|
||
possibly other) method on this database will cause FILENAME to be
|
||
written to. If FILENAME is `#f' this database will be changed to
|
||
a temporary, non-disk based database if such can be supported by
|
||
the underlying base table implelentation. If the operations
|
||
completed successfully, `#t' is returned. Otherwise, `#f' is
|
||
returned.
|
||
|
||
- Function: sync-database |
|
||
Causes any pending updates to the database file to be written out. |
|
||
If the operations completed successfully, `#t' is returned. |
|
||
Otherwise, `#f' is returned. |
|
||
|
|
||
- Function: table-exists? table-name
|
||
Returns `#t' if TABLE-NAME exists in the system catalog, otherwise
|
||
returns `#f'.
|
||
|
||
- Function: open-table table-name mutable?
|
||
Returns a "methods" procedure for an existing relational table in
|
||
this database if it exists and can be opened in the mode indicated
|
||
by MUTABLE?, otherwise returns `#f'.
|
||
|
||
These methods will be present only in databases which are MUTABLE?.
|
||
|
||
- Function: delete-table table-name
|
||
Removes and returns the TABLE-NAME row from the system catalog if
|
||
the table or view associated with TABLE-NAME gets removed from the
|
||
database, and `#f' otherwise.
|
||
|
||
- Function: create-table table-desc-name
|
||
Returns a methods procedure for a new (open) relational table for
|
||
describing the columns of a new base table in this database,
|
||
otherwise returns `#f'. For the fields and layout of descriptor
|
||
tables, *Note Catalog Representation::.
|
||
|
||
- Function: create-table table-name table-desc-name
|
||
Returns a methods procedure for a new (open) relational table with
|
||
columns as described by TABLE-DESC-NAME, otherwise returns `#f'.
|
||
|
||
- Function: create-view ??
|
||
- Function: project-table ??
|
||
- Function: restrict-table ??
|
||
- Function: cart-prod-tables ??
|
||
Not yet implemented.
|
||
|
||
|
||
File: slib.info, Node: Table Operations, Next: Catalog Representation, Prev: Relational Database Operations, Up: Relational Database
|
||
|
||
Table Operations
|
||
----------------
|
||
|
||
These are the descriptions of the methods available from an open
|
||
relational table. A method is retrieved from a table by calling the
|
||
table with the symbol name of the operation. For example:
|
||
|
||
(define telephone-table-desc
|
||
((my-database 'create-table) 'telephone-table-desc))
|
||
(require 'common-list-functions)
|
||
(define ndrp (telephone-table-desc 'row:insert))
|
||
(ndrp '(1 #t name #f string))
|
||
(ndrp '(2 #f telephone
|
||
(lambda (d)
|
||
(and (string? d) (> (string-length d) 2)
|
||
(every
|
||
(lambda (c)
|
||
(memv c '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9
|
||
#\+ #\( #\ #\) #\-)))
|
||
(string->list d))))
|
||
string))
|
||
|
||
Some operations described below require primary key arguments. Primary
|
||
keys arguments are denoted KEY1 KEY2 .... It is an error to call an
|
||
operation for a table which takes primary key arguments with the wrong
|
||
number of primary keys for that table.
|
||
|
||
The term "row" used below refers to a Scheme list of values (one for
|
||
each column) in the order specified in the descriptor (table) for this
|
||
table. Missing values appear as `#f'. Primary keys must not be
|
||
missing.
|
||
|
||
- Function: get column-name
|
||
Returns a procedure of arguments KEY1 KEY2 ... which returns the
|
||
value for the COLUMN-NAME column of the row associated with
|
||
primary keys KEY1, KEY2 ... if that row exists in the table, or
|
||
`#f' otherwise.
|
||
|
||
((plat 'get 'processor) 'djgpp) => i386
|
||
((plat 'get 'processor) 'be-os) => #f
|
||
|
||
- Function: get* column-name
|
||
Returns a procedure of optional arguments MATCH-KEY1 ... which
|
||
returns a list of the values for the specified column for all rows
|
||
in this table. The optional MATCH-KEY1 ... arguments restrict
|
||
actions to a subset of the table. See the match-key description
|
||
below for details.
|
||
|
||
((plat 'get* 'processor)) =>
|
||
(i386 8086 i386 8086 i386 i386 8086 m68000
|
||
m68000 m68000 m68000 m68000 powerpc)
|
||
|
||
((plat 'get* 'processor) #f) =>
|
||
(i386 8086 i386 8086 i386 i386 8086 m68000
|
||
m68000 m68000 m68000 m68000 powerpc)
|
||
|
||
(define (a-key? key)
|
||
(char=? #\a (string-ref (symbol->string key) 0)))
|
||
|
||
((plat 'get* 'processor) a-key?) =>
|
||
(m68000 m68000 m68000 m68000 m68000 powerpc)
|
||
|
||
((plat 'get* 'name) a-key?) =>
|
||
(atari-st-turbo-c atari-st-gcc amiga-sas/c-5.10
|
||
amiga-aztec amiga-dice-c aix)
|
||
|
||
- Function: row:retrieve
|
||
Returns a procedure of arguments KEY1 KEY2 ... which returns the
|
||
row associated with primary keys KEY1, KEY2 ... if it exists, or
|
||
`#f' otherwise.
|
||
|
||
((plat 'row:retrieve) 'linux) => (linux i386 linux gcc)
|
||
((plat 'row:retrieve) 'multics) => #f
|
||
|
||
- Function: row:retrieve*
|
||
Returns a procedure of optional arguments MATCH-KEY1 ... which
|
||
returns a list of all rows in this table. The optional MATCH-KEY1
|
||
... arguments restrict actions to a subset of the table. See the
|
||
match-key description below for details.
|
||
|
||
((plat 'row:retrieve*) a-key?) =>
|
||
((atari-st-turbo-c m68000 atari turbo-c)
|
||
(atari-st-gcc m68000 atari gcc)
|
||
(amiga-sas/c-5.10 m68000 amiga sas/c)
|
||
(amiga-aztec m68000 amiga aztec)
|
||
(amiga-dice-c m68000 amiga dice-c)
|
||
(aix powerpc aix -))
|
||
|
||
- Function: row:remove
|
||
Returns a procedure of arguments KEY1 KEY2 ... which removes and
|
||
returns the row associated with primary keys KEY1, KEY2 ... if it
|
||
exists, or `#f' otherwise.
|
||
|
||
- Function: row:remove*
|
||
Returns a procedure of optional arguments MATCH-KEY1 ... which
|
||
removes and returns a list of all rows in this table. The optional
|
||
MATCH-KEY1 ... arguments restrict actions to a subset of the
|
||
table. See the match-key description below for details.
|
||
|
||
- Function: row:delete
|
||
Returns a procedure of arguments KEY1 KEY2 ... which deletes the
|
||
row associated with primary keys KEY1, KEY2 ... if it exists. The
|
||
value returned is unspecified.
|
||
|
||
- Function: row:delete*
|
||
Returns a procedure of optional arguments MATCH-KEY1 ... which
|
||
Deletes all rows from this table. The optional MATCH-KEY1 ...
|
||
arguments restrict deletions to a subset of the table. See the
|
||
match-key description below for details. The value returned is
|
||
unspecified. The descriptor table and catalog entry for this
|
||
table are not affected.
|
||
|
||
- Function: row:update
|
||
Returns a procedure of one argument, ROW, which adds the row, ROW,
|
||
to this table. If a row for the primary key(s) specified by ROW
|
||
already exists in this table, it will be overwritten. The value
|
||
returned is unspecified.
|
||
|
||
- Function: row:update*
|
||
Returns a procedure of one argument, ROWS, which adds each row in
|
||
the list of rows, ROWS, to this table. If a row for the primary
|
||
key specified by an element of ROWS already exists in this table,
|
||
it will be overwritten. The value returned is unspecified.
|
||
|
||
- Function: row:insert
|
||
Adds the row ROW to this table. If a row for the primary key(s)
|
||
specified by ROW already exists in this table an error is
|
||
signaled. The value returned is unspecified.
|
||
|
||
- Function: row:insert*
|
||
Returns a procedure of one argument, ROWS, which adds each row in
|
||
the list of rows, ROWS, to this table. If a row for the primary
|
||
key specified by an element of ROWS already exists in this table,
|
||
an error is signaled. The value returned is unspecified.
|
||
|
||
- Function: for-each-row
|
||
Returns a procedure of arguments PROC MATCH-KEY1 ... which calls
|
||
PROC with each ROW in this table in the (implementation-dependent)
|
||
natural ordering for rows. The optional MATCH-KEY1 ... arguments
|
||
restrict actions to a subset of the table. See the match-key
|
||
description below for details.
|
||
|
||
_Real_ relational programmers would use some least-upper-bound join
|
||
for every row to get them in order; But we don't have joins yet.
|
||
|
||
The (optional) MATCH-KEY1 ... arguments are used to restrict actions of
|
||
a whole-table operation to a subset of that table. Those procedures
|
||
(returned by methods) which accept match-key arguments will accept any
|
||
number of match-key arguments between zero and the number of primary
|
||
keys in the table. Any unspecified MATCH-KEY arguments default to `#f'.
|
||
|
||
The MATCH-KEY1 ... restrict the actions of the table command to those
|
||
records whose primary keys each satisfy the corresponding MATCH-KEY
|
||
argument. The arguments and their actions are:
|
||
|
||
`#f'
|
||
The false value matches any key in the corresponding position.
|
||
|
||
an object of type procedure
|
||
This procedure must take a single argument, the key in the
|
||
corresponding position. Any key for which the procedure
|
||
returns a non-false value is a match; Any key for which the
|
||
procedure returns a `#f' is not.
|
||
|
||
other values
|
||
Any other value matches only those keys `equal?' to it.
|
||
|
||
- Function: close-table
|
||
Subsequent operations to this table will signal an error.
|
||
|
||
- Constant: column-names
|
||
- Constant: column-foreigns
|
||
- Constant: column-domains
|
||
- Constant: column-types
|
||
Return a list of the column names, foreign-key table names, domain
|
||
names, or type names respectively for this table. These 4 methods
|
||
are different from the others in that the list is returned, rather
|
||
than a procedure to obtain the list.
|
||
|
||
- Constant: primary-limit
|
||
Returns the number of primary keys fields in the relations in this
|
||
table.
|
||
|
||
|
||
File: slib.info, Node: Catalog Representation, Next: Unresolved Issues, Prev: Table Operations, Up: Relational Database
|
||
|
||
Catalog Representation
|
||
----------------------
|
||
|
||
Each database (in an implementation) has a "system catalog" which
|
||
describes all the user accessible tables in that database (including
|
||
itself).
|
||
|
||
The system catalog base table has the following fields. `PRI'
|
||
indicates a primary key for that table.
|
||
|
||
PRI table-name
|
||
column-limit the highest column number
|
||
coltab-name descriptor table name
|
||
bastab-id data base table identifier
|
||
user-integrity-rule
|
||
view-procedure A scheme thunk which, when called,
|
||
produces a handle for the view. coltab
|
||
and bastab are specified if and only if
|
||
view-procedure is not.
|
||
|
||
Descriptors for base tables (not views) are tables (pointed to by
|
||
system catalog). Descriptor (base) tables have the fields:
|
||
|
||
PRI column-number sequential integers from 1
|
||
primary-key? boolean TRUE for primary key components
|
||
column-name
|
||
column-integrity-rule
|
||
domain-name
|
||
|
||
A "primary key" is any column marked as `primary-key?' in the
|
||
corresponding descriptor table. All the `primary-key?' columns must
|
||
have lower column numbers than any non-`primary-key?' columns. Every
|
||
table must have at least one primary key. Primary keys must be
|
||
sufficient to distinguish all rows from each other in the table. All of
|
||
the system defined tables have a single primary key.
|
||
|
||
This package currently supports tables having from 1 to 4 primary keys
|
||
if there are non-primary columns, and any (natural) number if _all_
|
||
columns are primary keys. If you need more than 4 primary keys, I would
|
||
like to hear what you are doing!
|
||
|
||
A "domain" is a category describing the allowable values to occur in a
|
||
column. It is described by a (base) table with the fields:
|
||
|
||
PRI domain-name
|
||
foreign-table
|
||
domain-integrity-rule
|
||
type-id
|
||
type-param
|
||
|
||
The "type-id" field value is a symbol. This symbol may be used by the
|
||
underlying base table implementation in storing that field.
|
||
|
||
If the `foreign-table' field is non-`#f' then that field names a table
|
||
from the catalog. The values for that domain must match a primary key
|
||
of the table referenced by the TYPE-PARAM (or `#f', if allowed). This
|
||
package currently does not support composite foreign-keys.
|
||
|
||
The types for which support is planned are:
|
||
atom
|
||
symbol
|
||
string [<length>]
|
||
number [<base>]
|
||
money <currency>
|
||
date-time
|
||
boolean
|
||
|
||
foreign-key <table-name>
|
||
expression
|
||
virtual <expression>
|
||
|
||
|
||
File: slib.info, Node: Unresolved Issues, Next: Database Utilities, Prev: Catalog Representation, Up: Relational Database
|
||
|
||
Unresolved Issues
|
||
-----------------
|
||
|
||
Although `rdms.scm' is not large, I found it very difficult to write
|
||
(six rewrites). I am not aware of any other examples of a generalized
|
||
relational system (although there is little new in CS). I left out
|
||
several aspects of the Relational model in order to simplify the job.
|
||
The major features lacking (which might be addressed portably) are
|
||
views, transaction boundaries, and protection.
|
||
|
||
Protection needs a model for specifying priveledges. Given how
|
||
operations are accessed from handles it should not be difficult to
|
||
restrict table accesses to those allowed for that user.
|
||
|
||
The system catalog has a field called `view-procedure'. This should
|
||
allow a purely functional implementation of views. This will work but
|
||
is unsatisfying for views resulting from a "select"ion (subset of
|
||
rows); for whole table operations it will not be possible to reduce the
|
||
number of keys scanned over when the selection is specified only by an
|
||
opaque procedure.
|
||
|
||
Transaction boundaries present the most intriguing area. Transaction
|
||
boundaries are actually a feature of the "Comprehensive Language" of the
|
||
Relational database and not of the database. Scheme would seem to
|
||
provide the opportunity for an extremely clean semantics for transaction
|
||
boundaries since the builtin procedures with side effects are small in
|
||
number and easily identified.
|
||
|
||
These side-effect builtin procedures might all be portably redefined
|
||
to versions which properly handled transactions. Compiled library
|
||
routines would need to be recompiled as well. Many system extensions
|
||
(delete-file, system, etc.) would also need to be redefined.
|
||
|
||
There are 2 scope issues that must be resolved for multiprocess
|
||
transaction boundaries:
|
||
|
||
Process scope
|
||
The actions captured by a transaction should be only for the
|
||
process which invoked the start of transaction. Although standard
|
||
Scheme does not provide process primitives as such, `dynamic-wind'
|
||
would provide a workable hook into process switching for many
|
||
implementations.
|
||
|
||
Shared utilities with state
|
||
Some shared utilities have state which should _not_ be part of a
|
||
transaction. An example would be calling a pseudo-random number
|
||
generator. If the success of a transaction depended on the
|
||
pseudo-random number and failed, the state of the generator would
|
||
be set back. Subsequent calls would keep returning the same
|
||
number and keep failing.
|
||
|
||
Pseudo-random number generators are not reentrant; thus they would
|
||
require locks in order to operate properly in a multiprocess
|
||
environment. Are all examples of utilities whose state should not
|
||
be part of transactions also non-reentrant? If so, perhaps
|
||
suspending transaction capture for the duration of locks would
|
||
solve this problem.
|
||
|
||
|
||
File: slib.info, Node: Database Utilities, Next: Database Reports, Prev: Unresolved Issues, Up: Relational Database
|
||
|
||
Database Utilities
|
||
------------------
|
||
|
||
`(require 'database-utilities)'
|
||
|
||
This enhancement wraps a utility layer on `relational-database' which
|
||
provides:
|
||
* Automatic loading of the appropriate base-table package when
|
||
opening a database.
|
||
|
||
* Automatic execution of initialization commands stored in database.
|
||
|
||
* Transparent execution of database commands stored in `*commands*'
|
||
table in database.
|
||
|
||
Also included are utilities which provide:
|
||
* Data definition from Scheme lists and
|
||
|
||
* Report generation
|
||
|
||
for any SLIB relational database.
|
||
|
||
- Function: create-database filename base-table-type
|
||
Returns an open, nearly empty enhanced (with `*commands*' table)
|
||
relational database (with base-table type BASE-TABLE-TYPE)
|
||
associated with FILENAME.
|
||
|
||
- Function: open-database filename
|
||
- Function: open-database filename base-table-type
|
||
Returns an open enchanced relational database associated with
|
||
FILENAME. The database will be opened with base-table type
|
||
BASE-TABLE-TYPE) if supplied. If BASE-TABLE-TYPE is not supplied,
|
||
`open-database' will attempt to deduce the correct
|
||
base-table-type. If the database can not be opened or if it lacks
|
||
the `*commands*' table, `#f' is returned.
|
||
|
||
- Function: open-database! filename
|
||
- Function: open-database! filename base-table-type
|
||
Returns _mutable_ open enchanced relational database ...
|
||
|
||
The table `*commands*' in an "enhanced" relational-database has the
|
||
fields (with domains):
|
||
PRI name symbol
|
||
parameters parameter-list
|
||
procedure expression
|
||
documentation string
|
||
|
||
The `parameters' field is a foreign key (domain `parameter-list') of
|
||
the `*catalog-data*' table and should have the value of a table
|
||
described by `*parameter-columns*'. This `parameter-list' table
|
||
describes the arguments suitable for passing to the associated command.
|
||
The intent of this table is to be of a form such that different
|
||
user-interfaces (for instance, pull-down menus or plain-text queries)
|
||
can operate from the same table. A `parameter-list' table has the
|
||
following fields:
|
||
PRI index uint
|
||
name symbol
|
||
arity parameter-arity
|
||
domain domain
|
||
defaulter expression
|
||
expander expression
|
||
documentation string
|
||
|
||
The `arity' field can take the values:
|
||
|
||
`single'
|
||
Requires a single parameter of the specified domain.
|
||
|
||
`optional'
|
||
A single parameter of the specified domain or zero parameters is
|
||
acceptable.
|
||
|
||
`boolean'
|
||
A single boolean parameter or zero parameters (in which case `#f'
|
||
is substituted) is acceptable.
|
||
|
||
`nary'
|
||
Any number of parameters of the specified domain are acceptable.
|
||
The argument passed to the command function is always a list of the
|
||
parameters.
|
||
|
||
`nary1'
|
||
One or more of parameters of the specified domain are acceptable.
|
||
The argument passed to the command function is always a list of the
|
||
parameters.
|
||
|
||
The `domain' field specifies the domain which a parameter or
|
||
parameters in the `index'th field must satisfy.
|
||
|
||
The `defaulter' field is an expression whose value is either `#f' or
|
||
a procedure of one argument (the parameter-list) which returns a _list_
|
||
of the default value or values as appropriate. Note that since the
|
||
`defaulter' procedure is called every time a default parameter is
|
||
needed for this column, "sticky" defaults can be implemented using
|
||
shared state with the domain-integrity-rule.
|
||
|
||
Invoking Commands
|
||
.................
|
||
|
||
When an enhanced relational-database is called with a symbol which
|
||
matches a NAME in the `*commands*' table, the associated procedure
|
||
expression is evaluated and applied to the enhanced
|
||
relational-database. A procedure should then be returned which the user
|
||
can invoke on (optional) arguments.
|
||
|
||
The command `*initialize*' is special. If present in the
|
||
`*commands*' table, `open-database' or `open-database!' will return the
|
||
value of the `*initialize*' command. Notice that arbitrary code can be
|
||
run when the `*initialize*' procedure is automatically applied to the
|
||
enhanced relational-database.
|
||
|
||
Note also that if you wish to shadow or hide from the user
|
||
relational-database methods described in *Note Relational Database
|
||
Operations::, this can be done by a dispatch in the closure returned by
|
||
the `*initialize*' expression rather than by entries in the
|
||
`*commands*' table if it is desired that the underlying methods remain
|
||
accessible to code in the `*commands*' table.
|
||
|
||
- Function: make-command-server rdb table-name
|
||
Returns a procedure of 2 arguments, a (symbol) command and a
|
||
call-back procedure. When this returned procedure is called, it
|
||
looks up COMMAND in table TABLE-NAME and calls the call-back
|
||
procedure with arguments:
|
||
COMMAND
|
||
The COMMAND
|
||
|
||
COMMAND-VALUE
|
||
The result of evaluating the expression in the PROCEDURE
|
||
field of TABLE-NAME and calling it with RDB.
|
||
|
||
PARAMETER-NAME
|
||
A list of the "official" name of each parameter. Corresponds
|
||
to the `name' field of the COMMAND's parameter-table.
|
||
|
||
POSITIONS
|
||
A list of the positive integer index of each parameter.
|
||
Corresponds to the `index' field of the COMMAND's
|
||
parameter-table.
|
||
|
||
ARITIES
|
||
A list of the arities of each parameter. Corresponds to the
|
||
`arity' field of the COMMAND's parameter-table. For a
|
||
description of `arity' see table above.
|
||
|
||
TYPES
|
||
A list of the type name of each parameter. Correspnds to the
|
||
`type-id' field of the contents of the `domain' of the
|
||
COMMAND's parameter-table.
|
||
|
||
DEFAULTERS
|
||
A list of the defaulters for each parameter. Corresponds to
|
||
the `defaulters' field of the COMMAND's parameter-table.
|
||
|
||
DOMAIN-INTEGRITY-RULES
|
||
A list of procedures (one for each parameter) which tests
|
||
whether a value for a parameter is acceptable for that
|
||
parameter. The procedure should be called with each datum in
|
||
the list for `nary' arity parameters.
|
||
|
||
ALIASES
|
||
A list of lists of `(alias parameter-name)'. There can be
|
||
more than one alias per PARAMETER-NAME.
|
||
|
||
For information about parameters, *Note Parameter lists::. Here is an
|
||
example of setting up a command with arguments and parsing those
|
||
arguments from a `getopt' style argument list (*note Getopt::).
|
||
|
||
(require 'database-utilities)
|
||
(require 'fluid-let)
|
||
(require 'parameters)
|
||
(require 'getopt)
|
||
|
||
(define my-rdb (create-database #f 'alist-table))
|
||
|
||
(define-tables my-rdb
|
||
'(foo-params
|
||
*parameter-columns*
|
||
*parameter-columns*
|
||
((1 single-string single string
|
||
(lambda (pl) '("str")) #f "single string")
|
||
(2 nary-symbols nary symbol
|
||
(lambda (pl) '()) #f "zero or more symbols")
|
||
(3 nary1-symbols nary1 symbol
|
||
(lambda (pl) '(symb)) #f "one or more symbols")
|
||
(4 optional-number optional uint
|
||
(lambda (pl) '()) #f "zero or one number")
|
||
(5 flag boolean boolean
|
||
(lambda (pl) '(#f)) #f "a boolean flag")))
|
||
'(foo-pnames
|
||
((name string))
|
||
((parameter-index uint))
|
||
(("s" 1)
|
||
("single-string" 1)
|
||
("n" 2)
|
||
("nary-symbols" 2)
|
||
("N" 3)
|
||
("nary1-symbols" 3)
|
||
("o" 4)
|
||
("optional-number" 4)
|
||
("f" 5)
|
||
("flag" 5)))
|
||
'(my-commands
|
||
((name symbol))
|
||
((parameters parameter-list)
|
||
(parameter-names parameter-name-translation)
|
||
(procedure expression)
|
||
(documentation string))
|
||
((foo
|
||
foo-params
|
||
foo-pnames
|
||
(lambda (rdb) (lambda args (print args)))
|
||
"test command arguments"))))
|
||
|
||
(define (dbutil:serve-command-line rdb command-table
|
||
command argc argv)
|
||
(set! argv (if (vector? argv) (vector->list argv) argv))
|
||
((make-command-server rdb command-table)
|
||
command
|
||
(lambda (comname comval options positions
|
||
arities types defaulters dirs aliases)
|
||
(apply comval (getopt->arglist
|
||
argc argv options positions
|
||
arities types defaulters dirs aliases)))))
|
||
|
||
(define (cmd . opts)
|
||
(fluid-let ((*optind* 1))
|
||
(printf "%-34s => "
|
||
(call-with-output-string
|
||
(lambda (pt) (write (cons 'cmd opts) pt))))
|
||
(set! opts (cons "cmd" opts))
|
||
(force-output)
|
||
(dbutil:serve-command-line
|
||
my-rdb 'my-commands 'foo (length opts) opts)))
|
||
|
||
(cmd) => ("str" () (symb) () #f)
|
||
(cmd "-f") => ("str" () (symb) () #t)
|
||
(cmd "--flag") => ("str" () (symb) () #t)
|
||
(cmd "-o177") => ("str" () (symb) (177) #f)
|
||
(cmd "-o" "177") => ("str" () (symb) (177) #f)
|
||
(cmd "--optional" "621") => ("str" () (symb) (621) #f)
|
||
(cmd "--optional=621") => ("str" () (symb) (621) #f)
|
||
(cmd "-s" "speciality") => ("speciality" () (symb) () #f)
|
||
(cmd "-sspeciality") => ("speciality" () (symb) () #f)
|
||
(cmd "--single" "serendipity") => ("serendipity" () (symb) () #f)
|
||
(cmd "--single=serendipity") => ("serendipity" () (symb) () #f)
|
||
(cmd "-n" "gravity" "piety") => ("str" () (piety gravity) () #f)
|
||
(cmd "-ngravity" "piety") => ("str" () (piety gravity) () #f)
|
||
(cmd "--nary" "chastity") => ("str" () (chastity) () #f)
|
||
(cmd "--nary=chastity" "") => ("str" () ( chastity) () #f)
|
||
(cmd "-N" "calamity") => ("str" () (calamity) () #f)
|
||
(cmd "-Ncalamity") => ("str" () (calamity) () #f)
|
||
(cmd "--nary1" "surety") => ("str" () (surety) () #f)
|
||
(cmd "--nary1=surety") => ("str" () (surety) () #f)
|
||
(cmd "-N" "levity" "fealty") => ("str" () (fealty levity) () #f)
|
||
(cmd "-Nlevity" "fealty") => ("str" () (fealty levity) () #f)
|
||
(cmd "--nary1" "surety" "brevity") => ("str" () (brevity surety) () #f)
|
||
(cmd "--nary1=surety" "brevity") => ("str" () (brevity surety) () #f)
|
||
(cmd "-?")
|
||
-|
|
||
Usage: cmd [OPTION ARGUMENT ...] ...
|
||
|
||
-f, --flag
|
||
-o, --optional[=]<number>
|
||
-n, --nary[=]<symbols> ...
|
||
-N, --nary1[=]<symbols> ...
|
||
-s, --single[=]<string>
|
||
|
||
ERROR: getopt->parameter-list "unrecognized option" "-?"
|
||
|
||
Some commands are defined in all extended relational-databases. The
|
||
are called just like *Note Relational Database Operations::.
|
||
|
||
- Function: add-domain domain-row
|
||
Adds DOMAIN-ROW to the "domains" table if there is no row in the
|
||
domains table associated with key `(car DOMAIN-ROW)' and returns
|
||
`#t'. Otherwise returns `#f'.
|
||
|
||
For the fields and layout of the domain table, *Note Catalog
|
||
Representation::. Currently, these fields are
|
||
* domain-name
|
||
|
||
* foreign-table
|
||
|
||
* domain-integrity-rule
|
||
|
||
* type-id
|
||
|
||
* type-param
|
||
|
||
The following example adds 3 domains to the `build' database.
|
||
`Optstring' is either a string or `#f'. `filename' is a string
|
||
and `build-whats' is a symbol.
|
||
|
||
(for-each (build 'add-domain)
|
||
'((optstring #f
|
||
(lambda (x) (or (not x) (string? x)))
|
||
string
|
||
#f)
|
||
(filename #f #f string #f)
|
||
(build-whats #f #f symbol #f)))
|
||
|
||
- Function: delete-domain domain-name
|
||
Removes and returns the DOMAIN-NAME row from the "domains" table.
|
||
|
||
- Function: domain-checker domain
|
||
Returns a procedure to check an argument for conformance to domain
|
||
DOMAIN.
|
||
|
||
Defining Tables
|
||
...............
|
||
|
||
- Procedure: define-tables rdb spec-0 ...
|
||
Adds tables as specified in SPEC-0 ... to the open
|
||
relational-database RDB. Each SPEC has the form:
|
||
|
||
(<name> <descriptor-name> <descriptor-name> <rows>)
|
||
or
|
||
(<name> <primary-key-fields> <other-fields> <rows>)
|
||
|
||
where <name> is the table name, <descriptor-name> is the symbol
|
||
name of a descriptor table, <primary-key-fields> and
|
||
<other-fields> describe the primary keys and other fields
|
||
respectively, and <rows> is a list of data rows to be added to the
|
||
table.
|
||
|
||
<primary-key-fields> and <other-fields> are lists of field
|
||
descriptors of the form:
|
||
|
||
(<column-name> <domain>)
|
||
or
|
||
(<column-name> <domain> <column-integrity-rule>)
|
||
|
||
where <column-name> is the column name, <domain> is the domain of
|
||
the column, and <column-integrity-rule> is an expression whose
|
||
value is a procedure of one argument (which returns `#f' to signal
|
||
an error).
|
||
|
||
If <domain> is not a defined domain name and it matches the name of
|
||
this table or an already defined (in one of SPEC-0 ...) single key
|
||
field table, a foriegn-key domain will be created for it.
|
||
|
||
The following example shows a new database with the name of `foo.db'
|
||
being created with tables describing processor families and
|
||
processor/os/compiler combinations.
|
||
|
||
The database command `define-tables' is defined to call `define-tables'
|
||
with its arguments. The database is also configured to print `Welcome'
|
||
when the database is opened. The database is then closed and reopened.
|
||
|
||
(require 'database-utilities)
|
||
(define my-rdb (create-database "foo.db" 'alist-table))
|
||
|
||
(define-tables my-rdb
|
||
'(*commands*
|
||
((name symbol))
|
||
((parameters parameter-list)
|
||
(procedure expression)
|
||
(documentation string))
|
||
((define-tables
|
||
no-parameters
|
||
no-parameter-names
|
||
(lambda (rdb) (lambda specs (apply define-tables rdb specs)))
|
||
"Create or Augment tables from list of specs")
|
||
(*initialize*
|
||
no-parameters
|
||
no-parameter-names
|
||
(lambda (rdb) (display "Welcome") (newline) rdb)
|
||
"Print Welcome"))))
|
||
|
||
((my-rdb 'define-tables)
|
||
'(processor-family
|
||
((family atom))
|
||
((also-ran processor-family))
|
||
((m68000 #f)
|
||
(m68030 m68000)
|
||
(i386 8086)
|
||
(8086 #f)
|
||
(powerpc #f)))
|
||
|
||
'(platform
|
||
((name symbol))
|
||
((processor processor-family)
|
||
(os symbol)
|
||
(compiler symbol))
|
||
((aix powerpc aix -)
|
||
(amiga-dice-c m68000 amiga dice-c)
|
||
(amiga-aztec m68000 amiga aztec)
|
||
(amiga-sas/c-5.10 m68000 amiga sas/c)
|
||
(atari-st-gcc m68000 atari gcc)
|
||
(atari-st-turbo-c m68000 atari turbo-c)
|
||
(borland-c-3.1 8086 ms-dos borland-c)
|
||
(djgpp i386 ms-dos gcc)
|
||
(linux i386 linux gcc)
|
||
(microsoft-c 8086 ms-dos microsoft-c)
|
||
(os/2-emx i386 os/2 gcc)
|
||
(turbo-c-2 8086 ms-dos turbo-c)
|
||
(watcom-9.0 i386 ms-dos watcom))))
|
||
|
||
((my-rdb 'close-database))
|
||
|
||
(set! my-rdb (open-database "foo.db" 'alist-table))
|
||
-|
|
||
Welcome
|
||
|
||
Listing Tables |
|
||
.............. |
|
||
|
|
||
- Procedure: list-table-definition rdb table-name |
|
||
If symbol TABLE-NAME exists in the open relational-database RDB, |
|
||
then returns a list of the table-name, its primary key names and |
|
||
domains, its other key names and domains, and the table's records |
|
||
(as lists). Otherwise, returns #f. |
|
||
|
|
||
The list returned by `list-table-definition', when passed as an |
|
||
argument to `define-tables', will recreate the table. |
|
||
|
|
||
|
||
File: slib.info, Node: Database Reports, Next: Database Browser, Prev: Database Utilities, Up: Relational Database
|
||
|
||
Database Reports
|
||
----------------
|
||
|
||
Code for generating database reports is in `report.scm'. After writing
|
||
it using `format', I discovered that Common-Lisp `format' is not
|
||
useable for this application because there is no mechanismm for
|
||
truncating fields. `report.scm' needs to be rewritten using `printf'.
|
||
|
||
- Procedure: create-report rdb destination report-name table
|
||
- Procedure: create-report rdb destination report-name
|
||
The symbol REPORT-NAME must be primary key in the table named
|
||
`*reports*' in the relational database RDB. DESTINATION is a
|
||
port, string, or symbol. If DESTINATION is a:
|
||
|
||
port
|
||
The table is created as ascii text and written to that port.
|
||
|
||
string
|
||
The table is created as ascii text and written to the file
|
||
named by DESTINATION.
|
||
|
||
symbol
|
||
DESTINATION is the primary key for a row in the table named
|
||
*printers*.
|
||
|
||
The report is prepared as follows:
|
||
|
||
* `Format' (*note Format::) is called with the `header' field
|
||
and the (list of) `column-names' of the table.
|
||
|
||
* `Format' is called with the `reporter' field and (on
|
||
successive calls) each record in the natural order for the
|
||
table. A count is kept of the number of newlines output by
|
||
format. When the number of newlines to be output exceeds the
|
||
number of lines per page, the set of lines will be broken if
|
||
there are more than `minimum-break' left on this page and the
|
||
number of lines for this row is larger or equal to twice
|
||
`minimum-break'.
|
||
|
||
* `Format' is called with the `footer' field and the (list of)
|
||
`column-names' of the table. The footer field should not
|
||
output a newline.
|
||
|
||
* A new page is output.
|
||
|
||
* This entire process repeats until all the rows are output.
|
||
|
||
Each row in the table *reports* has the fields:
|
||
|
||
name
|
||
The report name.
|
||
|
||
default-table
|
||
The table to report on if none is specified.
|
||
|
||
header, footer
|
||
A `format' string. At the beginning and end of each page
|
||
respectively, `format' is called with this string and the (list of)
|
||
column-names of this table.
|
||
|
||
reporter
|
||
A `format' string. For each row in the table, `format' is called
|
||
with this string and the row.
|
||
|
||
minimum-break
|
||
The minimum number of lines into which the report lines for a row
|
||
can be broken. Use `0' if a row's lines should not be broken over
|
||
page boundaries.
|
||
|
||
Each row in the table *printers* has the fields:
|
||
|
||
name
|
||
The printer name.
|
||
|
||
print-procedure
|
||
The procedure to call to actually print.
|
||
|
||
|
||
File: slib.info, Node: Database Browser, Prev: Database Reports, Up: Relational Database
|
||
|
||
Database Browser
|
||
----------------
|
||
|
||
(require 'database-browse)
|
||
|
||
- Procedure: browse database
|
||
Prints the names of all the tables in DATABASE and sets browse's
|
||
default to DATABASE.
|
||
|
||
- Procedure: browse
|
||
Prints the names of all the tables in the default database.
|
||
|
||
- Procedure: browse table-name
|
||
For each record of the table named by the symbol TABLE-NAME,
|
||
prints a line composed of all the field values.
|
||
|
||
- Procedure: browse pathname
|
||
Opens the database named by the string PATHNAME, prints the names
|
||
of all its tables, and sets browse's default to the database.
|
||
|
||
- Procedure: browse database table-name
|
||
Sets browse's default to DATABASE and prints the records of the
|
||
table named by the symbol TABLE-NAME.
|
||
|
||
- Procedure: browse pathname table-name
|
||
Opens the database named by the string PATHNAME and sets browse's
|
||
default to it; `browse' prints the records of the table named by
|
||
the symbol TABLE-NAME.
|
||
|
||
|
||
|
||
File: slib.info, Node: Weight-Balanced Trees, Prev: Relational Database, Up: Database Packages
|
||
|
||
Weight-Balanced Trees
|
||
=====================
|
||
|
||
`(require 'wt-tree)'
|
||
|
||
Balanced binary trees are a useful data structure for maintaining
|
||
large sets of ordered objects or sets of associations whose keys are
|
||
ordered. MIT Scheme has an comprehensive implementation of
|
||
weight-balanced binary trees which has several advantages over the
|
||
other data structures for large aggregates:
|
||
|
||
* In addition to the usual element-level operations like insertion,
|
||
deletion and lookup, there is a full complement of collection-level
|
||
operations, like set intersection, set union and subset test, all
|
||
of which are implemented with good orders of growth in time and
|
||
space. This makes weight balanced trees ideal for rapid
|
||
prototyping of functionally derived specifications.
|
||
|
||
* An element in a tree may be indexed by its position under the
|
||
ordering of the keys, and the ordinal position of an element may
|
||
be determined, both with reasonable efficiency.
|
||
|
||
* Operations to find and remove minimum element make weight balanced
|
||
trees simple to use for priority queues.
|
||
|
||
* The implementation is _functional_ rather than _imperative_. This
|
||
means that operations like `inserting' an association in a tree do
|
||
not destroy the old tree, in much the same way that `(+ 1 x)'
|
||
modifies neither the constant 1 nor the value bound to `x'. The
|
||
trees are referentially transparent thus the programmer need not
|
||
worry about copying the trees. Referential transparency allows
|
||
space efficiency to be achieved by sharing subtrees.
|
||
|
||
|
||
These features make weight-balanced trees suitable for a wide range of
|
||
applications, especially those that require large numbers of sets or
|
||
discrete maps. Applications that have a few global databases and/or
|
||
concentrate on element-level operations like insertion and lookup are
|
||
probably better off using hash-tables or red-black trees.
|
||
|
||
The _size_ of a tree is the number of associations that it contains.
|
||
Weight balanced binary trees are balanced to keep the sizes of the
|
||
subtrees of each node within a constant factor of each other. This
|
||
ensures logarithmic times for single-path operations (like lookup and
|
||
insertion). A weight balanced tree takes space that is proportional to
|
||
the number of associations in the tree. For the current
|
||
implementation, the constant of proportionality is six words per
|
||
association.
|
||
|
||
Weight balanced trees can be used as an implementation for either
|
||
discrete sets or discrete maps (associations). Sets are implemented by
|
||
ignoring the datum that is associated with the key. Under this scheme
|
||
if an associations exists in the tree this indicates that the key of the
|
||
association is a member of the set. Typically a value such as `()',
|
||
`#t' or `#f' is associated with the key.
|
||
|
||
Many operations can be viewed as computing a result that, depending on
|
||
whether the tree arguments are thought of as sets or maps, is known by
|
||
two different names. An example is `wt-tree/member?', which, when
|
||
regarding the tree argument as a set, computes the set membership
|
||
operation, but, when regarding the tree as a discrete map,
|
||
`wt-tree/member?' is the predicate testing if the map is defined at an
|
||
element in its domain. Most names in this package have been chosen
|
||
based on interpreting the trees as sets, hence the name
|
||
`wt-tree/member?' rather than `wt-tree/defined-at?'.
|
||
|
||
The weight balanced tree implementation is a run-time-loadable option.
|
||
To use weight balanced trees, execute
|
||
|
||
(load-option 'wt-tree)
|
||
|
||
once before calling any of the procedures defined here.
|
||
|
||
* Menu:
|
||
|
||
* Construction of Weight-Balanced Trees::
|
||
* Basic Operations on Weight-Balanced Trees::
|
||
* Advanced Operations on Weight-Balanced Trees::
|
||
* Indexing Operations on Weight-Balanced Trees::
|
||
|
||
|
||
File: slib.info, Node: Construction of Weight-Balanced Trees, Next: Basic Operations on Weight-Balanced Trees, Prev: Weight-Balanced Trees, Up: Weight-Balanced Trees
|
||
|
||
Construction of Weight-Balanced Trees
|
||
-------------------------------------
|
||
|
||
Binary trees require there to be a total order on the keys used to
|
||
arrange the elements in the tree. Weight balanced trees are organized
|
||
by _types_, where the type is an object encapsulating the ordering
|
||
relation. Creating a tree is a two-stage process. First a tree type
|
||
must be created from the predicate which gives the ordering. The tree
|
||
type is then used for making trees, either empty or singleton trees or
|
||
trees from other aggregate structures like association lists. Once
|
||
created, a tree `knows' its type and the type is used to test
|
||
compatibility between trees in operations taking two trees. Usually a
|
||
small number of tree types are created at the beginning of a program and
|
||
used many times throughout the program's execution.
|
||
|
||
- procedure+: make-wt-tree-type key<?
|
||
This procedure creates and returns a new tree type based on the
|
||
ordering predicate KEY<?. KEY<? must be a total ordering, having
|
||
the property that for all key values `a', `b' and `c':
|
||
|
||
(key<? a a) => #f
|
||
(and (key<? a b) (key<? b a)) => #f
|
||
(if (and (key<? a b) (key<? b c))
|
||
(key<? a c)
|
||
#t) => #t
|
||
|
||
Two key values are assumed to be equal if neither is less than the
|
||
other by KEY<?.
|
||
|
||
Each call to `make-wt-tree-type' returns a distinct value, and
|
||
trees are only compatible if their tree types are `eq?'. A
|
||
consequence is that trees that are intended to be used in binary
|
||
tree operations must all be created with a tree type originating
|
||
from the same call to `make-wt-tree-type'.
|
||
|
||
- variable+: number-wt-type
|
||
A standard tree type for trees with numeric keys. `Number-wt-type'
|
||
could have been defined by
|
||
|
||
(define number-wt-type (make-wt-tree-type <))
|
||
|
||
- variable+: string-wt-type
|
||
A standard tree type for trees with string keys. `String-wt-type'
|
||
could have been defined by
|
||
|
||
(define string-wt-type (make-wt-tree-type string<?))
|
||
|
||
- procedure+: make-wt-tree wt-tree-type
|
||
This procedure creates and returns a newly allocated weight
|
||
balanced tree. The tree is empty, i.e. it contains no
|
||
associations. WT-TREE-TYPE is a weight balanced tree type
|
||
obtained by calling `make-wt-tree-type'; the returned tree has
|
||
this type.
|
||
|
||
- procedure+: singleton-wt-tree wt-tree-type key datum
|
||
This procedure creates and returns a newly allocated weight
|
||
balanced tree. The tree contains a single association, that of
|
||
DATUM with KEY. WT-TREE-TYPE is a weight balanced tree type
|
||
obtained by calling `make-wt-tree-type'; the returned tree has
|
||
this type.
|
||
|
||
- procedure+: alist->wt-tree tree-type alist
|
||
Returns a newly allocated weight-balanced tree that contains the
|
||
same associations as ALIST. This procedure is equivalent to:
|
||
|
||
(lambda (type alist)
|
||
(let ((tree (make-wt-tree type)))
|
||
(for-each (lambda (association)
|
||
(wt-tree/add! tree
|
||
(car association)
|
||
(cdr association)))
|
||
alist)
|
||
tree))
|
||
|
||
|
||
File: slib.info, Node: Basic Operations on Weight-Balanced Trees, Next: Advanced Operations on Weight-Balanced Trees, Prev: Construction of Weight-Balanced Trees, Up: Weight-Balanced Trees
|
||
|
||
Basic Operations on Weight-Balanced Trees
|
||
-----------------------------------------
|
||
|
||
This section describes the basic tree operations on weight balanced
|
||
trees. These operations are the usual tree operations for insertion,
|
||
deletion and lookup, some predicates and a procedure for determining the
|
||
number of associations in a tree.
|
||
|
||
- procedure+: wt-tree? object
|
||
Returns `#t' if OBJECT is a weight-balanced tree, otherwise
|
||
returns `#f'.
|
||
|
||
- procedure+: wt-tree/empty? wt-tree
|
||
Returns `#t' if WT-TREE contains no associations, otherwise
|
||
returns `#f'.
|
||
|
||
- procedure+: wt-tree/size wt-tree
|
||
Returns the number of associations in WT-TREE, an exact
|
||
non-negative integer. This operation takes constant time.
|
||
|
||
- procedure+: wt-tree/add wt-tree key datum
|
||
Returns a new tree containing all the associations in WT-TREE and
|
||
the association of DATUM with KEY. If WT-TREE already had an
|
||
association for KEY, the new association overrides the old. The
|
||
average and worst-case times required by this operation are
|
||
proportional to the logarithm of the number of associations in
|
||
WT-TREE.
|
||
|
||
- procedure+: wt-tree/add! wt-tree key datum
|
||
Associates DATUM with KEY in WT-TREE and returns an unspecified
|
||
value. If WT-TREE already has an association for KEY, that
|
||
association is replaced. The average and worst-case times
|
||
required by this operation are proportional to the logarithm of
|
||
the number of associations in WT-TREE.
|
||
|
||
- procedure+: wt-tree/member? key wt-tree
|
||
Returns `#t' if WT-TREE contains an association for KEY, otherwise
|
||
returns `#f'. The average and worst-case times required by this
|
||
operation are proportional to the logarithm of the number of
|
||
associations in WT-TREE.
|
||
|
||
- procedure+: wt-tree/lookup wt-tree key default
|
||
Returns the datum associated with KEY in WT-TREE. If WT-TREE
|
||
doesn't contain an association for KEY, DEFAULT is returned. The
|
||
average and worst-case times required by this operation are
|
||
proportional to the logarithm of the number of associations in
|
||
WT-TREE.
|
||
|
||
- procedure+: wt-tree/delete wt-tree key
|
||
Returns a new tree containing all the associations in WT-TREE,
|
||
except that if WT-TREE contains an association for KEY, it is
|
||
removed from the result. The average and worst-case times required
|
||
by this operation are proportional to the logarithm of the number
|
||
of associations in WT-TREE.
|
||
|
||
- procedure+: wt-tree/delete! wt-tree key
|
||
If WT-TREE contains an association for KEY the association is
|
||
removed. Returns an unspecified value. The average and worst-case
|
||
times required by this operation are proportional to the logarithm
|
||
of the number of associations in WT-TREE.
|
||
|
||
|
||
File: slib.info, Node: Advanced Operations on Weight-Balanced Trees, Next: Indexing Operations on Weight-Balanced Trees, Prev: Basic Operations on Weight-Balanced Trees, Up: Weight-Balanced Trees
|
||
|
||
Advanced Operations on Weight-Balanced Trees
|
||
--------------------------------------------
|
||
|
||
In the following the _size_ of a tree is the number of associations
|
||
that the tree contains, and a _smaller_ tree contains fewer
|
||
associations.
|
||
|
||
- procedure+: wt-tree/split< wt-tree bound
|
||
Returns a new tree containing all and only the associations in
|
||
WT-TREE which have a key that is less than BOUND in the ordering
|
||
relation of the tree type of WT-TREE. The average and worst-case
|
||
times required by this operation are proportional to the logarithm
|
||
of the size of WT-TREE.
|
||
|
||
- procedure+: wt-tree/split> wt-tree bound
|
||
Returns a new tree containing all and only the associations in
|
||
WT-TREE which have a key that is greater than BOUND in the
|
||
ordering relation of the tree type of WT-TREE. The average and
|
||
worst-case times required by this operation are proportional to the
|
||
logarithm of size of WT-TREE.
|
||
|
||
- procedure+: wt-tree/union wt-tree-1 wt-tree-2
|
||
Returns a new tree containing all the associations from both trees.
|
||
This operation is asymmetric: when both trees have an association
|
||
for the same key, the returned tree associates the datum from
|
||
WT-TREE-2 with the key. Thus if the trees are viewed as discrete
|
||
maps then `wt-tree/union' computes the map override of WT-TREE-1 by
|
||
WT-TREE-2. If the trees are viewed as sets the result is the set
|
||
union of the arguments. The worst-case time required by this
|
||
operation is proportional to the sum of the sizes of both trees.
|
||
If the minimum key of one tree is greater than the maximum key of
|
||
the other tree then the time required is at worst proportional to
|
||
the logarithm of the size of the larger tree.
|
||
|
||
- procedure+: wt-tree/intersection wt-tree-1 wt-tree-2
|
||
Returns a new tree containing all and only those associations from
|
||
WT-TREE-1 which have keys appearing as the key of an association
|
||
in WT-TREE-2. Thus the associated data in the result are those
|
||
from WT-TREE-1. If the trees are being used as sets the result is
|
||
the set intersection of the arguments. As a discrete map
|
||
operation, `wt-tree/intersection' computes the domain restriction
|
||
of WT-TREE-1 to (the domain of) WT-TREE-2. The time required by
|
||
this operation is never worse that proportional to the sum of the
|
||
sizes of the trees.
|
||
|
||
- procedure+: wt-tree/difference wt-tree-1 wt-tree-2
|
||
Returns a new tree containing all and only those associations from
|
||
WT-TREE-1 which have keys that _do not_ appear as the key of an
|
||
association in WT-TREE-2. If the trees are viewed as sets the
|
||
result is the asymmetric set difference of the arguments. As a
|
||
discrete map operation, it computes the domain restriction of
|
||
WT-TREE-1 to the complement of (the domain of) WT-TREE-2. The
|
||
time required by this operation is never worse that proportional to
|
||
the sum of the sizes of the trees.
|
||
|
||
- procedure+: wt-tree/subset? wt-tree-1 wt-tree-2
|
||
Returns `#t' iff the key of each association in WT-TREE-1 is the
|
||
key of some association in WT-TREE-2, otherwise returns `#f'.
|
||
Viewed as a set operation, `wt-tree/subset?' is the improper subset
|
||
predicate. A proper subset predicate can be constructed:
|
||
|
||
(define (proper-subset? s1 s2)
|
||
(and (wt-tree/subset? s1 s2)
|
||
(< (wt-tree/size s1) (wt-tree/size s2))))
|
||
|
||
As a discrete map operation, `wt-tree/subset?' is the subset test
|
||
on the domain(s) of the map(s). In the worst-case the time
|
||
required by this operation is proportional to the size of
|
||
WT-TREE-1.
|
||
|
||
- procedure+: wt-tree/set-equal? wt-tree-1 wt-tree-2
|
||
Returns `#t' iff for every association in WT-TREE-1 there is an
|
||
association in WT-TREE-2 that has the same key, and _vice versa_.
|
||
|
||
Viewing the arguments as sets `wt-tree/set-equal?' is the set
|
||
equality predicate. As a map operation it determines if two maps
|
||
are defined on the same domain.
|
||
|
||
This procedure is equivalent to
|
||
|
||
(lambda (wt-tree-1 wt-tree-2)
|
||
(and (wt-tree/subset? wt-tree-1 wt-tree-2
|
||
(wt-tree/subset? wt-tree-2 wt-tree-1)))
|
||
|
||
In the worst-case the time required by this operation is
|
||
proportional to the size of the smaller tree.
|
||
|
||
- procedure+: wt-tree/fold combiner initial wt-tree
|
||
This procedure reduces WT-TREE by combining all the associations,
|
||
using an reverse in-order traversal, so the associations are
|
||
visited in reverse order. COMBINER is a procedure of three
|
||
arguments: a key, a datum and the accumulated result so far.
|
||
Provided COMBINER takes time bounded by a constant, `wt-tree/fold'
|
||
takes time proportional to the size of WT-TREE.
|
||
|
||
A sorted association list can be derived simply:
|
||
|
||
(wt-tree/fold (lambda (key datum list)
|
||
(cons (cons key datum) list))
|
||
'()
|
||
WT-TREE))
|
||
|
||
The data in the associations can be summed like this:
|
||
|
||
(wt-tree/fold (lambda (key datum sum) (+ sum datum))
|
||
0
|
||
WT-TREE)
|
||
|
||
- procedure+: wt-tree/for-each action wt-tree
|
||
This procedure traverses the tree in-order, applying ACTION to
|
||
each association. The associations are processed in increasing
|
||
order of their keys. ACTION is a procedure of two arguments which
|
||
take the key and datum respectively of the association. Provided
|
||
ACTION takes time bounded by a constant, `wt-tree/for-each' takes
|
||
time proportional to in the size of WT-TREE. The example prints
|
||
the tree:
|
||
|
||
(wt-tree/for-each (lambda (key value)
|
||
(display (list key value)))
|
||
WT-TREE))
|
||
|
||
|
||
File: slib.info, Node: Indexing Operations on Weight-Balanced Trees, Prev: Advanced Operations on Weight-Balanced Trees, Up: Weight-Balanced Trees
|
||
|
||
Indexing Operations on Weight-Balanced Trees
|
||
--------------------------------------------
|
||
|
||
Weight balanced trees support operations that view the tree as sorted
|
||
sequence of associations. Elements of the sequence can be accessed by
|
||
position, and the position of an element in the sequence can be
|
||
determined, both in logarthmic time.
|
||
|
||
- procedure+: wt-tree/index wt-tree index
|
||
- procedure+: wt-tree/index-datum wt-tree index
|
||
- procedure+: wt-tree/index-pair wt-tree index
|
||
Returns the 0-based INDEXth association of WT-TREE in the sorted
|
||
sequence under the tree's ordering relation on the keys.
|
||
`wt-tree/index' returns the INDEXth key, `wt-tree/index-datum'
|
||
returns the datum associated with the INDEXth key and
|
||
`wt-tree/index-pair' returns a new pair `(KEY . DATUM)' which is
|
||
the `cons' of the INDEXth key and its datum. The average and
|
||
worst-case times required by this operation are proportional to
|
||
the logarithm of the number of associations in the tree.
|
||
|
||
These operations signal an error if the tree is empty, if
|
||
INDEX`<0', or if INDEX is greater than or equal to the number of
|
||
associations in the tree.
|
||
|
||
Indexing can be used to find the median and maximum keys in the
|
||
tree as follows:
|
||
|
||
median: (wt-tree/index WT-TREE
|
||
(quotient (wt-tree/size WT-TREE) 2))
|
||
|
||
maximum: (wt-tree/index WT-TREE
|
||
(-1+ (wt-tree/size WT-TREE)))
|
||
|
||
- procedure+: wt-tree/rank wt-tree key
|
||
Determines the 0-based position of KEY in the sorted sequence of
|
||
the keys under the tree's ordering relation, or `#f' if the tree
|
||
has no association with for KEY. This procedure returns either an
|
||
exact non-negative integer or `#f'. The average and worst-case
|
||
times required by this operation are proportional to the logarithm
|
||
of the number of associations in the tree.
|
||
|
||
- procedure+: wt-tree/min wt-tree
|
||
- procedure+: wt-tree/min-datum wt-tree
|
||
- procedure+: wt-tree/min-pair wt-tree
|
||
Returns the association of WT-TREE that has the least key under
|
||
the tree's ordering relation. `wt-tree/min' returns the least key,
|
||
`wt-tree/min-datum' returns the datum associated with the least key
|
||
and `wt-tree/min-pair' returns a new pair `(key . datum)' which is
|
||
the `cons' of the minimum key and its datum. The average and
|
||
worst-case times required by this operation are proportional to the
|
||
logarithm of the number of associations in the tree.
|
||
|
||
These operations signal an error if the tree is empty. They could
|
||
be written
|
||
(define (wt-tree/min tree) (wt-tree/index tree 0))
|
||
(define (wt-tree/min-datum tree) (wt-tree/index-datum tree 0))
|
||
(define (wt-tree/min-pair tree) (wt-tree/index-pair tree 0))
|
||
|
||
- procedure+: wt-tree/delete-min wt-tree
|
||
Returns a new tree containing all of the associations in WT-TREE
|
||
except the association with the least key under the WT-TREE's
|
||
ordering relation. An error is signalled if the tree is empty.
|
||
The average and worst-case times required by this operation are
|
||
proportional to the logarithm of the number of associations in the
|
||
tree. This operation is equivalent to
|
||
|
||
(wt-tree/delete WT-TREE (wt-tree/min WT-TREE))
|
||
|
||
- procedure+: wt-tree/delete-min! wt-tree
|
||
Removes the association with the least key under the WT-TREE's
|
||
ordering relation. An error is signalled if the tree is empty.
|
||
The average and worst-case times required by this operation are
|
||
proportional to the logarithm of the number of associations in the
|
||
tree. This operation is equivalent to
|
||
|
||
(wt-tree/delete! WT-TREE (wt-tree/min WT-TREE))
|
||
|
||
|
||
File: slib.info, Node: Other Packages, Next: About SLIB, Prev: Database Packages, Up: Top
|
||
|
||
Other Packages
|
||
**************
|
||
|
||
* Menu:
|
||
|
||
* Data Structures:: Various data structures.
|
||
* Procedures:: Miscellaneous utility procedures.
|
||
* Standards Support:: Support for Scheme Standards.
|
||
* Session Support:: REPL and Debugging.
|
||
* Extra-SLIB Packages::
|
||
|
||
|
||
File: slib.info, Node: Data Structures, Next: Procedures, Prev: Other Packages, Up: Other Packages
|
||
|
||
Data Structures
|
||
===============
|
||
|
||
* Menu:
|
||
|
||
* Arrays:: 'array
|
||
* Array Mapping:: 'array-for-each
|
||
* Association Lists:: 'alist
|
||
* Byte:: 'byte
|
||
* Portable Image Files:: 'pnm
|
||
* Collections:: 'collect
|
||
* Dynamic Data Type:: 'dynamic
|
||
* Hash Tables:: 'hash-table
|
||
* Hashing:: 'hash, 'sierpinski, 'soundex
|
||
* Object:: 'object
|
||
* Priority Queues:: 'priority-queue
|
||
* Queues:: 'queue
|
||
* Records:: 'record
|
||
* Structures:: 'struct, 'structure
|
||
|
||
|
||
File: slib.info, Node: Arrays, Next: Array Mapping, Prev: Data Structures, Up: Data Structures
|
||
|
||
Arrays
|
||
------
|
||
|
||
`(require 'array)'
|
||
|
||
- Function: array? obj
|
||
Returns `#t' if the OBJ is an array, and `#f' if not.
|
||
|
||
- Function: make-array initial-value bound1 bound2 ...
|
||
Creates and returns an array that has as many dimensins as there
|
||
are BOUNDs and fills it with INITIAL-VALUE.
|
||
|
||
When constructing an array, BOUND is either an inclusive range of
|
||
indices expressed as a two element list, or an upper bound expressed as
|
||
a single integer. So
|
||
(make-array 'foo 3 3) == (make-array 'foo '(0 2) '(0 2))
|
||
|
||
- Function: make-shared-array array mapper bound1 bound2 ...
|
||
`make-shared-array' can be used to create shared subarrays of other
|
||
arrays. The MAPPER is a function that translates coordinates in
|
||
the new array into coordinates in the old array. A MAPPER must be
|
||
linear, and its range must stay within the bounds of the old
|
||
array, but it can be otherwise arbitrary. A simple example:
|
||
(define fred (make-array #f 8 8))
|
||
(define freds-diagonal
|
||
(make-shared-array fred (lambda (i) (list i i)) 8))
|
||
(array-set! freds-diagonal 'foo 3)
|
||
(array-ref fred 3 3)
|
||
=> FOO
|
||
(define freds-center
|
||
(make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j)))
|
||
2 2))
|
||
(array-ref freds-center 0 0)
|
||
=> FOO
|
||
|
||
- Function: array-rank obj
|
||
Returns the number of dimensions of OBJ. If OBJ is not an array,
|
||
0 is returned.
|
||
|
||
- Function: array-shape array
|
||
`array-shape' returns a list of inclusive bounds. So:
|
||
(array-shape (make-array 'foo 3 5))
|
||
=> ((0 2) (0 4))
|
||
|
||
- Function: array-dimensions array
|
||
`array-dimensions' is similar to `array-shape' but replaces
|
||
elements with a 0 minimum with one greater than the maximum. So:
|
||
(array-dimensions (make-array 'foo 3 5))
|
||
=> (3 5)
|
||
|
||
- Procedure: array-in-bounds? array index1 index2 ...
|
||
Returns `#t' if its arguments would be acceptable to `array-ref'.
|
||
|
||
- Function: array-ref array index1 index2 ...
|
||
Returns the element at the `(INDEX1, INDEX2)' element in ARRAY.
|
||
|
||
- Procedure: array-set! array new-value index1 index2 ...
|
||
|
||
- Function: array-1d-ref array index
|
||
- Function: array-2d-ref array index1 index2
|
||
- Function: array-3d-ref array index1 index2 index3
|
||
|
||
- Procedure: array-1d-set! array new-value index
|
||
- Procedure: array-2d-set! array new-value index1 index2
|
||
- Procedure: array-3d-set! array new-value index1 index2 index3
|
||
|
||
The functions are just fast versions of `array-ref' and `array-set!'
|
||
that take a fixed number of arguments, and perform no bounds checking.
|
||
|
||
If you comment out the bounds checking code, this is about as
|
||
efficient as you could ask for without help from the compiler.
|
||
|
||
An exercise left to the reader: implement the rest of APL.
|
||
|
||
|
||
File: slib.info, Node: Array Mapping, Next: Association Lists, Prev: Arrays, Up: Data Structures
|
||
|
||
Array Mapping
|
||
-------------
|
||
|
||
`(require 'array-for-each)'
|
||
|
||
- Function: array-map! array0 proc array1 ...
|
||
ARRAY1, ... must have the same number of dimensions as ARRAY0 and
|
||
have a range for each index which includes the range for the
|
||
corresponding index in ARRAY0. PROC is applied to each tuple of
|
||
elements of ARRAY1 ... and the result is stored as the
|
||
corresponding element in ARRAY0. The value returned is
|
||
unspecified. The order of application is unspecified.
|
||
|
||
- Function: array-for-each PROC ARRAY0 ...
|
||
PROC is applied to each tuple of elements of ARRAY0 ... in
|
||
row-major order. The value returned is unspecified.
|
||
|
||
- Function: array-indexes ARRAY
|
||
Returns an array of lists of indexes for ARRAY such that, if LI is
|
||
a list of indexes for which ARRAY is defined, (equal? LI (apply
|
||
array-ref (array-indexes ARRAY) LI)).
|
||
|
||
- Function: array-index-map! array proc
|
||
applies PROC to the indices of each element of ARRAY in turn,
|
||
storing the result in the corresponding element. The value
|
||
returned and the order of application are unspecified.
|
||
|
||
One can implement ARRAY-INDEXES as
|
||
(define (array-indexes array)
|
||
(let ((ra (apply make-array #f (array-shape array))))
|
||
(array-index-map! ra (lambda x x))
|
||
ra))
|
||
Another example:
|
||
(define (apl:index-generator n)
|
||
(let ((v (make-uniform-vector n 1)))
|
||
(array-index-map! v (lambda (i) i))
|
||
v))
|
||
|
||
- Function: array-copy! source destination
|
||
Copies every element from vector or array SOURCE to the
|
||
corresponding element of DESTINATION. DESTINATION must have the
|
||
same rank as SOURCE, and be at least as large in each dimension.
|
||
The order of copying is unspecified.
|
||
|
||
|
||
File: slib.info, Node: Association Lists, Next: Byte, Prev: Array Mapping, Up: Data Structures
|
||
|
||
Association Lists
|
||
-----------------
|
||
|
||
`(require 'alist)'
|
||
|
||
Alist functions provide utilities for treating a list of key-value
|
||
pairs as an associative database. These functions take an equality
|
||
predicate, PRED, as an argument. This predicate should be repeatable,
|
||
symmetric, and transitive.
|
||
|
||
Alist functions can be used with a secondary index method such as hash
|
||
tables for improved performance.
|
||
|
||
- Function: predicate->asso pred
|
||
Returns an "association function" (like `assq', `assv', or
|
||
`assoc') corresponding to PRED. The returned function returns a
|
||
key-value pair whose key is `pred'-equal to its first argument or
|
||
`#f' if no key in the alist is PRED-equal to the first argument.
|
||
|
||
- Function: alist-inquirer pred
|
||
Returns a procedure of 2 arguments, ALIST and KEY, which returns
|
||
the value associated with KEY in ALIST or `#f' if KEY does not
|
||
appear in ALIST.
|
||
|
||
- Function: alist-associator pred
|
||
Returns a procedure of 3 arguments, ALIST, KEY, and VALUE, which
|
||
returns an alist with KEY and VALUE associated. Any previous
|
||
value associated with KEY will be lost. This returned procedure
|
||
may or may not have side effects on its ALIST argument. An
|
||
example of correct usage is:
|
||
(define put (alist-associator string-ci=?))
|
||
(define alist '())
|
||
(set! alist (put alist "Foo" 9))
|
||
|
||
- Function: alist-remover pred
|
||
Returns a procedure of 2 arguments, ALIST and KEY, which returns
|
||
an alist with an association whose KEY is key removed. This
|
||
returned procedure may or may not have side effects on its ALIST
|
||
argument. An example of correct usage is:
|
||
(define rem (alist-remover string-ci=?))
|
||
(set! alist (rem alist "foo"))
|
||
|
||
- Function: alist-map proc alist
|
||
Returns a new association list formed by mapping PROC over the
|
||
keys and values of ALIST. PROC must be a function of 2 arguments
|
||
which returns the new value part.
|
||
|
||
- Function: alist-for-each proc alist
|
||
Applies PROC to each pair of keys and values of ALIST. PROC must
|
||
be a function of 2 arguments. The returned value is unspecified.
|
||
|
||
|
||
File: slib.info, Node: Byte, Next: Portable Image Files, Prev: Association Lists, Up: Data Structures
|
||
|
||
Byte
|
||
----
|
||
|
||
`(require 'byte)'
|
||
|
||
Some algorithms are expressed in terms of arrays of small integers.
|
||
Using Scheme strings to implement these arrays is not portable vis-a-vis
|
||
the correspondence between integers and characters and non-ascii
|
||
character sets. These functions abstract the notion of a "byte".
|
||
|
||
- Function: byte-ref bytes k
|
||
K must be a valid index of BYTES. `byte-ref' returns byte K of
|
||
BYTES using zero-origin indexing.
|
||
|
||
- Procedure: byte-set! bytes k byte
|
||
K must be a valid index of BYTES%, and BYTE must be a small
|
||
integer. `Byte-set!' stores BYTE in element K of BYTES and
|
||
returns an unspecified value.
|
||
|
||
- Function: make-bytes k
|
||
- Function: make-bytes k byte
|
||
`Make-bytes' returns a newly allocated byte-array of length K. If
|
||
BYTE is given, then all elements of the byte-array are initialized
|
||
to BYTE, otherwise the contents of the byte-array are unspecified.
|
||
|
||
|
||
- Function: bytes-length bytes
|
||
`bytes-length' returns length of byte-array BYTES.
|
||
|
||
|
||
- Function: write-byte byte
|
||
- Function: write-byte byte port
|
||
Writes the byte BYTE (not an external representation of the byte)
|
||
to the given PORT and returns an unspecified value. The PORT
|
||
argument may be omitted, in which case it defaults to the value
|
||
returned by `current-output-port'.
|
||
|
||
|
||
- Function: read-byte
|
||
- Function: read-byte port
|
||
Returns the next byte available from the input PORT, updating the
|
||
PORT to point to the following byte. If no more bytes 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: bytes byte ...
|
||
Returns a newly allocated byte-array composed of the arguments.
|
||
|
||
|
||
- Function: bytes->list bytes
|
||
- Function: list->bytes bytes
|
||
`Bytes->list' returns a newly allocated list of the bytes that
|
||
make up the given byte-array. `List->bytes' returns a newly
|
||
allocated byte-array formed from the small integers in the list
|
||
BYTES. `Bytes->list' and `list->bytes' are inverses so far as
|
||
`equal?' is concerned.
|
||
|
||
|
||
|
||
File: slib.info, Node: Portable Image Files, Next: Collections, Prev: Byte, Up: Data Structures
|
||
|
||
Portable Image Files
|
||
--------------------
|
||
|
||
`(require 'pnm)'
|
||
|
||
- Function: pnm:type-dimensions path
|
||
The string PATH must name a "portable bitmap graphics" file.
|
||
`pnm:type-dimensions' returns a list of 4 items:
|
||
1. A symbol describing the type of the file named by PATH.
|
||
|
||
2. The image width in pixels.
|
||
|
||
3. The image height in pixels.
|
||
|
||
4. The maximum value of pixels assume in the file.
|
||
|
||
The current set of file-type symbols is:
|
||
pbm
|
||
pbm-raw
|
||
Black-and-White image; pixel values are 0 or 1.
|
||
|
||
pgm
|
||
pgm-raw
|
||
Gray (monochrome) image; pixel values are from 0 to MAXVAL
|
||
specified in file header.
|
||
|
||
ppm
|
||
ppm-raw
|
||
RGB (full color) image; red, green, and blue interleaved
|
||
pixel values are from 0 to MAXVAL
|
||
|
||
|
||
- Function: pnm:image-file->array path array
|
||
Reads the "portable bitmap graphics" file named by PATH into
|
||
ARRAY. ARRAY must be the correct size and type for PATH. ARRAY
|
||
is returned.
|
||
|
||
- Function: pnm:image-file->array path
|
||
`pnm:image-file->array' creates and returns an array with the
|
||
"portable bitmap graphics" file named by PATH read into it.
|
||
|
||
|
||
- Procedure: pnm:array-write type array maxval path
|
||
Writes the contents of ARRAY to a TYPE image file named PATH. The
|
||
file will have pixel values between 0 and MAXVAL, which must be
|
||
compatible with TYPE. For `pbm' files, MAXVAL must be `1'.
|
||
|
||
|
||
|
||
File: slib.info, Node: Collections, Next: Dynamic Data Type, Prev: Portable Image Files, Up: Data Structures
|
||
|
||
Collections
|
||
-----------
|
||
|
||
`(require 'collect)'
|
||
|
||
Routines for managing collections. Collections are aggregate data
|
||
structures supporting iteration over their elements, similar to the
|
||
Dylan(TM) language, but with a different interface. They have
|
||
"elements" indexed by corresponding "keys", although the keys may be
|
||
implicit (as with lists).
|
||
|
||
New types of collections may be defined as YASOS objects (*note
|
||
Yasos::). They must support the following operations:
|
||
* `(collection? SELF)' (always returns `#t');
|
||
|
||
* `(size SELF)' returns the number of elements in the collection;
|
||
|
||
* `(print SELF PORT)' is a specialized print operation for the
|
||
collection which prints a suitable representation on the given
|
||
PORT or returns it as a string if PORT is `#t';
|
||
|
||
* `(gen-elts SELF)' returns a thunk which on successive invocations
|
||
yields elements of SELF in order or gives an error if it is
|
||
invoked more than `(size SELF)' times;
|
||
|
||
* `(gen-keys SELF)' is like `gen-elts', but yields the collection's
|
||
keys in order.
|
||
|
||
They might support specialized `for-each-key' and `for-each-elt'
|
||
operations.
|
||
|
||
- Function: collection? obj
|
||
A predicate, true initially of lists, vectors and strings. New
|
||
sorts of collections must answer `#t' to `collection?'.
|
||
|
||
- Procedure: map-elts proc . collections
|
||
- Procedure: do-elts proc . collections
|
||
PROC is a procedure taking as many arguments as there are
|
||
COLLECTIONS (at least one). The COLLECTIONS are iterated over in
|
||
their natural order and PROC is applied to the elements yielded by
|
||
each iteration in turn. The order in which the arguments are
|
||
supplied corresponds to te order in which the COLLECTIONS appear.
|
||
`do-elts' is used when only side-effects of PROC are of interest
|
||
and its return value is unspecified. `map-elts' returns a
|
||
collection (actually a vector) of the results of the applications
|
||
of PROC.
|
||
|
||
Example:
|
||
(map-elts + (list 1 2 3) (vector 1 2 3))
|
||
=> #(2 4 6)
|
||
|
||
- Procedure: map-keys proc . collections
|
||
- Procedure: do-keys proc . collections
|
||
These are analogous to `map-elts' and `do-elts', but each
|
||
iteration is over the COLLECTIONS' _keys_ rather than their
|
||
elements.
|
||
|
||
Example:
|
||
(map-keys + (list 1 2 3) (vector 1 2 3))
|
||
=> #(0 2 4)
|
||
|
||
- Procedure: for-each-key collection proc
|
||
- Procedure: for-each-elt collection proc
|
||
These are like `do-keys' and `do-elts' but only for a single
|
||
collection; they are potentially more efficient.
|
||
|
||
- Function: reduce proc seed . collections
|
||
A generalization of the list-based `comlist:reduce-init' (*note
|
||
Lists as sequences::) to collections which will shadow the
|
||
list-based version if `(require 'collect)' follows `(require
|
||
'common-list-functions)' (*note Common List Functions::).
|
||
|
||
Examples:
|
||
(reduce + 0 (vector 1 2 3))
|
||
=> 6
|
||
(reduce union '() '((a b c) (b c d) (d a)))
|
||
=> (c b d a).
|
||
|
||
- Function: any? pred . collections
|
||
A generalization of the list-based `some' (*note Lists as
|
||
sequences::) to collections.
|
||
|
||
Example:
|
||
(any? odd? (list 2 3 4 5))
|
||
=> #t
|
||
|
||
- Function: every? pred . collections
|
||
A generalization of the list-based `every' (*note Lists as
|
||
sequences::) to collections.
|
||
|
||
Example:
|
||
(every? collection? '((1 2) #(1 2)))
|
||
=> #t
|
||
|
||
- Function: empty? collection
|
||
Returns `#t' iff there are no elements in COLLECTION.
|
||
|
||
`(empty? COLLECTION) == (zero? (size COLLECTION))'
|
||
|
||
- Function: size collection
|
||
Returns the number of elements in COLLECTION.
|
||
|
||
- Function: Setter list-ref
|
||
See *Note Setters:: for a definition of "setter". N.B. `(setter
|
||
list-ref)' doesn't work properly for element 0 of a list.
|
||
|
||
Here is a sample collection: `simple-table' which is also a `table'.
|
||
(define-predicate TABLE?)
|
||
(define-operation (LOOKUP table key failure-object))
|
||
(define-operation (ASSOCIATE! table key value)) ;; returns key
|
||
(define-operation (REMOVE! table key)) ;; returns value
|
||
|
||
(define (MAKE-SIMPLE-TABLE)
|
||
(let ( (table (list)) )
|
||
(object
|
||
;; table behaviors
|
||
((TABLE? self) #t)
|
||
((SIZE self) (size table))
|
||
((PRINT self port) (format port "#<SIMPLE-TABLE>"))
|
||
((LOOKUP self key failure-object)
|
||
(cond
|
||
((assq key table) => cdr)
|
||
(else failure-object)
|
||
))
|
||
((ASSOCIATE! self key value)
|
||
(cond
|
||
((assq key table)
|
||
=> (lambda (bucket) (set-cdr! bucket value) key))
|
||
(else
|
||
(set! table (cons (cons key value) table))
|
||
key)
|
||
))
|
||
((REMOVE! self key);; returns old value
|
||
(cond
|
||
((null? table) (slib:error "TABLE:REMOVE! Key not found: " key))
|
||
((eq? key (caar table))
|
||
(let ( (value (cdar table)) )
|
||
(set! table (cdr table))
|
||
value)
|
||
)
|
||
(else
|
||
(let loop ( (last table) (this (cdr table)) )
|
||
(cond
|
||
((null? this)
|
||
(slib:error "TABLE:REMOVE! Key not found: " key))
|
||
((eq? key (caar this))
|
||
(let ( (value (cdar this)) )
|
||
(set-cdr! last (cdr this))
|
||
value)
|
||
)
|
||
(else
|
||
(loop (cdr last) (cdr this)))
|
||
) ) )
|
||
))
|
||
;; collection behaviors
|
||
((COLLECTION? self) #t)
|
||
((GEN-KEYS self) (collect:list-gen-elts (map car table)))
|
||
((GEN-ELTS self) (collect:list-gen-elts (map cdr table)))
|
||
((FOR-EACH-KEY self proc)
|
||
(for-each (lambda (bucket) (proc (car bucket))) table)
|
||
)
|
||
((FOR-EACH-ELT self proc)
|
||
(for-each (lambda (bucket) (proc (cdr bucket))) table)
|
||
)
|
||
) ) )
|
||
|
||
|
||
File: slib.info, Node: Dynamic Data Type, Next: Hash Tables, Prev: Collections, Up: Data Structures
|
||
|
||
Dynamic Data Type
|
||
-----------------
|
||
|
||
`(require 'dynamic)'
|
||
|
||
- Function: make-dynamic obj
|
||
Create and returns a new "dynamic" whose global value is OBJ.
|
||
|
||
- Function: dynamic? obj
|
||
Returns true if and only if OBJ is a dynamic. No object
|
||
satisfying `dynamic?' satisfies any of the other standard type
|
||
predicates.
|
||
|
||
- Function: dynamic-ref dyn
|
||
Return the value of the given dynamic in the current dynamic
|
||
environment.
|
||
|
||
- Procedure: dynamic-set! dyn obj
|
||
Change the value of the given dynamic to OBJ in the current
|
||
dynamic environment. The returned value is unspecified.
|
||
|
||
- Function: call-with-dynamic-binding dyn obj thunk
|
||
Invoke and return the value of the given thunk in a new, nested
|
||
dynamic environment in which the given dynamic has been bound to a
|
||
new location whose initial contents are the value OBJ. This
|
||
dynamic environment has precisely the same extent as the
|
||
invocation of the thunk and is thus captured by continuations
|
||
created within that invocation and re-established by those
|
||
continuations when they are invoked.
|
||
|
||
The `dynamic-bind' macro is not implemented.
|
||
|
||
|
||
File: slib.info, Node: Hash Tables, Next: Hashing, Prev: Dynamic Data Type, Up: Data Structures
|
||
|
||
Hash Tables
|
||
-----------
|
||
|
||
`(require 'hash-table)'
|
||
|
||
- Function: predicate->hash pred
|
||
Returns a hash function (like `hashq', `hashv', or `hash')
|
||
corresponding to the equality predicate PRED. PRED should be
|
||
`eq?', `eqv?', `equal?', `=', `char=?', `char-ci=?', `string=?', or
|
||
`string-ci=?'.
|
||
|
||
A hash table is a vector of association lists.
|
||
|
||
- Function: make-hash-table k
|
||
Returns a vector of K empty (association) lists.
|
||
|
||
Hash table functions provide utilities for an associative database.
|
||
These functions take an equality predicate, PRED, as an argument. PRED
|
||
should be `eq?', `eqv?', `equal?', `=', `char=?', `char-ci=?',
|
||
`string=?', or `string-ci=?'.
|
||
|
||
- Function: predicate->hash-asso pred
|
||
Returns a hash association function of 2 arguments, KEY and
|
||
HASHTAB, corresponding to PRED. The returned function returns a
|
||
key-value pair whose key is PRED-equal to its first argument or
|
||
`#f' if no key in HASHTAB is PRED-equal to the first argument.
|
||
|
||
- Function: hash-inquirer pred
|
||
Returns a procedure of 3 arguments, `hashtab' and `key', which
|
||
returns the value associated with `key' in `hashtab' or `#f' if
|
||
key does not appear in `hashtab'.
|
||
|
||
- Function: hash-associator pred
|
||
Returns a procedure of 3 arguments, HASHTAB, KEY, and VALUE, which
|
||
modifies HASHTAB so that KEY and VALUE associated. Any previous
|
||
value associated with KEY will be lost.
|
||
|
||
- Function: hash-remover pred
|
||
Returns a procedure of 2 arguments, HASHTAB and KEY, which
|
||
modifies HASHTAB so that the association whose key is KEY is
|
||
removed.
|
||
|
||
- Function: hash-map proc hash-table
|
||
Returns a new hash table formed by mapping PROC over the keys and
|
||
values of HASH-TABLE. PROC must be a function of 2 arguments
|
||
which returns the new value part.
|
||
|
||
- Function: hash-for-each proc hash-table
|
||
Applies PROC to each pair of keys and values of HASH-TABLE. PROC
|
||
must be a function of 2 arguments. The returned value is
|
||
unspecified.
|
||
|
||
|
||
File: slib.info, Node: Hashing, Next: Object, Prev: Hash Tables, Up: Data Structures
|
||
|
||
Hashing
|
||
-------
|
||
|
||
`(require 'hash)'
|
||
|
||
These hashing functions are for use in quickly classifying objects.
|
||
Hash tables use these functions.
|
||
|
||
- Function: hashq obj k
|
||
- Function: hashv obj k
|
||
- Function: hash obj k
|
||
Returns an exact non-negative integer less than K. For each
|
||
non-negative integer less than K there are arguments OBJ for which
|
||
the hashing functions applied to OBJ and K returns that integer.
|
||
|
||
For `hashq', `(eq? obj1 obj2)' implies `(= (hashq obj1 k) (hashq
|
||
obj2))'.
|
||
|
||
For `hashv', `(eqv? obj1 obj2)' implies `(= (hashv obj1 k) (hashv
|
||
obj2))'.
|
||
|
||
For `hash', `(equal? obj1 obj2)' implies `(= (hash obj1 k) (hash
|
||
obj2))'.
|
||
|
||
`hash', `hashv', and `hashq' return in time bounded by a constant.
|
||
Notice that items having the same `hash' implies the items have
|
||
the same `hashv' implies the items have the same `hashq'.
|
||
|
||
`(require 'sierpinski)'
|
||
|
||
- Function: make-sierpinski-indexer max-coordinate
|
||
Returns a procedure (eg hash-function) of 2 numeric arguments which
|
||
preserves _nearness_ in its mapping from NxN to N.
|
||
|
||
MAX-COORDINATE is the maximum coordinate (a positive integer) of a
|
||
population of points. The returned procedures is a function that
|
||
takes the x and y coordinates of a point, (non-negative integers)
|
||
and returns an integer corresponding to the relative position of
|
||
that point along a Sierpinski curve. (You can think of this as
|
||
computing a (pseudo-) inverse of the Sierpinski spacefilling
|
||
curve.)
|
||
|
||
Example use: Make an indexer (hash-function) for integer points
|
||
lying in square of integer grid points [0,99]x[0,99]:
|
||
(define space-key (make-sierpinski-indexer 100))
|
||
Now let's compute the index of some points:
|
||
(space-key 24 78) => 9206
|
||
(space-key 23 80) => 9172
|
||
|
||
Note that locations (24, 78) and (23, 80) are near in index and
|
||
therefore, because the Sierpinski spacefilling curve is
|
||
continuous, we know they must also be near in the plane. Nearness
|
||
in the plane does not, however, necessarily correspond to nearness
|
||
in index, although it _tends_ to be so.
|
||
|
||
Example applications:
|
||
* Sort points by Sierpinski index to get heuristic solution to
|
||
_travelling salesman problem_. For details of performance,
|
||
see L. Platzman and J. Bartholdi, "Spacefilling curves and the
|
||
Euclidean travelling salesman problem", JACM 36(4):719-737
|
||
(October 1989) and references therein.
|
||
|
||
* Use Sierpinski index as key by which to store 2-dimensional
|
||
data in a 1-dimensional data structure (such as a table).
|
||
Then locations that are near each other in 2-d space will
|
||
tend to be near each other in 1-d data structure; and
|
||
locations that are near in 1-d data structure will be near in
|
||
2-d space. This can significantly speed retrieval from
|
||
secondary storage because contiguous regions in the plane
|
||
will tend to correspond to contiguous regions in secondary
|
||
storage. (This is a standard technique for managing CAD/CAM
|
||
or geographic data.)
|
||
|
||
|
||
`(require 'soundex)'
|
||
|
||
- Function: soundex name
|
||
Computes the _soundex_ hash of NAME. Returns a string of an
|
||
initial letter and up to three digits between 0 and 6. Soundex
|
||
supposedly has the property that names that sound similar in normal
|
||
English pronunciation tend to map to the same key.
|
||
|
||
Soundex was a classic algorithm used for manual filing of personal
|
||
records before the advent of computers. It performs adequately for
|
||
English names but has trouble with other languages. |
|
||
|
||
See Knuth, Vol. 3 `Sorting and searching', pp 391-2
|
||
|
||
To manage unusual inputs, `soundex' omits all non-alphabetic
|
||
characters. Consequently, in this implementation:
|
||
|
||
(soundex <string of blanks>) => ""
|
||
(soundex "") => ""
|
||
|
||
Examples from Knuth:
|
||
|
||
(map soundex '("Euler" "Gauss" "Hilbert" "Knuth"
|
||
"Lloyd" "Lukasiewicz"))
|
||
=> ("E460" "G200" "H416" "K530" "L300" "L222")
|
||
|
||
(map soundex '("Ellery" "Ghosh" "Heilbronn" "Kant"
|
||
"Ladd" "Lissajous"))
|
||
=> ("E460" "G200" "H416" "K530" "L300" "L222")
|
||
|
||
Some cases in which the algorithm fails (Knuth):
|
||
|
||
(map soundex '("Rogers" "Rodgers")) => ("R262" "R326")
|
||
|
||
(map soundex '("Sinclair" "St. Clair")) => ("S524" "S324")
|
||
|
||
(map soundex '("Tchebysheff" "Chebyshev")) => ("T212" "C121")
|
||
|
||
|
||
File: slib.info, Node: Object, Next: Priority Queues, Prev: Hashing, Up: Data Structures
|
||
|
||
Macroless Object System
|
||
-----------------------
|
||
|
||
`(require 'object)'
|
||
|
||
This is the Macroless Object System written by Wade Humeniuk
|
||
(whumeniu@datap.ca). Conceptual Tributes: *Note Yasos::, MacScheme's
|
||
%object, CLOS, Lack of R4RS macros.
|
||
|
||
Concepts
|
||
--------
|
||
|
||
OBJECT
|
||
An object is an ordered association-list (by `eq?') of methods
|
||
(procedures). Methods can be added (`make-method!'), deleted
|
||
(`unmake-method!') and retrieved (`get-method'). Objects may
|
||
inherit methods from other objects. The object binds to the
|
||
environment it was created in, allowing closures to be used to
|
||
hide private procedures and data.
|
||
|
||
GENERIC-METHOD
|
||
A generic-method associates (in terms of `eq?') object's method.
|
||
This allows scheme function style to be used for objects. The
|
||
calling scheme for using a generic method is `(generic-method
|
||
object param1 param2 ...)'.
|
||
|
||
METHOD
|
||
A method is a procedure that exists in the object. To use a method
|
||
get-method must be called to look-up the method. Generic methods
|
||
implement the get-method functionality. Methods may be added to an
|
||
object associated with any scheme obj in terms of eq?
|
||
|
||
GENERIC-PREDICATE
|
||
A generic method that returns a boolean value for any scheme obj.
|
||
|
||
PREDICATE
|
||
A object's method asscociated with a generic-predicate. Returns
|
||
`#t'.
|
||
|
||
Procedures
|
||
----------
|
||
|
||
- Function: make-object ancestor ...
|
||
Returns an object. Current object implementation is a tagged
|
||
vector. ANCESTORs are optional and must be objects in terms of
|
||
object?. ANCESTORs methods are included in the object. Multiple
|
||
ANCESTORs might associate the same generic-method with a method.
|
||
In this case the method of the ANCESTOR first appearing in the
|
||
list is the one returned by `get-method'.
|
||
|
||
- Function: object? obj
|
||
Returns boolean value whether OBJ was created by make-object.
|
||
|
||
- Function: make-generic-method exception-procedure
|
||
Returns a procedure which be associated with an object's methods.
|
||
If EXCEPTION-PROCEDURE is specified then it is used to process
|
||
non-objects.
|
||
|
||
- Function: make-generic-predicate
|
||
Returns a boolean procedure for any scheme object.
|
||
|
||
- Function: make-method! object generic-method method
|
||
Associates METHOD to the GENERIC-METHOD in the object. The METHOD
|
||
overrides any previous association with the GENERIC-METHOD within
|
||
the object. Using `unmake-method!' will restore the object's
|
||
previous association with the GENERIC-METHOD. METHOD must be a
|
||
procedure.
|
||
|
||
- Function: make-predicate! object generic-preciate
|
||
Makes a predicate method associated with the GENERIC-PREDICATE.
|
||
|
||
- Function: unmake-method! object generic-method
|
||
Removes an object's association with a GENERIC-METHOD .
|
||
|
||
- Function: get-method object generic-method
|
||
Returns the object's method associated (if any) with the
|
||
GENERIC-METHOD. If no associated method exists an error is
|
||
flagged.
|
||
|
||
Examples
|
||
--------
|
||
|
||
(require 'object)
|
||
|
||
(define instantiate (make-generic-method))
|
||
|
||
(define (make-instance-object . ancestors)
|
||
(define self (apply make-object
|
||
(map (lambda (obj) (instantiate obj)) ancestors)))
|
||
(make-method! self instantiate (lambda (self) self))
|
||
self)
|
||
|
||
(define who (make-generic-method))
|
||
(define imigrate! (make-generic-method))
|
||
(define emigrate! (make-generic-method))
|
||
(define describe (make-generic-method))
|
||
(define name (make-generic-method))
|
||
(define address (make-generic-method))
|
||
(define members (make-generic-method))
|
||
|
||
(define society
|
||
(let ()
|
||
(define self (make-instance-object))
|
||
(define population '())
|
||
(make-method! self imigrate!
|
||
(lambda (new-person)
|
||
(if (not (eq? new-person self))
|
||
(set! population (cons new-person population)))))
|
||
(make-method! self emigrate!
|
||
(lambda (person)
|
||
(if (not (eq? person self))
|
||
(set! population
|
||
(comlist:remove-if (lambda (member)
|
||
(eq? member person))
|
||
population)))))
|
||
(make-method! self describe
|
||
(lambda (self)
|
||
(map (lambda (person) (describe person)) population)))
|
||
(make-method! self who
|
||
(lambda (self) (map (lambda (person) (name person))
|
||
population)))
|
||
(make-method! self members (lambda (self) population))
|
||
self))
|
||
|
||
(define (make-person %name %address)
|
||
(define self (make-instance-object society))
|
||
(make-method! self name (lambda (self) %name))
|
||
(make-method! self address (lambda (self) %address))
|
||
(make-method! self who (lambda (self) (name self)))
|
||
(make-method! self instantiate
|
||
(lambda (self)
|
||
(make-person (string-append (name self) "-son-of")
|
||
%address)))
|
||
(make-method! self describe
|
||
(lambda (self) (list (name self) (address self))))
|
||
(imigrate! self)
|
||
self)
|
||
|
||
Inverter Documentation
|
||
......................
|
||
|
||
Inheritance:
|
||
<inverter>::(<number> <description>)
|
||
Generic-methods
|
||
<inverter>::value => <number>::value
|
||
<inverter>::set-value! => <number>::set-value!
|
||
<inverter>::describe => <description>::describe
|
||
<inverter>::help
|
||
<inverter>::invert
|
||
<inverter>::inverter?
|
||
|
||
Number Documention
|
||
..................
|
||
|
||
Inheritance
|
||
<number>::()
|
||
Slots
|
||
<number>::<x>
|
||
Generic Methods
|
||
<number>::value
|
||
<number>::set-value!
|
||
|
||
Inverter code
|
||
.............
|
||
|
||
(require 'object)
|
||
|
||
(define value (make-generic-method (lambda (val) val)))
|
||
(define set-value! (make-generic-method))
|
||
(define invert (make-generic-method
|
||
(lambda (val)
|
||
(if (number? val)
|
||
(/ 1 val)
|
||
(error "Method not supported:" val)))))
|
||
(define noop (make-generic-method))
|
||
(define inverter? (make-generic-predicate))
|
||
(define describe (make-generic-method))
|
||
(define help (make-generic-method))
|
||
|
||
(define (make-number x)
|
||
(define self (make-object))
|
||
(make-method! self value (lambda (this) x))
|
||
(make-method! self set-value!
|
||
(lambda (this new-value) (set! x new-value)))
|
||
self)
|
||
|
||
(define (make-description str)
|
||
(define self (make-object))
|
||
(make-method! self describe (lambda (this) str))
|
||
(make-method! self help (lambda (this) "Help not available"))
|
||
self)
|
||
|
||
(define (make-inverter)
|
||
(let* ((self (make-object
|
||
(make-number 1)
|
||
(make-description "A number which can be inverted")))
|
||
(<value> (get-method self value)))
|
||
(make-method! self invert (lambda (self) (/ 1 (<value> self))))
|
||
(make-predicate! self inverter?)
|
||
(unmake-method! self help)
|
||
(make-method! self help
|
||
(lambda (self)
|
||
(display "Inverter Methods:") (newline)
|
||
(display " (value inverter) ==> n") (newline)))
|
||
self))
|
||
|
||
;;;; Try it out
|
||
|
||
(define invert! (make-generic-method))
|
||
|
||
(define x (make-inverter))
|
||
|
||
(make-method! x invert! (lambda (x) (set-value! x (/ 1 (value x)))))
|
||
|
||
(value x) => 1
|
||
(set-value! x 33) => undefined
|
||
(invert! x) => undefined
|
||
(value x) => 1/33
|
||
|
||
(unmake-method! x invert!) => undefined
|
||
|
||
(invert! x) error--> ERROR: Method not supported: x
|
||
|
||
|
||
File: slib.info, Node: Priority Queues, Next: Queues, Prev: Object, Up: Data Structures
|
||
|
||
Priority Queues
|
||
---------------
|
||
|
||
`(require 'priority-queue)'
|
||
|
||
- Function: make-heap pred<?
|
||
Returns a binary heap suitable which can be used for priority queue
|
||
operations.
|
||
|
||
- Function: heap-length heap
|
||
Returns the number of elements in HEAP.
|
||
|
||
- Procedure: heap-insert! heap item
|
||
Inserts ITEM into HEAP. ITEM can be inserted multiple times. The
|
||
value returned is unspecified.
|
||
|
||
- Function: heap-extract-max! heap
|
||
Returns the item which is larger than all others according to the
|
||
PRED<? argument to `make-heap'. If there are no items in HEAP, an
|
||
error is signaled.
|
||
|
||
The algorithm for priority queues was taken from `Introduction to
|
||
Algorithms' by T. Cormen, C. Leiserson, R. Rivest. 1989 MIT Press.
|
||
|
||
|
||
File: slib.info, Node: Queues, Next: Records, Prev: Priority Queues, Up: Data Structures
|
||
|
||
Queues
|
||
------
|
||
|
||
`(require 'queue)'
|
||
|
||
A "queue" is a list where elements can be added to both the front and
|
||
rear, and removed from the front (i.e., they are what are often called
|
||
"dequeues"). A queue may also be used like a stack.
|
||
|
||
- Function: make-queue
|
||
Returns a new, empty queue.
|
||
|
||
- Function: queue? obj
|
||
Returns `#t' if OBJ is a queue.
|
||
|
||
- Function: queue-empty? q
|
||
Returns `#t' if the queue Q is empty.
|
||
|
||
- Procedure: queue-push! q datum
|
||
Adds DATUM to the front of queue Q.
|
||
|
||
- Procedure: enquque! q datum
|
||
Adds DATUM to the rear of queue Q.
|
||
|
||
All of the following functions raise an error if the queue Q is empty.
|
||
|
||
- Function: queue-front q
|
||
Returns the datum at the front of the queue Q.
|
||
|
||
- Function: queue-rear q
|
||
Returns the datum at the rear of the queue Q.
|
||
|
||
- Prcoedure: queue-pop! q
|
||
- Procedure: dequeue! q
|
||
Both of these procedures remove and return the datum at the front
|
||
of the queue. `queue-pop!' is used to suggest that the queue is
|
||
being used like a stack.
|
||
|
||
|
||
File: slib.info, Node: Records, Next: Structures, Prev: Queues, Up: Data Structures
|
||
|
||
Records
|
||
-------
|
||
|
||
`(require 'record)'
|
||
|
||
The Record package provides a facility for user to define their own
|
||
record data types.
|
||
|
||
- Function: make-record-type type-name field-names
|
||
Returns a "record-type descriptor", a value representing a new data
|
||
type disjoint from all others. The TYPE-NAME argument must be a
|
||
string, but is only used for debugging purposes (such as the
|
||
printed representation of a record of the new type). The
|
||
FIELD-NAMES argument is a list of symbols naming the "fields" of a
|
||
record of the new type. It is an error if the list contains any
|
||
duplicates. It is unspecified how record-type descriptors are
|
||
represented.
|
||
|
||
- Function: record-constructor rtd [field-names]
|
||
Returns a procedure for constructing new members of the type
|
||
represented by RTD. The returned procedure accepts exactly as
|
||
many arguments as there are symbols in the given list,
|
||
FIELD-NAMES; these are used, in order, as the initial values of
|
||
those fields in a new record, which is returned by the constructor
|
||
procedure. The values of any fields not named in that list are
|
||
unspecified. The FIELD-NAMES argument defaults to the list of
|
||
field names in the call to `make-record-type' that created the
|
||
type represented by RTD; if the FIELD-NAMES argument is provided,
|
||
it is an error if it contains any duplicates or any symbols not in
|
||
the default list.
|
||
|
||
- Function: record-predicate rtd
|
||
Returns a procedure for testing membership in the type represented
|
||
by RTD. The returned procedure accepts exactly one argument and
|
||
returns a true value if the argument is a member of the indicated
|
||
record type; it returns a false value otherwise.
|
||
|
||
- Function: record-accessor rtd field-name
|
||
Returns a procedure for reading the value of a particular field of
|
||
a member of the type represented by RTD. The returned procedure
|
||
accepts exactly one argument which must be a record of the
|
||
appropriate type; it returns the current value of the field named
|
||
by the symbol FIELD-NAME in that record. The symbol FIELD-NAME
|
||
must be a member of the list of field-names in the call to
|
||
`make-record-type' that created the type represented by RTD.
|
||
|
||
- Function: record-modifier rtd field-name
|
||
Returns a procedure for writing the value of a particular field of
|
||
a member of the type represented by RTD. The returned procedure
|
||
accepts exactly two arguments: first, a record of the appropriate
|
||
type, and second, an arbitrary Scheme value; it modifies the field
|
||
named by the symbol FIELD-NAME in that record to contain the given
|
||
value. The returned value of the modifier procedure is
|
||
unspecified. The symbol FIELD-NAME must be a member of the list
|
||
of field-names in the call to `make-record-type' that created the
|
||
type represented by RTD.
|
||
|
||
In May of 1996, as a product of discussion on the `rrrs-authors'
|
||
mailing list, I rewrote `record.scm' to portably implement type
|
||
disjointness for record data types.
|
||
|
||
As long as an implementation's procedures are opaque and the `record'
|
||
code is loaded before other programs, this will give disjoint record
|
||
types which are unforgeable and incorruptible by R4RS procedures.
|
||
|
||
As a consequence, the procedures `record?', `record-type-descriptor',
|
||
`record-type-name'.and `record-type-field-names' are no longer
|
||
supported.
|
||
|
||
|
||
File: slib.info, Node: Structures, Prev: Records, Up: Data Structures
|
||
|
||
Structures
|
||
----------
|
||
|
||
`(require 'struct)' (uses defmacros)
|
||
|
||
`defmacro's which implement "records" from the book `Essentials of
|
||
Programming Languages' by Daniel P. Friedman, M. Wand and C.T. Haynes.
|
||
Copyright 1992 Jeff Alexander, Shinnder Lee, and Lewis Patterson
|
||
|
||
Matthew McDonald <mafm@cs.uwa.edu.au> added field setters.
|
||
|
||
- Macro: define-record tag (var1 var2 ...)
|
||
Defines several functions pertaining to record-name TAG:
|
||
|
||
- Function: make-TAG var1 var2 ...
|
||
|
||
- Function: TAG? obj
|
||
|
||
- Function: TAG->var1 obj
|
||
|
||
- Function: TAG->var2 obj
|
||
...
|
||
|
||
- Function: set-TAG-var1! obj val
|
||
|
||
- Function: set-TAG-var2! obj val
|
||
...
|
||
|
||
Here is an example of its use.
|
||
|
||
(define-record term (operator left right))
|
||
=> #<unspecified>
|
||
(define foo (make-term 'plus 1 2))
|
||
=> foo
|
||
(term->left foo)
|
||
=> 1
|
||
(set-term-left! foo 2345)
|
||
=> #<unspecified>
|
||
(term->left foo)
|
||
=> 2345
|
||
|
||
- Macro: variant-case exp (tag (var1 var2 ...) body) ...
|
||
executes the following for the matching clause:
|
||
|
||
((lambda (VAR1 VAR ...) BODY)
|
||
(TAG->VAR1 EXP)
|
||
(TAG->VAR2 EXP) ...)
|
||
|
||
|
||
File: slib.info, Node: Procedures, Next: Standards Support, Prev: Data Structures, Up: Other Packages
|
||
|
||
Procedures
|
||
==========
|
||
|
||
Anything that doesn't fall neatly into any of the other categories
|
||
winds up here.
|
||
|
||
* Menu:
|
||
|
||
* Common List Functions:: 'common-list-functions
|
||
* Tree Operations:: 'tree
|
||
* Type Coercion:: 'coerce |
|
||
* Chapter Ordering:: 'chapter-order
|
||
* Sorting:: 'sort
|
||
* Topological Sort:: Keep your socks on.
|
||
* String-Case:: 'string-case
|
||
* String Ports:: 'string-port
|
||
* String Search:: Also Search from a Port.
|
||
* Line I/O:: 'line-i/o
|
||
* Multi-Processing:: 'process
|
||
* Metric Units:: Portable manifest types for numeric values. |
|
||
|
||
|
||
File: slib.info, Node: Common List Functions, Next: Tree Operations, Prev: Procedures, 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)
|
||
=> (#<unspecified> #<unspecified> #<unspecified>)
|
||
(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
|
||
.............
|
||
|
||
`eqv?' is used to test for membership by procedures 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))
|
||
=> (4 3) |
|
||
(intersection '(1 2 3 4) '(5 6 7 8))
|
||
=> ()
|
||
|
||
- Function: set-difference l1 l2
|
||
`set-difference' returns all elements that are in L1 but not in L2.
|
||
|
||
Example:
|
||
(set-difference '(1 2 3 4) '(3 4 5 6))
|
||
=> (2 1) |
|
||
(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: list-of?? predicate |
|
||
Returns a predicate which returns true if its argument is a list |
|
||
every element of which satisfies PREDICATE. |
|
||
|
|
||
- Function: list-of?? predicate low-bound high-bound |
|
||
LOW-BOUND and HIGH-BOUND are non-negative integers. `list-of??' |
|
||
returns a predicate which returns true if its argument is a list |
|
||
of length between LOW-BOUND and HIGH-BOUND (inclusive); every |
|
||
element of which satisfies PREDICATE. |
|
||
|
|
||
- Function: list-of?? predicate bound |
|
||
BOUND is an integer. If BOUND is negative, `list-of??' returns a |
|
||
predicate which returns true if its argument is a list of length |
|
||
greater than `(- BOUND)'; every element of which satisfies |
|
||
PREDICATE. Otherwise, `list-of??' returns a predicate which |
|
||
returns true if its argument is a list of length less than or |
|
||
equal to BOUND; every element of which satisfies PREDICATE. |
|
||
|
|
||
- 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))
|
||
=> (5 4 3 2) |
|
||
|
||
(remove 'foo '(bar baz bang))
|
||
=> (bang baz bar) |
|
||
|
||
- 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))
|
||
=> (7 5 3 1) |
|
||
|
||
- 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))
|
||
=> (7 5 3 1) |
|
||
|
||
- 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
|
||
|
||
The procedure `remove-duplicates' uses `member' (rather than `memv').
|
||
|
||
- Function: remove-duplicates lst
|
||
returns a copy of LST with its duplicate members removed.
|
||
Elements are considered duplicate if they are `equal?'.
|
||
|
||
Example:
|
||
(remove-duplicates '(1 2 3 4))
|
||
=> (4 3 2 1)
|
||
|
||
(remove-duplicates '(2 4 3 4))
|
||
=> (3 4 2)
|
||
|
||
|
||
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: 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
|
||
|
||
- Function: butlast lst n
|
||
`butlast' returns all but the last N elements of LST.
|
||
|
||
Example:
|
||
(butlast '(a b c d) 3)
|
||
=> (a)
|
||
(butlast '(a b c d) 4)
|
||
=> ()
|
||
|
||
`last' and `butlast' split a list into two parts when given identical
|
||
arugments.
|
||
(last '(a b c d e) 2)
|
||
=> (d e)
|
||
(butlast '(a b c d e) 2)
|
||
=> (a b c)
|
||
|
||
- Function: nthcdr n lst
|
||
`nthcdr' takes N `cdr's of LST and returns the result. Thus
|
||
`(nthcdr 3 LST)' == `(cdddr LST)'
|
||
|
||
Example:
|
||
(nthcdr 2 '(a b c d))
|
||
=> (c d)
|
||
(nthcdr 0 '(a b c d))
|
||
=> (a b c d)
|
||
|
||
- Function: butnthcdr n lst
|
||
`butnthcdr' returns all but the nthcdr N elements of LST.
|
||
|
||
Example:
|
||
(butnthcdr 3 '(a b c d))
|
||
=> (a b c)
|
||
(butnthcdr 4 '(a b c d))
|
||
=> (a b c d) |
|
||
|
||
`nthcdr' and `butnthcdr' split a list into two parts when given
|
||
identical arugments.
|
||
(nthcdr 2 '(a b c d e))
|
||
=> (c d e)
|
||
(butnthcdr 2 '(a b c d e))
|
||
=> (a b)
|
||
|
||
|
||
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
|
||
|
|
||
|
||
File: slib.info, Node: Tree Operations, Next: Type Coercion, Prev: Common List Functions, Up: Procedures
|
||
|
|
||
Tree operations
|
||
---------------
|
||
|
||
`(require 'tree)'
|
||
|
||
These are operations that treat lists a representations of trees.
|
||
|
||
- Function: subst new old tree
|
||
- Function: substq new old tree
|
||
- Function: substv new old tree
|
||
`subst' makes a copy of TREE, substituting NEW for every subtree
|
||
or leaf of TREE which is `equal?' to OLD and returns a modified
|
||
tree. The original TREE is unchanged, but may share parts with
|
||
the result.
|
||
|
||
`substq' and `substv' are similar, but test against OLD using
|
||
`eq?' and `eqv?' respectively.
|
||
|
||
Examples:
|
||
(substq 'tempest 'hurricane '(shakespeare wrote (the hurricane)))
|
||
=> (shakespeare wrote (the tempest))
|
||
(substq 'foo '() '(shakespeare wrote (twelfth night)))
|
||
=> (shakespeare wrote (twelfth night . foo) . foo)
|
||
(subst '(a . cons) '(old . pair)
|
||
'((old . spice) ((old . shoes) old . pair) (old . pair)))
|
||
=> ((old . spice) ((old . shoes) a . cons) (a . cons))
|
||
|
||
- Function: copy-tree tree
|
||
Makes a copy of the nested list structure TREE using new pairs and
|
||
returns it. All levels are copied, so that none of the pairs in
|
||
the tree are `eq?' to the original ones - only the leaves are.
|
||
|
||
Example:
|
||
(define bar '(bar))
|
||
(copy-tree (list bar 'foo))
|
||
=> ((bar) foo)
|
||
(eq? bar (car (copy-tree (list bar 'foo))))
|
||
=> #f
|
||
|
||
|
||
File: slib.info, Node: Type Coercion, Next: Chapter Ordering, Prev: Tree Operations, Up: Procedures
|
||
|
|
||
Type Coercion |
|
||
------------- |
|
||
|
|
||
`(require 'coerce)' |
|
||
|
|
||
- Function: type-of obj |
|
||
Returns a symbol name for the type of OBJ. |
|
||
|
|
||
- Function: coerce obj result-type |
|
||
Converts and returns OBJ of type `char', `number', `string', |
|
||
`symbol', `list', or `vector' to RESULT-TYPE (which must be one of |
|
||
these symbols). |
|
||
|
|
||
|
||
File: slib.info, Node: Chapter Ordering, Next: Sorting, Prev: Type Coercion, Up: Procedures
|
||
|
|
||
Chapter Ordering
|
||
----------------
|
||
|
||
`(require 'chapter-order)'
|
||
|
||
The `chap:' functions deal with strings which are ordered like
|
||
chapter numbers (or letters) in a book. Each section of the string
|
||
consists of consecutive numeric or consecutive aphabetic characters of
|
||
like case.
|
||
|
||
- Function: chap:string<? string1 string2
|
||
Returns #t if the first non-matching run of alphabetic upper-case
|
||
or the first non-matching run of alphabetic lower-case or the first
|
||
non-matching run of numeric characters of STRING1 is `string<?'
|
||
than the corresponding non-matching run of characters of STRING2.
|
||
|
||
(chap:string<? "a.9" "a.10") => #t
|
||
(chap:string<? "4c" "4aa") => #t
|
||
(chap:string<? "Revised^{3.99}" "Revised^{4}") => #t
|
||
|
||
- Function: chap:string>? string1 string2
|
||
- Function: chap:string<=? string1 string2
|
||
- Function: chap:string>=? string1 string2
|
||
Implement the corresponding chapter-order predicates.
|
||
|
||
- Function: chap:next-string string
|
||
Returns the next string in the _chapter order_. If STRING has no
|
||
alphabetic or numeric characters, `(string-append STRING "0")' is
|
||
returnd. The argument to chap:next-string will always be
|
||
`chap:string<?' than the result.
|
||
|
||
(chap:next-string "a.9") => "a.10"
|
||
(chap:next-string "4c") => "4d"
|
||
(chap:next-string "4z") => "4aa"
|
||
(chap:next-string "Revised^{4}") => "Revised^{5}"
|
||
|
||
|
||
File: slib.info, Node: Sorting, Next: Topological Sort, Prev: Chapter Ordering, Up: Procedures
|
||
|
||
Sorting
|
||
-------
|
||
|
||
`(require 'sort)'
|
||
|
||
Many Scheme systems provide some kind of sorting functions. They do
|
||
not, however, always provide the _same_ sorting functions, and those
|
||
that I have had the opportunity to test provided inefficient ones (a
|
||
common blunder is to use quicksort which does not perform well).
|
||
|
||
Because `sort' and `sort!' are not in the standard, there is very
|
||
little agreement about what these functions look like. For example,
|
||
Dybvig says that Chez Scheme provides
|
||
(merge predicate list1 list2)
|
||
(merge! predicate list1 list2)
|
||
(sort predicate list)
|
||
(sort! predicate list)
|
||
|
||
while MIT Scheme 7.1, following Common LISP, offers unstable
|
||
(sort list predicate)
|
||
|
||
TI PC Scheme offers
|
||
(sort! list/vector predicate?)
|
||
|
||
and Elk offers
|
||
(sort list/vector predicate?)
|
||
(sort! list/vector predicate?)
|
||
|
||
Here is a comprehensive catalogue of the variations I have found.
|
||
|
||
1. Both `sort' and `sort!' may be provided.
|
||
|
||
2. `sort' may be provided without `sort!'.
|
||
|
||
3. `sort!' may be provided without `sort'.
|
||
|
||
4. Neither may be provided.
|
||
|
||
5. The sequence argument may be either a list or a vector.
|
||
|
||
6. The sequence argument may only be a list.
|
||
|
||
7. The sequence argument may only be a vector.
|
||
|
||
8. The comparison function may be expected to behave like `<'.
|
||
|
||
9. The comparison function may be expected to behave like `<='.
|
||
|
||
10. The interface may be `(sort predicate? sequence)'.
|
||
|
||
11. The interface may be `(sort sequence predicate?)'.
|
||
|
||
12. The interface may be `(sort sequence &optional (predicate? <))'.
|
||
|
||
13. The sort may be stable.
|
||
|
||
14. The sort may be unstable.
|
||
|
||
All of this variation really does not help anybody. A nice simple
|
||
merge sort is both stable and fast (quite a lot faster than _quick_
|
||
sort).
|
||
|
||
I am providing this source code with no restrictions at all on its use
|
||
(but please retain D.H.D.Warren's credit for the original idea). You
|
||
may have to rename some of these functions in order to use them in a
|
||
system which already provides incompatible or inferior sorts. For each
|
||
of the functions, only the top-level define needs to be edited to do
|
||
that.
|
||
|
||
I could have given these functions names which would not clash with
|
||
any Scheme that I know of, but I would like to encourage implementors to
|
||
converge on a single interface, and this may serve as a hint. The
|
||
argument order for all functions has been chosen to be as close to
|
||
Common LISP as made sense, in order to avoid NIH-itis.
|
||
|
||
Each of the five functions has a required _last_ parameter which is a
|
||
comparison function. A comparison function `f' is a function of 2
|
||
arguments which acts like `<'. For example,
|
||
|
||
(not (f x x))
|
||
(and (f x y) (f y z)) == (f x z)
|
||
|
||
The standard functions `<', `>', `char<?', `char>?', `char-ci<?',
|
||
`char-ci>?', `string<?', `string>?', `string-ci<?', and `string-ci>?'
|
||
are suitable for use as comparison functions. Think of `(less? x y)'
|
||
as saying when `x' must _not_ precede `y'.
|
||
|
||
- Function: sorted? sequence less?
|
||
Returns `#t' when the sequence argument is in non-decreasing order
|
||
according to LESS? (that is, there is no adjacent pair `... x y
|
||
...' for which `(less? y x)').
|
||
|
||
Returns `#f' when the sequence contains at least one out-of-order
|
||
pair. It is an error if the sequence is neither a list nor a
|
||
vector.
|
||
|
||
- Function: merge list1 list2 less?
|
||
This merges two lists, producing a completely new list as result.
|
||
I gave serious consideration to producing a Common-LISP-compatible
|
||
version. However, Common LISP's `sort' is our `sort!' (well, in
|
||
fact Common LISP's `stable-sort' is our `sort!', merge sort is
|
||
_fast_ as well as stable!) so adapting CL code to Scheme takes a
|
||
bit of work anyway. I did, however, appeal to CL to determine the
|
||
_order_ of the arguments.
|
||
|
||
- Procedure: merge! list1 list2 less?
|
||
Merges two lists, re-using the pairs of LIST1 and LIST2 to build
|
||
the result. If the code is compiled, and LESS? constructs no new
|
||
pairs, no pairs at all will be allocated. The first pair of the
|
||
result will be either the first pair of LIST1 or the first pair of
|
||
LIST2, but you can't predict which.
|
||
|
||
The code of `merge' and `merge!' could have been quite a bit
|
||
simpler, but they have been coded to reduce the amount of work
|
||
done per iteration. (For example, we only have one `null?' test
|
||
per iteration.)
|
||
|
||
- Function: sort sequence less?
|
||
Accepts either a list or a vector, and returns a new sequence
|
||
which is sorted. The new sequence is the same type as the input.
|
||
Always `(sorted? (sort sequence less?) less?)'. The original
|
||
sequence is not altered in any way. The new sequence shares its
|
||
_elements_ with the old one; no elements are copied.
|
||
|
||
- Procedure: sort! sequence less?
|
||
Returns its sorted result in the original boxes. If the original
|
||
sequence is a list, no new storage is allocated at all. If the
|
||
original sequence is a vector, the sorted elements are put back in
|
||
the same vector.
|
||
|
||
Some people have been confused about how to use `sort!', thinking
|
||
that it doesn't return a value. It needs to be pointed out that
|
||
(set! slist (sort! slist <))
|
||
|
||
is the proper usage, not
|
||
(sort! slist <)
|
||
|
||
Note that these functions do _not_ accept a CL-style `:key' argument.
|
||
A simple device for obtaining the same expressiveness is to define
|
||
(define (keyed less? key)
|
||
(lambda (x y) (less? (key x) (key y))))
|
||
|
||
and then, when you would have written
|
||
(sort a-sequence #'my-less :key #'my-key)
|
||
|
||
in Common LISP, just write
|
||
(sort! a-sequence (keyed my-less? my-key))
|
||
|
||
in Scheme.
|
||
|
||
|
||
File: slib.info, Node: Topological Sort, Next: String-Case, Prev: Sorting, Up: Procedures
|
||
|
||
Topological Sort
|
||
----------------
|
||
|
||
`(require 'topological-sort)' or `(require 'tsort)'
|
||
|
||
The algorithm is inspired by Cormen, Leiserson and Rivest (1990)
|
||
`Introduction to Algorithms', chapter 23.
|
||
|
||
- Function: tsort dag pred
|
||
- Function: topological-sort dag pred
|
||
where
|
||
DAG
|
||
is a list of sublists. The car of each sublist is a vertex.
|
||
The cdr is the adjacency list of that vertex, i.e. a list of
|
||
all vertices to which there exists an edge from the car
|
||
vertex.
|
||
|
||
PRED
|
||
is one of `eq?', `eqv?', `equal?', `=', `char=?',
|
||
`char-ci=?', `string=?', or `string-ci=?'.
|
||
|
||
Sort the directed acyclic graph DAG so that for every edge from
|
||
vertex U to V, U will come before V in the resulting list of
|
||
vertices.
|
||
|
||
Time complexity: O (|V| + |E|)
|
||
|
||
Example (from Cormen):
|
||
Prof. Bumstead topologically sorts his clothing when getting
|
||
dressed. The first argument to `tsort' describes which
|
||
garments he needs to put on before others. (For example,
|
||
Prof Bumstead needs to put on his shirt before he puts on his
|
||
tie or his belt.) `tsort' gives the correct order of
|
||
dressing:
|
||
|
||
(require 'tsort)
|
||
(tsort '((shirt tie belt)
|
||
(tie jacket)
|
||
(belt jacket)
|
||
(watch)
|
||
(pants shoes belt)
|
||
(undershorts pants shoes)
|
||
(socks shoes))
|
||
eq?)
|
||
=>
|
||
(socks undershorts pants shoes watch shirt belt tie jacket)
|
||
|
||
|
||
File: slib.info, Node: String-Case, Next: String Ports, Prev: Topological Sort, Up: Procedures
|
||
|
||
String-Case
|
||
-----------
|
||
|
||
`(require 'string-case)'
|
||
|
||
- Procedure: string-upcase str
|
||
- Procedure: string-downcase str
|
||
- Procedure: string-capitalize str
|
||
The obvious string conversion routines. These are non-destructive.
|
||
|
||
- Function: string-upcase! str
|
||
- Function: string-downcase! str
|
||
- Function: string-captialize! str
|
||
The destructive versions of the functions above.
|
||
|
||
- Function: string-ci->symbol str
|
||
Converts string STR to a symbol having the same case as if the
|
||
symbol had been `read'.
|
||
|
||
- Function: symbol-append obj1 ... |
|
||
Converts OBJ1 ... to strings, appends them, and converts to a |
|
||
symbol which is returned. Strings and numbers are converted to |
|
||
read's symbol case; the case of symbol characters is not changed. |
|
||
#f is converted to the empty string (symbol). |
|
||
|
|
||
|
||
File: slib.info, Node: String Ports, Next: String Search, Prev: String-Case, Up: Procedures
|
||
|
||
String Ports
|
||
------------
|
||
|
||
`(require 'string-port)'
|
||
|
||
- Procedure: call-with-output-string proc
|
||
PROC must be a procedure of one argument. This procedure calls
|
||
PROC with one argument: a (newly created) output port. When the
|
||
function returns, the string composed of the characters written
|
||
into the port is returned.
|
||
|
||
- Procedure: call-with-input-string string proc
|
||
PROC must be a procedure of one argument. This procedure calls
|
||
PROC with one argument: an (newly created) input port from which
|
||
STRING's contents may be read. When PROC returns, the port is
|
||
closed and the value yielded by the procedure PROC is returned.
|
||
|
||
|
||
File: slib.info, Node: String Search, Next: Line I/O, Prev: String Ports, Up: Procedures
|
||
|
||
String Search
|
||
-------------
|
||
|
||
`(require 'string-search)'
|
||
|
||
- Procedure: string-index string char
|
||
- Procedure: string-index-ci string char
|
||
Returns the index of the first occurence of CHAR within STRING, or
|
||
`#f' if the STRING does not contain a character CHAR.
|
||
|
||
- Procedure: string-reverse-index string char
|
||
- Procedure: string-reverse-index-ci string char
|
||
Returns the index of the last occurence of CHAR within STRING, or
|
||
`#f' if the STRING does not contain a character CHAR.
|
||
|
||
- procedure: substring? pattern string
|
||
- procedure: substring-ci? pattern string
|
||
Searches STRING to see if some substring of STRING is equal to
|
||
PATTERN. `substring?' returns the index of the first character of
|
||
the first substring of STRING that is equal to PATTERN; or `#f' if
|
||
STRING does not contain PATTERN.
|
||
|
||
(substring? "rat" "pirate") => 2
|
||
(substring? "rat" "outrage") => #f
|
||
(substring? "" any-string) => 0
|
||
|
||
- Procedure: find-string-from-port? str in-port max-no-chars
|
||
Looks for a string STR within the first MAX-NO-CHARS chars of the
|
||
input port IN-PORT.
|
||
|
||
- Procedure: find-string-from-port? str in-port
|
||
When called with two arguments, the search span is limited by the
|
||
end of the input stream.
|
||
|
||
- Procedure: find-string-from-port? str in-port char
|
||
Searches up to the first occurrence of character CHAR in STR.
|
||
|
||
- Procedure: find-string-from-port? str in-port proc
|
||
Searches up to the first occurrence of the procedure PROC
|
||
returning non-false when called with a character (from IN-PORT)
|
||
argument.
|
||
|
||
When the STR is found, `find-string-from-port?' returns the number
|
||
of characters it has read from the port, and the port is set to
|
||
read the first char after that (that is, after the STR) The
|
||
function returns `#f' when the STR isn't found.
|
||
|
||
`find-string-from-port?' reads the port _strictly_ sequentially,
|
||
and does not perform any buffering. So `find-string-from-port?'
|
||
can be used even if the IN-PORT is open to a pipe or other
|
||
communication channel.
|
||
|
||
- Function: string-subst txt old1 new1 ...
|
||
Returns a copy of string TXT with all occurrences of string OLD1
|
||
in TXT replaced with NEW1, OLD2 replaced with NEW2 ....
|
||
|
||
|
||
File: slib.info, Node: Line I/O, Next: Multi-Processing, Prev: String Search, 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. The PORT argument 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. The PORT argument 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. The PORT argument may be omitted, in which
|
||
case it defaults to the value returned by `current-input-port'.
|
||
|
||
- Function: display-file path
|
||
- Function: display-file path port
|
||
Displays the contents of the file named by PATH to PORT. The PORT
|
||
argument may be ommited, in which case it defaults to the value
|
||
returned by `current-output-port'.
|
||
|
||
|
||
File: slib.info, Node: Multi-Processing, Next: Metric Units, Prev: Line I/O, Up: Procedures
|
||
|
|
||
Multi-Processing
|
||
----------------
|
||
|
||
`(require 'process)'
|
||
|
||
This module implements asynchronous (non-polled) time-sliced
|
||
multi-processing in the SCM Scheme implementation using procedures
|
||
`alarm' and `alarm-interrupt'. Until this is ported to another
|
||
implementation, consider it an example of writing schedulers in Scheme.
|
||
|
||
- 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: Metric Units, Prev: Multi-Processing, Up: Procedures
|
||
|
|
||
Metric Units |
|
||
------------ |
|
||
|
|
||
`(require 'metric-units)' |
|
||
|
|
||
<http://swissnet.ai.mit.edu/~jaffer/MIXF.html> |
|
||
|
|
||
"Metric Interchange Format" is a character string encoding for |
|
||
numerical values and units which: |
|
||
|
|
||
* is unambiguous in all locales; |
|
||
|
|
||
* uses only [TOG] "Portable Character Set" characters matching "Basic |
|
||
Latin" characters in Plane 0 of the Universal Character Set [UCS]; |
|
||
|
|
||
* is transparent to [UTF-7] and [UTF-8] UCS transformation formats; |
|
||
|
|
||
* is human readable and writable; |
|
||
|
|
||
* is machine readable and writable; |
|
||
|
|
||
* incorporates SI prefixes and units; |
|
||
|
|
||
* incorporates [ISO 6093] numbers; and |
|
||
|
|
||
* incorporates [IEC 60027-2] binary prefixes. |
|
||
|
|
||
In the expression for the value of a quantity, the unit symbol is |
|
||
placed after the numerical value. A dot (PERIOD, `.') is placed between |
|
||
the numerical value and the unit symbol. |
|
||
|
|
||
Within a compound unit, each of the base and derived symbols can |
|
||
optionally have an attached SI prefix. |
|
||
|
|
||
Unit symbols formed from other unit symbols by multiplication are |
|
||
indicated by means of a dot (PERIOD, `.') placed between them. |
|
||
|
|
||
Unit symbols formed from other unit symbols by division are indicated |
|
||
by means of a SOLIDUS (`/') or negative exponents. The SOLIDUS must |
|
||
not be repeated in the same compound unit unless contained within a |
|
||
parenthesized subexpression. |
|
||
|
|
||
The grouping formed by a prefix symbol attached to a unit symbol |
|
||
constitutes a new inseparable symbol (forming a multiple or submultiple |
|
||
of the unit concerned) which can be raised to a positive or negative |
|
||
power and which can be combined with other unit symbols to form compound |
|
||
unit symbols. |
|
||
|
|
||
The grouping formed by surrounding compound unit symbols with |
|
||
parentheses (`(' and `)') constitutes a new inseparable symbol which |
|
||
can be raised to a positive or negative power and which can be combined |
|
||
with other unit symbols to form compound unit symbols. |
|
||
|
|
||
Compound prefix symbols, that is, prefix symbols formed by the |
|
||
juxtaposition of two or more prefix symbols, are not permitted. |
|
||
|
|
||
Prefix symbols are not used with the time-related unit symbols min |
|
||
(minute), h (hour), d (day). No prefix symbol may be used with dB |
|
||
(decibel). Only submultiple prefix symbols may be used with the unit |
|
||
symbols L (liter), Np (neper), o (degree), oC (degree Celsius), rad |
|
||
(radian), and sr (steradian). Submultiple prefix symbols may not be |
|
||
used with the unit symbols t (metric ton), r (revolution), or Bd (baud). |
|
||
|
|
||
A unit exponent follows the unit, separated by a CIRCUMFLEX (`^'). |
|
||
Exponents may be positive or negative. Fractional exponents must be |
|
||
parenthesized. |
|
||
|
|
||
SI Prefixes |
|
||
........... |
|
||
|
|
||
Factor Name Symbol | Factor Name Symbol |
|
||
====== ==== ====== | ====== ==== ====== |
|
||
1e24 yotta Y | 1e-1 deci d |
|
||
1e21 zetta Z | 1e-2 centi c |
|
||
1e18 exa E | 1e-3 milli m |
|
||
1e15 peta P | 1e-6 micro u |
|
||
1e12 tera T | 1e-9 nano n |
|
||
1e9 giga G | 1e-12 pico p |
|
||
1e6 mega M | 1e-15 femto f |
|
||
1e3 kilo k | 1e-18 atto a |
|
||
1e2 hecto h | 1e-21 zepto z |
|
||
1e1 deka da | 1e-24 yocto y |
|
||
|
|
||
Binary Prefixes |
|
||
............... |
|
||
|
|
||
These binary prefixes are valid only with the units B (byte) and bit. |
|
||
However, decimal prefixes can also be used with bit; and decimal |
|
||
multiple (not submultiple) prefixes can also be used with B (byte). |
|
||
|
|
||
Factor (power-of-2) Name Symbol |
|
||
====== ============ ==== ====== |
|
||
1.152921504606846976e18 (2^60) exbi Ei |
|
||
1.125899906842624e15 (2^50) pebi Pi |
|
||
1.099511627776e12 (2^40) tebi Ti |
|
||
1.073741824e9 (2^30) gibi Gi |
|
||
1.048576e6 (2^20) mebi Mi |
|
||
1.024e3 (2^10) kibi Ki |
|
||
|
|
||
Unit Symbols |
|
||
............ |
|
||
|
|
||
Type of Quantity Name Symbol Equivalent |
|
||
================ ==== ====== ========== |
|
||
time second s |
|
||
time minute min = 60.s |
|
||
time hour h = 60.min |
|
||
time day d = 24.h |
|
||
frequency hertz Hz s^-1 |
|
||
signaling rate baud Bd s^-1 |
|
||
length meter m |
|
||
volume liter L dm^3 |
|
||
plane angle radian rad |
|
||
solid angle steradian sr rad^2 |
|
||
plane angle revolution * r = 6.283185307179586.rad |
|
||
plane angle degree * o = 2.777777777777778e-3.r |
|
||
information capacity bit bit |
|
||
information capacity byte, octet B = 8.bit |
|
||
mass gram g |
|
||
mass ton t Mg |
|
||
mass unified atomic mass unit u = 1.66053873e-27.kg |
|
||
amount of substance mole mol |
|
||
catalytic activity katal kat mol/s |
|
||
thermodynamic temperature kelvin K |
|
||
centigrade temperature degree Celsius oC |
|
||
luminous intensity candela cd |
|
||
luminous flux lumen lm cd.sr |
|
||
illuminance lux lx lm/m^2 |
|
||
force newton N m.kg.s^-2 |
|
||
pressure, stress pascal Pa N/m^2 |
|
||
energy, work, heat joule J N.m |
|
||
energy electronvolt eV = 1.602176462e-19.J |
|
||
power, radiant flux watt W J/s |
|
||
logarithm of power ratio neper Np |
|
||
logarithm of power ratio decibel * dB = 0.1151293.Np |
|
||
electric current ampere A |
|
||
electric charge coulomb C s.A |
|
||
electric potential, EMF volt V W/A |
|
||
capacitance farad F C/V |
|
||
electric resistance ohm Ohm V/A |
|
||
electric conductance siemens S A/V |
|
||
magnetic flux weber Wb V.s |
|
||
magnetic flux density tesla T Wb/m^2 |
|
||
inductance henry H Wb/A |
|
||
radionuclide activity becquerel Bq s^-1 |
|
||
absorbed dose energy gray Gy m^2.s^-2 |
|
||
dose equivalent sievert Sv m^2.s^-2 |
|
||
|
|
||
* The formulas are: |
|
||
|
|
||
* r/rad = 8 * atan(1) |
|
||
|
|
||
* o/r = 1 / 360 |
|
||
|
|
||
* db/Np = ln(10) / 20 |
|
||
|
|
||
- Function: si:conversion-factor to-unit from-unit |
|
||
If the strings FROM-UNIT and TO-UNIT express valid unit |
|
||
expressions for quantities of the same unit-dimensions, then the |
|
||
value returned by `si:conversion-factor' will be such that |
|
||
multiplying a numerical value expressed in FROM-UNITs by the |
|
||
returned conversion factor yields the numerical value expressed in |
|
||
TO-UNITs. |
|
||
|
|
||
Otherwise, `si:conversion-factor' returns: |
|
||
|
|
||
-3 |
|
||
if neither FROM-UNIT nor TO-UNIT is a syntactically valid |
|
||
unit. |
|
||
|
|
||
-2 |
|
||
if FROM-UNIT is not a syntactically valid unit. |
|
||
|
|
||
-1 |
|
||
if TO-UNIT is not a syntactically valid unit. |
|
||
|
|
||
0 |
|
||
if linear conversion (by a factor) is not possible. |
|
||
|
|
||
|
|
||
(si:conversion-factor "km/s" "m/s" ) => 0.001 |
|
||
(si:conversion-factor "N" "m/s" ) => 0 |
|
||
(si:conversion-factor "moC" "oC" ) => 1000 |
|
||
(si:conversion-factor "mK" "oC" ) => 0 |
|
||
(si:conversion-factor "rad" "o" ) => 0.0174533 |
|
||
(si:conversion-factor "K" "o" ) => 0 |
|
||
(si:conversion-factor "K" "K" ) => 1 |
|
||
(si:conversion-factor "oK" "oK" ) => -3 |
|
||
(si:conversion-factor "" "s/s" ) => 1 |
|
||
(si:conversion-factor "km/h" "mph" ) => -2 |
|
||
|
|
||
|
||
File: slib.info, Node: Standards Support, Next: Session Support, Prev: Procedures, Up: Other Packages
|
||
|
|
||
Standards Support
|
||
=================
|
||
|
||
* Menu:
|
||
|
||
* With-File:: 'with-file
|
||
* Transcripts:: 'transcript
|
||
* Rev2 Procedures:: 'rev2-procedures
|
||
* Rev4 Optional Procedures:: 'rev4-optional-procedures
|
||
* Multi-argument / and -:: 'multiarg/and-
|
||
* Multi-argument Apply:: 'multiarg-apply
|
||
* Rationalize:: 'rationalize
|
||
* Promises:: 'promise
|
||
* Dynamic-Wind:: 'dynamic-wind
|
||
* Eval:: 'eval
|
||
* Values:: 'values
|
||
|
||
|
||
File: slib.info, Node: With-File, Next: Transcripts, Prev: Standards Support, Up: Standards Support
|
||
|
||
With-File
|
||
---------
|
||
|
||
`(require 'with-file)'
|
||
|
||
- Function: with-input-from-file file thunk
|
||
- Function: with-output-to-file file thunk
|
||
Description found in R4RS.
|
||
|
||
|
||
File: slib.info, Node: Transcripts, Next: Rev2 Procedures, Prev: With-File, Up: Standards Support
|
||
|
||
Transcripts
|
||
-----------
|
||
|
||
`(require 'transcript)'
|
||
|
||
- Function: transcript-on filename
|
||
- Function: transcript-off filename
|
||
Redefines `read-char', `read', `write-char', `write', `display',
|
||
and `newline'.
|
||
|
||
|
||
File: slib.info, Node: Rev2 Procedures, Next: Rev4 Optional Procedures, Prev: Transcripts, Up: Standards Support
|
||
|
||
Rev2 Procedures
|
||
---------------
|
||
|
||
`(require 'rev2-procedures)'
|
||
|
||
The procedures below were specified in the `Revised^2 Report on
|
||
Scheme'. *N.B.*: The symbols `1+' and `-1+' are not `R4RS' syntax.
|
||
Scheme->C, for instance, barfs on this module.
|
||
|
||
- Procedure: substring-move-left! string1 start1 end1 string2 start2
|
||
- Procedure: substring-move-right! string1 start1 end1 string2 start2
|
||
STRING1 and STRING2 must be a strings, and START1, START2 and END1
|
||
must be exact integers satisfying
|
||
|
||
0 <= START1 <= END1 <= (string-length STRING1)
|
||
0 <= START2 <= END1 - START1 + START2 <= (string-length STRING2)
|
||
|
||
`substring-move-left!' and `substring-move-right!' store
|
||
characters of STRING1 beginning with index START1 (inclusive) and
|
||
ending with index END1 (exclusive) into STRING2 beginning with
|
||
index START2 (inclusive).
|
||
|
||
`substring-move-left!' stores characters in time order of
|
||
increasing indices. `substring-move-right!' stores characters in
|
||
time order of increasing indeces.
|
||
|
||
- Procedure: substring-fill! string start end char
|
||
Fills the elements START-END of STRING with the character CHAR.
|
||
|
||
- Function: string-null? str
|
||
== `(= 0 (string-length STR))'
|
||
|
||
- Procedure: append! . pairs
|
||
Destructively appends its arguments. Equivalent to `nconc'.
|
||
|
||
- Function: 1+ n
|
||
Adds 1 to N.
|
||
|
||
- Function: -1+ n
|
||
Subtracts 1 from N.
|
||
|
||
- Function: <?
|
||
- Function: <=?
|
||
- Function: =?
|
||
- Function: >?
|
||
- Function: >=?
|
||
These are equivalent to the procedures of the same name but
|
||
without the trailing `?'.
|
||
|
||
|
||
File: slib.info, Node: Rev4 Optional Procedures, Next: Multi-argument / and -, Prev: Rev2 Procedures, Up: Standards Support
|
||
|
||
Rev4 Optional Procedures
|
||
------------------------
|
||
|
||
`(require 'rev4-optional-procedures)'
|
||
|
||
For the specification of these optional procedures, *Note Standard
|
||
procedures: (r4rs)Standard procedures.
|
||
|
||
- Function: list-tail l p
|
||
|
||
- Function: string->list s
|
||
|
||
- Function: list->string l
|
||
|
||
- Function: string-copy
|
||
|
||
- Procedure: string-fill! s obj
|
||
|
||
- Function: list->vector l
|
||
|
||
- Function: vector->list s
|
||
|
||
- Procedure: vector-fill! s obj
|
||
|
||
|
||
File: slib.info, Node: Multi-argument / and -, Next: Multi-argument Apply, Prev: Rev4 Optional Procedures, Up: Standards Support
|
||
|
||
Multi-argument / and -
|
||
----------------------
|
||
|
||
`(require 'mutliarg/and-)'
|
||
|
||
For the specification of these optional forms, *Note Numerical
|
||
operations: (r4rs)Numerical operations. The `two-arg:'* forms are only
|
||
defined if the implementation does not support the many-argument forms.
|
||
|
||
- Function: two-arg:/ n1 n2
|
||
The original two-argument version of `/'.
|
||
|
||
- Function: / divident . divisors
|
||
|
||
- Function: two-arg:- n1 n2
|
||
The original two-argument version of `-'.
|
||
|
||
- Function: - minuend . subtrahends
|
||
|
||
|
||
File: slib.info, Node: Multi-argument Apply, Next: Rationalize, Prev: Multi-argument / and -, Up: Standards Support
|
||
|
||
Multi-argument Apply
|
||
--------------------
|
||
|
||
`(require 'multiarg-apply)'
|
||
|
||
For the specification of this optional form, *Note Control features:
|
||
(r4rs)Control features.
|
||
|
||
- Function: two-arg:apply proc l
|
||
The implementation's native `apply'. Only defined for
|
||
implementations which don't support the many-argument version.
|
||
|
||
- Function: apply proc . args
|
||
|
||
|
||
File: slib.info, Node: Rationalize, Next: Promises, Prev: Multi-argument Apply, Up: Standards Support
|
||
|
||
Rationalize
|
||
-----------
|
||
|
||
`(require 'rationalize)'
|
||
|
||
The procedure "rationalize" is interesting because most programming
|
||
languages do not provide anything analogous to it. Thanks to Alan
|
||
Bawden for contributing this algorithm.
|
||
|
||
- Function: rationalize x y
|
||
Computes the correct result for exact arguments (provided the
|
||
implementation supports exact rational numbers of unlimited
|
||
precision); and produces a reasonable answer for inexact arguments
|
||
when inexact arithmetic is implemented using floating-point.
|
||
|
||
`Rationalize' has limited use in implementations lacking exact
|
||
(non-integer) rational numbers. The following procedures return a list
|
||
of the numerator and denominator.
|
||
|
||
- Function: find-ratio x y
|
||
`find-ratio' returns the list of the _simplest_ numerator and
|
||
denominator whose quotient differs from X by no more than Y.
|
||
|
||
(find-ratio 3/97 .0001) => (3 97) |
|
||
(find-ratio 3/97 .001) => (1 32) |
|
||
|
||
- Function: find-ratio-between x y
|
||
`find-ratio-between' returns the list of the _simplest_ numerator
|
||
and denominator between X and Y.
|
||
|
||
(find-ratio-between 2/7 3/5) => (1 2) |
|
||
(find-ratio-between -3/5 -2/7) => (-1 2) |
|
||
|
||
|
||
File: slib.info, Node: Promises, Next: Dynamic-Wind, Prev: Rationalize, Up: Standards Support
|
||
|
||
Promises
|
||
--------
|
||
|
||
`(require 'promise)'
|
||
|
||
- Function: make-promise proc
|
||
|
||
Change occurrences of `(delay EXPRESSION)' to `(make-promise (lambda
|
||
() EXPRESSION))' and `(define force promise:force)' to implement
|
||
promises if your implementation doesn't support them (*note Control
|
||
features: (r4rs)Control features.).
|
||
|
||
|
||
File: slib.info, Node: Dynamic-Wind, Next: Eval, Prev: Promises, Up: Standards Support
|
||
|
||
Dynamic-Wind
|
||
------------
|
||
|
||
`(require 'dynamic-wind)'
|
||
|
||
This facility is a generalization of Common LISP `unwind-protect',
|
||
designed to take into account the fact that continuations produced by
|
||
`call-with-current-continuation' may be reentered.
|
||
|
||
- Procedure: dynamic-wind thunk1 thunk2 thunk3
|
||
The arguments THUNK1, THUNK2, and THUNK3 must all be procedures of
|
||
no arguments (thunks).
|
||
|
||
`dynamic-wind' calls THUNK1, THUNK2, and then THUNK3. The value
|
||
returned by THUNK2 is returned as the result of `dynamic-wind'.
|
||
THUNK3 is also called just before control leaves the dynamic
|
||
context of THUNK2 by calling a continuation created outside that
|
||
context. Furthermore, THUNK1 is called before reentering the
|
||
dynamic context of THUNK2 by calling a continuation created inside
|
||
that context. (Control is inside the context of THUNK2 if THUNK2
|
||
is on the current return stack).
|
||
|
||
*Warning:* There is no provision for dealing with errors or
|
||
interrupts. If an error or interrupt occurs while using
|
||
`dynamic-wind', the dynamic environment will be that in effect at
|
||
the time of the error or interrupt.
|
||
|
||
|
||
File: slib.info, Node: Eval, Next: Values, Prev: Dynamic-Wind, Up: Standards Support
|
||
|
||
Eval
|
||
----
|
||
|
||
`(require 'eval)'
|
||
|
||
- Function: eval expression environment-specifier
|
||
Evaluates EXPRESSION in the specified environment and returns its
|
||
value. EXPRESSION must be a valid Scheme expression represented
|
||
as data, and ENVIRONMENT-SPECIFIER must be a value returned by one
|
||
of the three procedures described below. Implementations may
|
||
extend `eval' to allow non-expression programs (definitions) as
|
||
the first argument and to allow other values as environments, with
|
||
the restriction that `eval' is not allowed to create new bindings
|
||
in the environments associated with `null-environment' or
|
||
`scheme-report-environment'.
|
||
|
||
(eval '(* 7 3) (scheme-report-environment 5))
|
||
=> 21
|
||
|
||
(let ((f (eval '(lambda (f x) (f x x))
|
||
(null-environment))))
|
||
(f + 10))
|
||
=> 20
|
||
|
||
- Function: scheme-report-environment version
|
||
- Function: null-environment version
|
||
- Function: null-environment
|
||
VERSION must be an exact non-negative integer N corresponding to a
|
||
version of one of the Revised^N Reports on Scheme.
|
||
`Scheme-report-environment' returns a specifier for an environment
|
||
that contains the set of bindings specified in the corresponding
|
||
report that the implementation supports. `Null-environment'
|
||
returns a specifier for an environment that contains only the
|
||
(syntactic) bindings for all the syntactic keywords defined in the
|
||
given version of the report.
|
||
|
||
Not all versions may be available in all implementations at all
|
||
times. However, an implementation that conforms to version N of
|
||
the Revised^N Reports on Scheme must accept version N. An error
|
||
is signalled if the specified version is not available.
|
||
|
||
The effect of assigning (through the use of `eval') a variable
|
||
bound in a `scheme-report-environment' (for example `car') is
|
||
unspecified. Thus the environments specified by
|
||
`scheme-report-environment' may be immutable.
|
||
|
||
|
||
- Function: interaction-environment
|
||
This optional procedure returns a specifier for the environment
|
||
that contains implementation-defined bindings, typically a
|
||
superset of those listed in the report. The intent is that this
|
||
procedure will return the environment in which the implementation
|
||
would evaluate expressions dynamically typed by the user.
|
||
|
||
Here are some more `eval' examples:
|
||
|
||
(require 'eval)
|
||
=> #<unspecified>
|
||
(define car 'volvo)
|
||
=> #<unspecified>
|
||
car
|
||
=> volvo
|
||
(eval 'car (interaction-environment))
|
||
=> volvo
|
||
(eval 'car (scheme-report-environment 5))
|
||
=> #<primitive-procedure car>
|
||
(eval '(eval 'car (interaction-environment))
|
||
(scheme-report-environment 5))
|
||
=> volvo
|
||
(eval '(eval '(set! car 'buick) (interaction-environment))
|
||
(scheme-report-environment 5))
|
||
=> #<unspecified>
|
||
car
|
||
=> buick
|
||
(eval 'car (scheme-report-environment 5))
|
||
=> #<primitive-procedure car>
|
||
(eval '(eval 'car (interaction-environment))
|
||
(scheme-report-environment 5))
|
||
=> buick
|
||
|
||
|
||
File: slib.info, Node: Values, Prev: Eval, Up: Standards Support
|
||
|
||
Values
|
||
------
|
||
|
||
`(require 'values)'
|
||
|
||
- Function: values obj ...
|
||
`values' takes any number of arguments, and passes (returns) them
|
||
to its continuation.
|
||
|
||
- Function: call-with-values thunk proc
|
||
THUNK must be a procedure of no arguments, and PROC must be a
|
||
procedure. `call-with-values' calls THUNK with a continuation
|
||
that, when passed some values, calls PROC with those values as
|
||
arguments.
|
||
|
||
Except for continuations created by the `call-with-values'
|
||
procedure, all continuations take exactly one value, as now; the
|
||
effect of passing no value or more than one value to continuations
|
||
that were not created by the `call-with-values' procedure is
|
||
unspecified.
|
||
|
||
|
||
File: slib.info, Node: Session Support, Next: Extra-SLIB Packages, Prev: Standards Support, Up: Other Packages
|
||
|
||
Session Support
|
||
===============
|
||
|
||
* Menu:
|
||
|
||
* Repl:: Macros at top-level
|
||
* Quick Print:: Loop-safe Output
|
||
* Debug:: To err is human ...
|
||
* Breakpoints:: Pause execution
|
||
* Trace:: 'trace
|
||
* System Interface:: 'system, 'getenv, and 'net-clients
|
||
|
||
|
||
File: slib.info, Node: Repl, Next: Quick Print, Prev: Session Support, Up: Session Support
|
||
|
||
Repl
|
||
----
|
||
|
||
`(require 'repl)'
|
||
|
||
Here is a read-eval-print-loop which, given an eval, evaluates forms.
|
||
|
||
- Procedure: repl:top-level repl:eval
|
||
`read's, `repl:eval's and `write's expressions from
|
||
`(current-input-port)' to `(current-output-port)' until an
|
||
end-of-file is encountered. `load', `slib:eval', `slib:error',
|
||
and `repl:quit' dynamically bound during `repl:top-level'.
|
||
|
||
- Procedure: repl:quit
|
||
Exits from the invocation of `repl:top-level'.
|
||
|
||
The `repl:' procedures establish, as much as is possible to do
|
||
portably, a top level environment supporting macros. `repl:top-level'
|
||
uses `dynamic-wind' to catch error conditions and interrupts. If your
|
||
implementation supports this you are all set.
|
||
|
||
Otherwise, if there is some way your implementation can catch error
|
||
conditions and interrupts, then have them call `slib:error'. It will
|
||
display its arguments and reenter `repl:top-level'. `slib:error'
|
||
dynamically bound by `repl:top-level'.
|
||
|
||
To have your top level loop always use macros, add any interrupt
|
||
catching lines and the following lines to your Scheme init file:
|
||
(require 'macro)
|
||
(require 'repl)
|
||
(repl:top-level macro:eval)
|
||
|
||
|
||
File: slib.info, Node: Quick Print, Next: Debug, Prev: Repl, Up: Session Support
|
||
|
||
Quick Print
|
||
-----------
|
||
|
||
`(require 'qp)'
|
||
|
||
When displaying error messages and warnings, it is paramount that the
|
||
output generated for circular lists and large data structures be
|
||
limited. This section supplies a procedure to do this. It could be
|
||
much improved.
|
||
|
||
Notice that the neccessity for truncating output eliminates
|
||
Common-Lisp's *Note Format:: from consideration; even when
|
||
variables `*print-level*' and `*print-level*' are set, huge
|
||
strings and bit-vectors are _not_ limited.
|
||
|
||
- Procedure: qp arg1 ...
|
||
- Procedure: qpn arg1 ...
|
||
- Procedure: qpr arg1 ...
|
||
`qp' writes its arguments, separated by spaces, to
|
||
`(current-output-port)'. `qp' compresses printing by substituting
|
||
`...' for substructure it does not have sufficient room to print.
|
||
`qpn' is like `qp' but outputs a newline before returning. `qpr'
|
||
is like `qpn' except that it returns its last argument.
|
||
|
||
- Variable: *qp-width*
|
||
`*qp-width*' is the largest number of characters that `qp' should
|
||
use.
|
||
|
||
|
||
File: slib.info, Node: Debug, Next: Breakpoints, Prev: Quick Print, Up: Session Support
|
||
|
||
Debug
|
||
-----
|
||
|
||
`(require 'debug)'
|
||
|
||
Requiring `debug' automatically requires `trace' and `break'.
|
||
|
||
An application with its own datatypes may want to substitute its own
|
||
printer for `qp'. This example shows how to do this:
|
||
|
||
(define qpn (lambda args) ...)
|
||
(provide 'qp)
|
||
(require 'debug)
|
||
|
||
- Procedure: trace-all file ...
|
||
Traces (*note Trace::) all procedures `define'd at top-level in
|
||
`file' ....
|
||
|
||
- Procedure: track-all file ...
|
||
Tracks (*note Trace::) all procedures `define'd at top-level in
|
||
`file' ....
|
||
|
||
- Procedure: stack-all file ...
|
||
Stacks (*note Trace::) all procedures `define'd at top-level in
|
||
`file' ....
|
||
|
||
- Procedure: break-all file ...
|
||
Breakpoints (*note Breakpoints::) all procedures `define'd at
|
||
top-level in `file' ....
|
||
|
||
|
||
File: slib.info, Node: Breakpoints, Next: Trace, Prev: Debug, Up: Session Support
|
||
|
||
Breakpoints
|
||
-----------
|
||
|
||
`(require 'break)'
|
||
|
||
- Function: init-debug
|
||
If your Scheme implementation does not support `break' or `abort',
|
||
a message will appear when you `(require 'break)' or `(require
|
||
'debug)' telling you to type `(init-debug)'. This is in order to
|
||
establish a top-level continuation. Typing `(init-debug)' at top
|
||
level sets up a continuation for `break'.
|
||
|
||
- Function: breakpoint arg1 ...
|
||
Returns from the top level continuation and pushes the
|
||
continuation from which it was called on a continuation stack.
|
||
|
||
- Function: continue
|
||
Pops the topmost continuation off of the continuation stack and
|
||
returns an unspecified value to it.
|
||
|
||
- Function: continue arg1 ...
|
||
Pops the topmost continuation off of the continuation stack and
|
||
returns ARG1 ... to it.
|
||
|
||
- Macro: break proc1 ...
|
||
Redefines the top-level named procedures given as arguments so that
|
||
`breakpoint' is called before calling PROC1 ....
|
||
|
||
- Macro: break
|
||
With no arguments, makes sure that all the currently broken
|
||
identifiers are broken (even if those identifiers have been
|
||
redefined) and returns a list of the broken identifiers.
|
||
|
||
- Macro: unbreak proc1 ...
|
||
Turns breakpoints off for its arguments.
|
||
|
||
- Macro: unbreak
|
||
With no arguments, unbreaks all currently broken identifiers and
|
||
returns a list of these formerly broken identifiers.
|
||
|
||
These are _procedures_ for breaking. If defmacros are not natively
|
||
supported by your implementation, these might be more convenient to use.
|
||
|
||
- Function: breakf proc
|
||
- Function: breakf proc name
|
||
To break, type
|
||
(set! SYMBOL (breakf SYMBOL))
|
||
|
||
or
|
||
(set! SYMBOL (breakf SYMBOL 'SYMBOL))
|
||
|
||
or
|
||
(define SYMBOL (breakf FUNCTION))
|
||
|
||
or
|
||
(define SYMBOL (breakf FUNCTION 'SYMBOL))
|
||
|
||
- Function: unbreakf proc
|
||
To unbreak, type
|
||
(set! SYMBOL (unbreakf SYMBOL))
|
||
|
||
|
||
File: slib.info, Node: Trace, Next: System Interface, Prev: Breakpoints, Up: Session Support
|
||
|
||
Tracing
|
||
-------
|
||
|
||
`(require 'trace)'
|
||
|
||
This feature provides three ways to monitor procedure invocations:
|
||
|
||
stack
|
||
Pushes the procedure-name when the procedure is called; pops when
|
||
it returns.
|
||
|
||
track
|
||
Pushes the procedure-name and arguments when the procedure is
|
||
called; pops when it returns.
|
||
|
||
trace
|
||
Pushes the procedure-name and prints `CALL PROCEDURE-NAME ARG1
|
||
...' when the procdure is called; pops and prints `RETN
|
||
PROCEDURE-NAME VALUE' when the procedure returns.
|
||
|
||
- Variable: debug:max-count
|
||
If a traced procedure calls itself or untraced procedures which
|
||
call it, stack, track, and trace will limit the number of stack
|
||
pushes to DEBUG:MAX-COUNT.
|
||
|
||
- Function: print-call-stack
|
||
- Function: print-call-stack port
|
||
Prints the call-stack to PORT or the current-error-port.
|
||
|
||
- Macro: trace proc1 ...
|
||
Traces the top-level named procedures given as arguments.
|
||
|
||
- Macro: trace
|
||
With no arguments, makes sure that all the currently traced
|
||
identifiers are traced (even if those identifiers have been
|
||
redefined) and returns a list of the traced identifiers.
|
||
|
||
- Macro: track proc1 ...
|
||
Traces the top-level named procedures given as arguments.
|
||
|
||
- Macro: track
|
||
With no arguments, makes sure that all the currently tracked
|
||
identifiers are tracked (even if those identifiers have been
|
||
redefined) and returns a list of the tracked identifiers.
|
||
|
||
- Macro: stack proc1 ...
|
||
Traces the top-level named procedures given as arguments.
|
||
|
||
- Macro: stack
|
||
With no arguments, makes sure that all the currently stacked
|
||
identifiers are stacked (even if those identifiers have been
|
||
redefined) and returns a list of the stacked identifiers.
|
||
|
||
- Macro: untrace proc1 ...
|
||
Turns tracing, tracking, and off for its arguments.
|
||
|
||
- Macro: untrace
|
||
With no arguments, untraces all currently traced identifiers and
|
||
returns a list of these formerly traced identifiers.
|
||
|
||
- Macro: untrack proc1 ...
|
||
Turns tracing, tracking, and off for its arguments.
|
||
|
||
- Macro: untrack
|
||
With no arguments, untracks all currently tracked identifiers and
|
||
returns a list of these formerly tracked identifiers.
|
||
|
||
- Macro: unstack proc1 ...
|
||
Turns tracing, stacking, and off for its arguments.
|
||
|
||
- Macro: unstack
|
||
With no arguments, unstacks all currently stacked identifiers and
|
||
returns a list of these formerly stacked identifiers.
|
||
|
||
These are _procedures_ for tracing. If defmacros are not natively
|
||
supported by your implementation, these might be more convenient to use.
|
||
|
||
- Function: tracef proc
|
||
- Function: tracef proc name
|
||
To trace, type
|
||
(set! SYMBOL (tracef SYMBOL))
|
||
|
||
or
|
||
(set! SYMBOL (tracef SYMBOL 'SYMBOL))
|
||
|
||
or
|
||
(define SYMBOL (tracef FUNCTION))
|
||
|
||
or
|
||
(define SYMBOL (tracef FUNCTION 'SYMBOL))
|
||
|
||
- Function: untracef proc
|
||
Removes tracing, tracking, or stacking for PROC. To untrace, type
|
||
(set! SYMBOL (untracef SYMBOL))
|
||
|
||
|
||
File: slib.info, Node: System Interface, Prev: Trace, Up: Session Support
|
||
|
||
System Interface
|
||
----------------
|
||
|
||
If `(provided? 'getenv)':
|
||
|
||
- Function: getenv name
|
||
Looks up NAME, a string, in the program environment. If NAME is
|
||
found a string of its value is returned. Otherwise, `#f' is
|
||
returned.
|
||
|
||
If `(provided? 'system)':
|
||
|
||
- Function: system command-string
|
||
Executes the COMMAND-STRING on the computer and returns the
|
||
integer status code.
|
||
|
||
If `system' is provided by the Scheme implementation, the "net-clients"
|
||
package provides interfaces to common network client programs like FTP,
|
||
mail, and Netscape.
|
||
|
||
`(require 'net-clients)'
|
||
|
||
- Function: call-with-tmpnam proc
|
||
- Function: call-with-tmpnam proc k
|
||
Calls PROC with K arguments, strings returned by successive calls
|
||
to `tmpnam'. If PROC returns, then any files named by the
|
||
arguments to PROC are deleted automatically and the value(s)
|
||
yielded by the PROC is(are) returned. K may be ommited, in which
|
||
case it defaults to `1'.
|
||
|
||
- Function: user-email-address
|
||
`user-email-address' returns a string of the form
|
||
`username@hostname'. If this e-mail address cannot be obtained,
|
||
#f is returned.
|
||
|
||
- Function: current-directory
|
||
`current-directory' returns a string containing the absolute file
|
||
name representing the current working directory. If this string
|
||
cannot be obtained, #f is returned.
|
||
|
||
If `current-directory' cannot be supported by the platform, the
|
||
value of `current-directory' is #f.
|
||
|
||
- Function: make-directory name
|
||
Creates a sub-directory NAME of the current-directory. If
|
||
successful, `make-directory' returns #t; otherwise #f.
|
||
|
||
- Function: null-directory? file-name
|
||
Returns #t if changing directory to FILE-NAME makes the current
|
||
working directory the same as it is before changing directory;
|
||
otherwise returns #f.
|
||
|
||
- Function: absolute-path? file-name
|
||
Returns #t if FILE-NAME is a fully specified pathname (does not
|
||
depend on the current working directory); otherwise returns #f.
|
||
|
||
- Function: glob-pattern? str
|
||
Returns #t if the string STR contains characters used for
|
||
specifying glob patterns, namely `*', `?', or `['.
|
||
|
||
- Function: parse-ftp-address uri |
|
||
Returns a list of the decoded FTP URI; or #f if indecipherable. |
|
||
FTP "Uniform Resource Locator", "ange-ftp", and "getit" formats
|
||
are handled. The returned list has four elements which are
|
||
strings or #f:
|
||
|
||
0. username
|
||
|
||
1. password
|
||
|
||
2. remote-site
|
||
|
||
3. remote-directory
|
||
|
||
- Function: ftp-upload paths user password remote-site remote-dir
|
||
PASSWORD must be a non-empty string or #f. PATHS must be a
|
||
non-empty list of pathnames or Glob patterns (*note Filenames::)
|
||
matching files to transfer.
|
||
|
||
`ftp-upload' puts the files specified by PATHS into the REMOTE-DIR
|
||
directory of FTP REMOTE-SITE using name USER with (optional)
|
||
PASSWORD.
|
||
|
||
If PASSWORD is #f and USER is not `ftp' or `anonymous', then USER
|
||
is ignored; FTP takes the username and password from the `.netrc'
|
||
or equivalent file.
|
||
|
||
- Function: path->uri path |
|
||
Returns a URI-string for PATH on the local host. |
|
||
|
||
- Function: browse-url-netscape url
|
||
If a `netscape' browser is running, `browse-url-netscape' causes
|
||
the browser to display the page specified by string URL and
|
||
returns #t.
|
||
|
||
If the browser is not running, `browse-url-netscape' runs
|
||
`netscape' with the argument URL. If the browser starts as a
|
||
background job, `browse-url-netscape' returns #t immediately; if
|
||
the browser starts as a foreground job, then `browse-url-netscape'
|
||
returns #t when the browser exits; otherwise it returns #f.
|
||
|
||
|
||
File: slib.info, Node: Extra-SLIB Packages, Prev: Session Support, Up: Other Packages
|
||
|
||
Extra-SLIB Packages
|
||
===================
|
||
|
||
Several Scheme packages have been written using SLIB. There are
|
||
several reasons why a package might not be included in the SLIB
|
||
distribution:
|
||
* Because it requires special hardware or software which is not
|
||
universal.
|
||
|
||
* Because it is large and of limited interest to most Scheme users.
|
||
|
||
* Because it has copying terms different enough from the other SLIB
|
||
packages that its inclusion would cause confusion.
|
||
|
||
* Because it is an application program, rather than a library module.
|
||
|
||
* Because I have been too busy to integrate it.
|
||
|
||
Once an optional package is installed (and an entry added to
|
||
`*catalog*', the `require' mechanism allows it to be called up and used
|
||
as easily as any other SLIB package. Some optional packages (for which
|
||
`*catalog*' already has entries) available from SLIB sites are:
|
||
|
||
SLIB-PSD
|
||
is a portable debugger for Scheme (requires emacs editor).
|
||
|
||
http://swissnet.ai.mit.edu/ftpdir/scm/slib-psd1-3.tar.gz
|
||
|
||
swissnet.ai.mit.edu:/pub/scm/slib-psd1-3.tar.gz
|
||
|
||
ftp.maths.tcd.ie:pub/bosullvn/jacal/slib-psd1-3.tar.gz
|
||
|
||
ftp.cs.indiana.edu:/pub/scheme-repository/utl/slib-psd1-3.tar.gz
|
||
|
||
|
||
With PSD, you can run a Scheme program in an Emacs buffer, set
|
||
breakpoints, single step evaluation and access and modify the
|
||
program's variables. It works by instrumenting the original source
|
||
code, so it should run with any R4RS compliant Scheme. It has been
|
||
tested with SCM, Elk 1.5, and the sci interpreter in the Scheme->C
|
||
system, but should work with other Schemes with a minimal amount
|
||
of porting, if at all. Includes documentation and user's manual.
|
||
Written by Pertti Kellom\"aki, pk@cs.tut.fi. The Lisp Pointers
|
||
article describing PSD (Lisp Pointers VI(1):15-23, January-March
|
||
1993) is available as
|
||
http://www.cs.tut.fi/staff/pk/scheme/psd/article/article.html
|
||
|
||
|
||
SCHELOG
|
||
is an embedding of Prolog in Scheme.
|
||
http://www.cs.rice.edu/CS/PLT/packages/schelog/
|
||
|
||
|
||
JFILTER
|
||
is a Scheme program which converts text among the JIS, EUC, and
|
||
Shift-JIS Japanese character sets.
|
||
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/Jfilter/index.html
|
||
|
||
|
||
File: slib.info, Node: About SLIB, Next: Index, Prev: Other Packages, Up: Top
|
||
|
||
About SLIB
|
||
**********
|
||
|
||
More people than I can name have contributed to SLIB. Thanks to all of
|
||
you!
|
||
|
||
SLIB 2d1, released March 2001. |
|
||
Aubrey Jaffer <jaffer @ ai.mit.edu>
|
||
Hyperactive Software - The Maniac Inside!
|
||
<http://swissnet.ai.mit.edu/~jaffer/SLIB.html>
|
||
|
||
* Menu:
|
||
|
||
* Installation:: How to install SLIB on your system.
|
||
* Porting:: SLIB to new platforms.
|
||
* Coding Guidelines:: How to write modules for SLIB.
|
||
* Copyrights:: Intellectual propery issues.
|
||
|
||
|
||
File: slib.info, Node: Installation, Next: Porting, Prev: About SLIB, Up: About SLIB
|
||
|
||
Installation
|
||
============
|
||
|
||
Check the manifest in `README' to find a configuration file for your
|
||
Scheme implementation. Initialization files for most IEEE P1178
|
||
compliant Scheme Implementations are included with this distribution.
|
||
|
||
If the Scheme implementation supports `getenv', then the value of the
|
||
shell environment variable SCHEME_LIBRARY_PATH will be used for
|
||
`(library-vicinity)' if it is defined. Currently, Chez, Elk,
|
||
MITScheme, scheme->c, VSCM, and SCM support `getenv'. Scheme48
|
||
supports `getenv' but does not use it for determining
|
||
`library-vicinity'. (That is done from the Makefile.)
|
||
|
||
You should check the definitions of `software-type',
|
||
`scheme-implementation-version', `implementation-vicinity', and
|
||
`library-vicinity' in the initialization file. There are comments in
|
||
the file for how to configure it.
|
||
|
||
Once this is done you can modify the startup file for your Scheme
|
||
implementation to `load' this initialization file. SLIB is then
|
||
installed.
|
||
|
||
Multiple implementations of Scheme can all use the same SLIB
|
||
directory. Simply configure each implementation's initialization file
|
||
as outlined above.
|
||
|
||
- Implementation: SCM
|
||
The SCM implementation does not require any initialization file as
|
||
SLIB support is already built into SCM. See the documentation
|
||
with SCM for installation instructions.
|
||
|
||
- Implementation: VSCM
|
||
From: Matthias Blume <blume@cs.Princeton.EDU>
|
||
Date: Tue, 1 Mar 1994 11:42:31 -0500
|
||
|
||
Disclaimer: The code below is only a quick hack. If I find some
|
||
time to spare I might get around to make some more things work.
|
||
|
||
You have to provide `vscm.init' as an explicit command line
|
||
argument. Since this is not very nice I would recommend the
|
||
following installation procedure:
|
||
|
||
1. run scheme
|
||
|
||
2. `(load "vscm.init")'
|
||
|
||
3. `(slib:dump "dumpfile")'
|
||
|
||
4. mv dumpfile place-where-vscm-standard-bootfile-resides e.g.
|
||
mv dumpfile /usr/local/vscm/lib/scheme-boot (In this case
|
||
vscm should have been compiled with flag
|
||
-DDEFAULT_BOOTFILE='"/usr/local/vscm/lib/scheme-boot"'. See
|
||
Makefile (definition of DDP) for details.)
|
||
|
||
|
||
- Implementation: Scheme48
|
||
To make a Scheme48 image for an installation under `<prefix>',
|
||
|
||
1. `cd' to the SLIB directory
|
||
|
||
2. type `make prefix=<prefix> slib48'.
|
||
|
||
3. To install the image, type `make prefix=<prefix> install48'.
|
||
This will also create a shell script with the name `slib48'
|
||
which will invoke the saved image.
|
||
|
||
- Implementation: PLT Scheme
|
||
- Implementation: DrScheme
|
||
- Implementation: MzScheme
|
||
Date: Mon, 2 Oct 2000 21:29:48 -0400 (EDT)
|
||
From: Shriram Krishnamurthi <sk@cs.brown.edu>
|
||
|
||
We distribute an SLIB init file for our system. If you have PLT
|
||
Scheme (our preferred name for the entire suite, which includes
|
||
DrScheme, MzScheme and other implementations) installed, you ought
|
||
to be able to run "help-desk", or run `drscheme' and choose Help
|
||
Desk from the Help menu; in Help Desk, type `slib'. This will give
|
||
instructions for how to load the SLIB init file.
|
||
|
||
|
||
File: slib.info, Node: Porting, Next: Coding Guidelines, Prev: Installation, Up: About SLIB
|
||
|
||
Porting
|
||
=======
|
||
|
||
If there is no initialization file for your Scheme implementation, you
|
||
will have to create one. Your Scheme implementation must be largely
|
||
compliant with `IEEE Std 1178-1990', `Revised^4 Report on the
|
||
Algorithmic Language Scheme', or `Revised^5 Report on the Algorithmic
|
||
Language Scheme' in order to support SLIB. (1)
|
||
|
||
`Template.scm' is an example configuration file. The comments inside
|
||
will direct you on how to customize it to reflect your system. Give
|
||
your new initialization file the implementation's name with `.init'
|
||
appended. For instance, if you were porting `foo-scheme' then the
|
||
initialization file might be called `foo.init'.
|
||
|
||
Your customized version should then be loaded as part of your scheme
|
||
implementation's initialization. It will load `require.scm' from the
|
||
library; this will allow the use of `provide', `provided?', and
|
||
`require' along with the "vicinity" functions (these functions are
|
||
documented in the section *Note Require::). The rest of the library
|
||
will then be accessible in a system independent fashion.
|
||
|
||
Please mail new working configuration files to `jaffer @ ai.mit.edu'
|
||
so that they can be included in the SLIB distribution.
|
||
|
||
---------- Footnotes ----------
|
||
|
||
(1) If you are porting a `Revised^3 Report on the Algorithmic
|
||
Language Scheme' implementation, then you will need to finish writing
|
||
`sc4sc3.scm' and `load' it from your initialization file.
|
||
|
||
|
||
File: slib.info, Node: Coding Guidelines, Next: Copyrights, Prev: Porting, Up: About SLIB
|
||
|
||
Coding Guidelines
|
||
=================
|
||
|
||
All library packages are written in IEEE P1178 Scheme and assume that
|
||
a configuration file and `require.scm' package have already been
|
||
loaded. Other versions of Scheme can be supported in library packages
|
||
as well by using, for example, `(provided? 'rev3-report)' or `(require
|
||
'rev3-report)' (*note Require::).
|
||
|
||
The module name and `:' should prefix each symbol defined in the
|
||
package. Definitions for external use should then be exported by having
|
||
`(define foo module-name:foo)'.
|
||
|
||
Code submitted for inclusion in SLIB should not duplicate routines
|
||
already in SLIB files. Use `require' to force those library routines
|
||
to be used by your package. Care should be taken that there are no
|
||
circularities in the `require's and `load's between the library
|
||
packages.
|
||
|
||
Documentation should be provided in Emacs Texinfo format if possible,
|
||
But documentation must be provided.
|
||
|
||
Your package will be released sooner with SLIB if you send me a file
|
||
which tests your code. Please run this test _before_ you send me the
|
||
code!
|
||
|
||
Modifications
|
||
-------------
|
||
|
||
Please document your changes. A line or two for `ChangeLog' is
|
||
sufficient for simple fixes or extensions. Look at the format of
|
||
`ChangeLog' to see what information is desired. Please send me `diff'
|
||
files from the latest SLIB distribution (remember to send `diff's of
|
||
`slib.texi' and `ChangeLog'). This makes for less email traffic and
|
||
makes it easier for me to integrate when more than one person is
|
||
changing a file (this happens a lot with `slib.texi' and `*.init'
|
||
files).
|
||
|
||
If someone else wrote a package you want to significantly modify,
|
||
please try to contact the author, who may be working on a new version.
|
||
This will insure against wasting effort on obsolete versions.
|
||
|
||
Please _do not_ reformat the source code with your favorite
|
||
beautifier, make 10 fixes, and send me the resulting source code. I do
|
||
not have the time to fish through 10000 diffs to find your 10 real
|
||
fixes.
|
||
|
||
|
||
File: slib.info, Node: Copyrights, Prev: Coding Guidelines, Up: About SLIB
|
||
|
||
Copyrights
|
||
==========
|
||
|
||
This section has instructions for SLIB authors regarding copyrights.
|
||
|
||
Each package in SLIB must either be in the public domain, or come
|
||
with a statement of terms permitting users to copy, redistribute and
|
||
modify it. The comments at the beginning of `require.scm' and
|
||
`macwork.scm' illustrate copyright and appropriate terms.
|
||
|
||
If your code or changes amount to less than about 10 lines, you do not
|
||
need to add your copyright or send a disclaimer.
|
||
|
||
Putting code into the Public Domain
|
||
-----------------------------------
|
||
|
||
In order to put code in the public domain you should sign a copyright
|
||
disclaimer and send it to the SLIB maintainer. Contact jaffer @
|
||
ai.mit.edu for the address to mail the disclaimer to.
|
||
|
||
I, NAME, hereby affirm that I have placed the software package
|
||
NAME in the public domain.
|
||
|
||
I affirm that I am the sole author and sole copyright holder for
|
||
the software package, that I have the right to place this software
|
||
package in the public domain, and that I will do nothing to
|
||
undermine this status in the future.
|
||
|
||
SIGNATURE AND DATE
|
||
|
||
This wording assumes that you are the sole author. If you are not the
|
||
sole author, the wording needs to be different. If you don't want to be
|
||
bothered with sending a letter every time you release or modify a
|
||
module, make your letter say that it also applies to your future
|
||
revisions of that module.
|
||
|
||
Make sure no employer has any claim to the copyright on the work you
|
||
are submitting. If there is any doubt, create a copyright disclaimer
|
||
and have your employer sign it. Mail the signed disclaimer to the SLIB
|
||
maintainer. Contact jaffer @ ai.mit.edu for the address to mail the
|
||
disclaimer to. An example disclaimer follows.
|
||
|
||
Explicit copying terms
|
||
----------------------
|
||
|
||
If you submit more than about 10 lines of code which you are not placing
|
||
into the Public Domain (by sending me a disclaimer) you need to:
|
||
|
||
* Arrange that your name appears in a copyright line for the
|
||
appropriate year. Multiple copyright lines are acceptable.
|
||
|
||
* With your copyright line, specify any terms you require to be
|
||
different from those already in the file.
|
||
|
||
* Make sure no employer has any claim to the copyright on the work
|
||
you are submitting. If there is any doubt, create a copyright
|
||
disclaimer and have your employer sign it. Mail the signed
|
||
disclaim to the SLIB maintainer. Contact jaffer @ ai.mit.edu for
|
||
the address to mail the disclaimer to.
|
||
|
||
Example: Company Copyright Disclaimer
|
||
-------------------------------------
|
||
|
||
This disclaimer should be signed by a vice president or general
|
||
manager of the company. If you can't get at them, anyone else
|
||
authorized to license out software produced there will do. Here is a
|
||
sample wording:
|
||
|
||
EMPLOYER Corporation hereby disclaims all copyright interest in
|
||
the program PROGRAM written by NAME.
|
||
|
||
EMPLOYER Corporation affirms that it has no other intellectual
|
||
property interest that would undermine this release, and will do
|
||
nothing to undermine it in the future.
|
||
|
||
SIGNATURE AND DATE,
|
||
NAME, TITLE, EMPLOYER Corporation
|
||
|
||
|
||
File: slib.info, Node: Index, Prev: About SLIB, Up: Top
|
||
|
||
Procedure and Macro Index
|
||
*************************
|
||
|
||
This is an alphabetical list of all the procedures and macros in SLIB.
|
||
|
||
* Menu:
|
||
|
||
* -: Multi-argument / and -.
|
||
* -1+: Rev2 Procedures.
|
||
* /: Multi-argument / and -.
|
||
* 1+: Rev2 Procedures.
|
||
* <=?: Rev2 Procedures.
|
||
* <?: Rev2 Procedures.
|
||
* =?: Rev2 Procedures.
|
||
* >=?: Rev2 Procedures.
|
||
* >?: Rev2 Procedures.
|
||
* absolute-path?: System Interface.
|
||
* add-domain: Database Utilities.
|
||
* add-process!: Multi-Processing.
|
||
* add-setter: Setters.
|
||
* adjoin: Lists as sets.
|
||
* adjoin-parameters!: Parameter lists.
|
||
* alarm: Multi-Processing.
|
||
* alarm-interrupt: Multi-Processing.
|
||
* alist->wt-tree: Construction of Weight-Balanced Trees.
|
||
* alist-associator: Association Lists.
|
||
* alist-for-each: Association Lists.
|
||
* alist-inquirer: Association Lists.
|
||
* alist-map: Association Lists.
|
||
* alist-remover: Association Lists.
|
||
* and?: Non-List functions.
|
||
* any?: Collections.
|
||
* append!: Rev2 Procedures.
|
||
* apply: Multi-argument Apply.
|
||
* array-1d-ref: Arrays.
|
||
* array-1d-set!: Arrays.
|
||
* array-2d-ref: Arrays.
|
||
* array-2d-set!: Arrays.
|
||
* array-3d-ref: Arrays.
|
||
* array-3d-set!: Arrays.
|
||
* array-copy!: Array Mapping.
|
||
* array-dimensions: Arrays.
|
||
* array-for-each: Array Mapping.
|
||
* array-in-bounds?: Arrays.
|
||
* array-index-map!: Array Mapping.
|
||
* array-indexes: Array Mapping.
|
||
* array-map!: Array Mapping.
|
||
* array-rank: Arrays.
|
||
* array-ref: Arrays.
|
||
* array-set!: Arrays.
|
||
* array-shape: Arrays.
|
||
* array?: Arrays.
|
||
* asctime: Posix Time.
|
||
* ash: Bit-Twiddling.
|
||
* atom?: Non-List functions.
|
||
* batch:call-with-output-script: Batch.
|
||
* batch:command: Batch.
|
||
* batch:comment: Batch.
|
||
* batch:delete-file: Batch.
|
||
* batch:initialize!: Batch.
|
||
* batch:lines->file: Batch.
|
||
* batch:rename-file: Batch.
|
||
* batch:run-script: Batch.
|
||
* batch:try-chopped-command: Batch.
|
||
* batch:try-command: Batch.
|
||
* bit-extract: Bit-Twiddling.
|
||
* bit-field: Bit-Twiddling.
|
||
* bitwise-if: Bit-Twiddling.
|
||
* break: Breakpoints.
|
||
* break-all: Debug.
|
||
* breakf: Breakpoints.
|
||
* breakpoint: Breakpoints.
|
||
* browse: Database Browser.
|
||
* browse-url-netscape: System Interface.
|
||
* butlast: Lists as sequences.
|
||
* butnthcdr: Lists as sequences.
|
||
* byte-ref: Byte.
|
||
* byte-set!: Byte.
|
||
* bytes: Byte.
|
||
* bytes->list: Byte.
|
||
* bytes-length: Byte.
|
||
* call-with-dynamic-binding: Dynamic Data Type.
|
||
* call-with-input-string: String Ports.
|
||
* call-with-output-string: String Ports.
|
||
* call-with-tmpnam: System Interface.
|
||
* call-with-values: Values.
|
||
* capture-syntactic-environment: Syntactic Closures.
|
||
* cart-prod-tables: Relational Database Operations.
|
||
* catalog->html: HTML Tables. |
|
||
* cgi:serve-query: HTTP and CGI.
|
||
* chap:next-string: Chapter Ordering.
|
||
* chap:string<=?: Chapter Ordering.
|
||
* chap:string<?: Chapter Ordering.
|
||
* chap:string>=?: Chapter Ordering.
|
||
* chap:string>?: Chapter Ordering.
|
||
* check-parameters: Parameter lists.
|
||
* close-base: Base Table.
|
||
* close-database: Relational Database Operations.
|
||
* close-table: Table Operations.
|
||
* coerce: Type Coercion. |
|
||
* collection?: Collections.
|
||
* combined-rulesets: Commutative Rings.
|
||
* command->p-specs: HTML. |
|
||
* command:make-editable-table: HTML Tables. |
|
||
* command:modify-table: HTML Tables. |
|
||
* continue: Breakpoints.
|
||
* copy-bit: Bit-Twiddling.
|
||
* copy-bit-field: Bit-Twiddling.
|
||
* copy-list: List construction.
|
||
* copy-random-state: Random Numbers.
|
||
* copy-tree: Tree Operations.
|
||
* create-database <1>: Database Utilities.
|
||
* create-database: Creating and Opening Relational Databases.
|
||
* create-report: Database Reports.
|
||
* create-table: Relational Database Operations.
|
||
* create-view: Relational Database Operations.
|
||
* cring:define-rule: Commutative Rings.
|
||
* ctime: Posix Time.
|
||
* current-directory: System Interface.
|
||
* current-error-port: Input/Output.
|
||
* current-input-port <1>: Byte.
|
||
* current-input-port: Ruleset Definition and Use.
|
||
* current-output-port: Byte.
|
||
* current-time: Time and Date.
|
||
* db->html-directory: HTML Tables. |
|
||
* db->html-files: HTML Tables. |
|
||
* db->netscape: HTML Tables.
|
||
* decode-universal-time: Common-Lisp Time.
|
||
* define-access-operation: Setters.
|
||
* define-operation: Yasos interface.
|
||
* define-predicate: Yasos interface.
|
||
* define-record: Structures.
|
||
* define-syntax: Macro by Example.
|
||
* define-tables: Database Utilities.
|
||
* defmacro: Defmacro.
|
||
* defmacro:eval: Defmacro.
|
||
* defmacro:expand*: Defmacro.
|
||
* defmacro:load: Defmacro.
|
||
* defmacro?: Defmacro.
|
||
* delete <1>: Destructive list operations.
|
||
* delete: Base Table.
|
||
* delete*: Base Table.
|
||
* delete-domain: Database Utilities.
|
||
* delete-file: Input/Output.
|
||
* delete-if: Destructive list operations.
|
||
* delete-if-not: Destructive list operations.
|
||
* delete-table: Relational Database Operations.
|
||
* dequeue!: Queues.
|
||
* determinant: Determinant. |
|
||
* difftime: Time and Date.
|
||
* display-file: Line I/O.
|
||
* do-elts: Collections.
|
||
* do-keys: Collections.
|
||
* domain-checker: Database Utilities.
|
||
* dynamic-ref: Dynamic Data Type.
|
||
* dynamic-set!: Dynamic Data Type.
|
||
* dynamic-wind: Dynamic-Wind.
|
||
* dynamic?: Dynamic Data Type.
|
||
* empty?: Collections.
|
||
* encode-universal-time: Common-Lisp Time.
|
||
* enquque!: Queues.
|
||
* equal?: Byte.
|
||
* eval: Eval.
|
||
* every: Lists as sets.
|
||
* every?: Collections.
|
||
* extended-euclid: Modular Arithmetic.
|
||
* factor: Prime Numbers.
|
||
* fft: Fast Fourier Transform.
|
||
* fft-1: Fast Fourier Transform.
|
||
* file-exists?: Input/Output.
|
||
* filename:match-ci??: Filenames.
|
||
* filename:match??: Filenames.
|
||
* filename:substitute-ci??: Filenames.
|
||
* filename:substitute??: Filenames.
|
||
* fill-empty-parameters: Parameter lists.
|
||
* find-if: Lists as sets.
|
||
* find-ratio: Rationalize.
|
||
* find-ratio-between: Rationalize.
|
||
* find-string-from-port?: String Search.
|
||
* fluid-let: Fluid-Let.
|
||
* for-each-elt: Collections.
|
||
* for-each-key <1>: Collections.
|
||
* for-each-key: Base Table.
|
||
* for-each-row: Table Operations.
|
||
* force-output: Input/Output.
|
||
* form:delimited: HTML. |
|
||
* form:element: HTML. |
|
||
* form:image: HTML. |
|
||
* form:reset: HTML. |
|
||
* form:submit: HTML. |
|
||
* format: Format Interface.
|
||
* fprintf: Standard Formatted Output.
|
||
* fscanf: Standard Formatted Input.
|
||
* ftp-upload: System Interface.
|
||
* generic-write: Generic-Write.
|
||
* gentemp: Defmacro.
|
||
* get: Table Operations.
|
||
* get*: Table Operations.
|
||
* get-decoded-time: Common-Lisp Time.
|
||
* get-method: Object.
|
||
* get-universal-time: Common-Lisp Time.
|
||
* getenv: System Interface.
|
||
* getopt: Getopt.
|
||
* getopt--: Getopt.
|
||
* getopt->arglist: Getopt Parameter lists.
|
||
* getopt->parameter-list: Getopt Parameter lists.
|
||
* glob-pattern?: System Interface.
|
||
* gmktime: Posix Time.
|
||
* gmtime: Posix Time.
|
||
* golden-section-search: Minimizing.
|
||
* gtime: Posix Time.
|
||
* has-duplicates?: Lists as sets.
|
||
* hash: Hashing.
|
||
* hash-associator: Hash Tables.
|
||
* hash-for-each: Hash Tables.
|
||
* hash-inquirer: Hash Tables.
|
||
* hash-map: Hash Tables.
|
||
* hash-remover: Hash Tables.
|
||
* hashq: Hashing.
|
||
* hashv: Hashing.
|
||
* heap-extract-max!: Priority Queues.
|
||
* heap-insert!: Priority Queues.
|
||
* heap-length: Priority Queues.
|
||
* home-vicinity: Vicinity.
|
||
* html:anchor: URI. |
|
||
* html:atval: HTML.
|
||
* html:base: URI. |
|
||
* html:body: HTML.
|
||
* html:buttons: HTML. |
|
||
* html:caption: HTML Tables. |
|
||
* html:checkbox: HTML. |
|
||
* html:comment: HTML.
|
||
* html:editable-row-converter: HTML Tables. |
|
||
* html:form: HTML.
|
||
* html:head: HTML.
|
||
* html:heading: HTML Tables.
|
||
* html:hidden: HTML. |
|
||
* html:href-heading: HTML Tables.
|
||
* html:http-equiv: HTML. |
|
||
* html:isindex: URI. |
|
||
* html:link: URI. |
|
||
* html:linked-row-converter: HTML Tables. |
|
||
* html:meta: HTML. |
|
||
* html:meta-refresh: HTML. |
|
||
* html:plain: HTML.
|
||
* html:pre: HTML.
|
||
* html:select: HTML. |
|
||
* html:table: HTML Tables.
|
||
* html:text: HTML. |
|
||
* html:text-area: HTML. |
|
||
* http:content: HTTP and CGI.
|
||
* http:error-page: HTTP and CGI.
|
||
* http:forwarding-page: HTTP and CGI. |
|
||
* http:header: HTTP and CGI.
|
||
* http:serve-query: HTTP and CGI.
|
||
* identifier=?: Syntactic Closures.
|
||
* identifier?: Syntactic Closures.
|
||
* identity: Legacy.
|
||
* implementation-vicinity: Vicinity.
|
||
* in-vicinity: Vicinity.
|
||
* init-debug: Breakpoints.
|
||
* integer-expt: Bit-Twiddling.
|
||
* integer-length: Bit-Twiddling.
|
||
* integer-sqrt: Root Finding.
|
||
* interaction-environment: Eval.
|
||
* intersection: Lists as sets.
|
||
* jacobi-symbol: Prime Numbers.
|
||
* kill-process!: Multi-Processing.
|
||
* kill-table: Base Table.
|
||
* laguerre:find-polynomial-root: Root Finding.
|
||
* laguerre:find-root: Root Finding.
|
||
* last: Lists as sequences.
|
||
* last-pair: Legacy.
|
||
* library-vicinity: Vicinity.
|
||
* list*: List construction.
|
||
* list->bytes: Byte.
|
||
* list->string: Rev4 Optional Procedures.
|
||
* list->vector: Rev4 Optional Procedures.
|
||
* list-of??: Lists as sets. |
|
||
* list-table-definition: Database Utilities. |
|
||
* list-tail: Rev4 Optional Procedures.
|
||
* load-option: Weight-Balanced Trees.
|
||
* localtime: Posix Time.
|
||
* logand: Bit-Twiddling.
|
||
* logbit?: Bit-Twiddling.
|
||
* logcount: Bit-Twiddling.
|
||
* logior: Bit-Twiddling.
|
||
* lognot: Bit-Twiddling.
|
||
* logtest: Bit-Twiddling.
|
||
* logxor: Bit-Twiddling.
|
||
* macro:eval <1>: Syntax-Case Macros.
|
||
* macro:eval <2>: Syntactic Closures.
|
||
* macro:eval <3>: Macros That Work.
|
||
* macro:eval: R4RS Macros.
|
||
* macro:expand <1>: Syntax-Case Macros.
|
||
* macro:expand <2>: Syntactic Closures.
|
||
* macro:expand <3>: Macros That Work.
|
||
* macro:expand: R4RS Macros.
|
||
* macro:load <1>: Syntax-Case Macros.
|
||
* macro:load <2>: Syntactic Closures.
|
||
* macro:load <3>: Macros That Work.
|
||
* macro:load: R4RS Macros.
|
||
* macroexpand: Defmacro.
|
||
* macroexpand-1: Defmacro.
|
||
* macwork:eval: Macros That Work.
|
||
* macwork:expand: Macros That Work.
|
||
* macwork:load: Macros That Work.
|
||
* make-: Structures.
|
||
* make-array: Arrays.
|
||
* make-base: Base Table.
|
||
* make-bytes: Byte.
|
||
* make-command-server: Database Utilities.
|
||
* make-directory: System Interface.
|
||
* make-dynamic: Dynamic Data Type.
|
||
* make-generic-method: Object.
|
||
* make-generic-predicate: Object.
|
||
* make-getter: Base Table.
|
||
* make-hash-table: Hash Tables.
|
||
* make-heap: Priority Queues.
|
||
* make-key->list: Base Table.
|
||
* make-key-extractor: Base Table.
|
||
* make-keyifier-1: Base Table.
|
||
* make-list: List construction.
|
||
* make-list-keyifier: Base Table.
|
||
* make-method!: Object.
|
||
* make-object: Object.
|
||
* make-parameter-list: Parameter lists.
|
||
* make-port-crc: Cyclic Checksum.
|
||
* make-predicate!: Object.
|
||
* make-promise: Promises.
|
||
* make-putter: Base Table.
|
||
* make-query-alist-command-server: HTTP and CGI. |
|
||
* make-queue: Queues.
|
||
* make-random-state: Random Numbers.
|
||
* make-record-type: Records.
|
||
* make-relational-system: Creating and Opening Relational Databases.
|
||
* make-ruleset: Commutative Rings.
|
||
* make-shared-array: Arrays.
|
||
* make-sierpinski-indexer: Hashing.
|
||
* make-syntactic-closure: Syntactic Closures.
|
||
* make-table: Base Table.
|
||
* make-uri: URI. |
|
||
* make-vicinity: Vicinity.
|
||
* make-wt-tree: Construction of Weight-Balanced Trees.
|
||
* make-wt-tree-type: Construction of Weight-Balanced Trees.
|
||
* map-elts: Collections.
|
||
* map-key: Base Table.
|
||
* map-keys: Collections.
|
||
* member-if: Lists as sets.
|
||
* merge: Sorting.
|
||
* merge!: Sorting.
|
||
* mktime: Posix Time.
|
||
* modular:: Modular Arithmetic.
|
||
* modular:*: Modular Arithmetic.
|
||
* modular:+: Modular Arithmetic.
|
||
* modular:expt: Modular Arithmetic.
|
||
* modular:invert: Modular Arithmetic.
|
||
* modular:invertable?: Modular Arithmetic.
|
||
* modular:negate: Modular Arithmetic.
|
||
* modular:normalize: Modular Arithmetic.
|
||
* modulus->integer: Modular Arithmetic.
|
||
* must-be-first: Batch.
|
||
* must-be-last: Batch.
|
||
* nconc: Destructive list operations.
|
||
* newton:find-root: Root Finding.
|
||
* newtown:find-integer-root: Root Finding.
|
||
* notany: Lists as sets.
|
||
* notevery: Lists as sets.
|
||
* nreverse: Destructive list operations.
|
||
* nthcdr: Lists as sequences.
|
||
* null-directory?: System Interface.
|
||
* null-environment: Eval.
|
||
* object: Yasos interface.
|
||
* object->limited-string: Object-To-String.
|
||
* object->string: Object-To-String.
|
||
* object-with-ancestors: Yasos interface.
|
||
* object?: Object.
|
||
* offset-time: Time and Date.
|
||
* open-base: Base Table.
|
||
* open-database <1>: Database Utilities.
|
||
* open-database: Creating and Opening Relational Databases.
|
||
* open-database!: Database Utilities.
|
||
* open-table <1>: Relational Database Operations.
|
||
* open-table: Base Table.
|
||
* operate-as: Yasos interface.
|
||
* or?: Non-List functions.
|
||
* ordered-for-each-key: Base Table.
|
||
* os->batch-dialect: Batch.
|
||
* output-port-height: Input/Output.
|
||
* output-port-width: Input/Output.
|
||
* parameter-list->arglist: Parameter lists.
|
||
* parameter-list-expand: Parameter lists.
|
||
* parameter-list-ref: Parameter lists.
|
||
* parse-ftp-address: System Interface.
|
||
* path->uri: System Interface. |
|
||
* plot!: Plotting.
|
||
* plot-function!: Plotting.
|
||
* pnm:array-write: Portable Image Files.
|
||
* pnm:image-file->array: Portable Image Files.
|
||
* pnm:type-dimensions: Portable Image Files.
|
||
* position: Lists as sequences.
|
||
* pprint-file: Pretty-Print.
|
||
* pprint-filter-file: Pretty-Print.
|
||
* prec:commentfix: Grammar Rule Definition.
|
||
* prec:define-grammar: Ruleset Definition and Use.
|
||
* prec:delim: Grammar Rule Definition.
|
||
* prec:infix: Grammar Rule Definition.
|
||
* prec:inmatchfix: Grammar Rule Definition.
|
||
* prec:make-led: Nud and Led Definition.
|
||
* prec:make-nud: Nud and Led Definition.
|
||
* prec:matchfix: Grammar Rule Definition.
|
||
* prec:nary: Grammar Rule Definition.
|
||
* prec:nofix: Grammar Rule Definition.
|
||
* prec:parse: Ruleset Definition and Use.
|
||
* prec:postfix: Grammar Rule Definition.
|
||
* prec:prefix: Grammar Rule Definition.
|
||
* prec:prestfix: Grammar Rule Definition.
|
||
* predicate->asso: Association Lists.
|
||
* predicate->hash: Hash Tables.
|
||
* predicate->hash-asso: Hash Tables.
|
||
* present?: Base Table.
|
||
* pretty-print: Pretty-Print.
|
||
* pretty-print->string: Pretty-Print. |
|
||
* prime?: Prime Numbers.
|
||
* primes<: Prime Numbers.
|
||
* primes>: Prime Numbers.
|
||
* print: Yasos interface.
|
||
* print-call-stack: Trace.
|
||
* printf: Standard Formatted Output.
|
||
* process:schedule!: Multi-Processing.
|
||
* program-vicinity: Vicinity.
|
||
* project-table: Relational Database Operations.
|
||
* provide <1>: Require.
|
||
* provide: Feature.
|
||
* provided? <1>: Require.
|
||
* provided?: Feature.
|
||
* qp: Quick Print.
|
||
* qpn: Quick Print.
|
||
* qpr: Quick Print.
|
||
* queue-empty?: Queues.
|
||
* queue-front: Queues.
|
||
* queue-pop!: Queues.
|
||
* queue-push!: Queues.
|
||
* queue-rear: Queues.
|
||
* queue?: Queues.
|
||
* random: Random Numbers.
|
||
* random:exp: Random Numbers.
|
||
* random:hollow-sphere!: Random Numbers.
|
||
* random:normal: Random Numbers.
|
||
* random:normal-vector!: Random Numbers.
|
||
* random:solid-sphere!: Random Numbers.
|
||
* random:uniform: Random Numbers.
|
||
* rationalize: Rationalize.
|
||
* read-byte: Byte.
|
||
* read-command: Command Line.
|
||
* read-line: Line I/O.
|
||
* read-line!: Line I/O.
|
||
* read-options-file: Command Line.
|
||
* record-accessor: Records.
|
||
* record-constructor: Records.
|
||
* record-modifier: Records.
|
||
* record-predicate: Records.
|
||
* reduce <1>: Lists as sequences.
|
||
* reduce: Collections.
|
||
* reduce-init: Lists as sequences.
|
||
* remove: Lists as sets.
|
||
* remove-duplicates: Lists as sets.
|
||
* remove-if: Lists as sets.
|
||
* remove-if-not: Lists as sets.
|
||
* remove-parameter: Parameter lists.
|
||
* remove-setter-for: Setters.
|
||
* repl:quit: Repl.
|
||
* repl:top-level: Repl.
|
||
* replace-suffix: Filenames.
|
||
* require <1>: Require.
|
||
* require <2>: Catalog Compilation.
|
||
* require: Requesting Features.
|
||
* require:feature->path <1>: Require.
|
||
* require:feature->path: Requesting Features.
|
||
* restrict-table: Relational Database Operations.
|
||
* row:delete: Table Operations.
|
||
* row:delete*: Table Operations.
|
||
* row:insert: Table Operations.
|
||
* row:insert*: Table Operations.
|
||
* row:remove: Table Operations.
|
||
* row:remove*: Table Operations.
|
||
* row:retrieve: Table Operations.
|
||
* row:retrieve*: Table Operations.
|
||
* row:update: Table Operations.
|
||
* row:update*: Table Operations.
|
||
* scanf: Standard Formatted Input.
|
||
* scanf-read-list: Standard Formatted Input.
|
||
* scheme-report-environment: Eval.
|
||
* schmooz: Schmooz.
|
||
* secant:find-bracketed-root: Root Finding.
|
||
* secant:find-root: Root Finding.
|
||
* seed->random-state: Random Numbers.
|
||
* set: Setters.
|
||
* set-: Structures.
|
||
* set-difference: Lists as sets.
|
||
* Setter: Collections.
|
||
* setter: Setters.
|
||
* si:conversion-factor: Metric Units. |
|
||
* singleton-wt-tree: Construction of Weight-Balanced Trees.
|
||
* size <1>: Collections.
|
||
* size: Yasos interface.
|
||
* slib:error: System.
|
||
* slib:eval: System.
|
||
* slib:eval-load: System.
|
||
* slib:exit: System.
|
||
* slib:load: System.
|
||
* slib:load-compiled: System.
|
||
* slib:load-source: System.
|
||
* slib:report: Configuration.
|
||
* slib:report-version: Configuration.
|
||
* slib:warn: System.
|
||
* software-type: Configuration.
|
||
* some: Lists as sets.
|
||
* sort: Sorting.
|
||
* sort!: Sorting.
|
||
* sorted?: Sorting.
|
||
* soundex: Hashing.
|
||
* sprintf: Standard Formatted Output.
|
||
* sscanf: Standard Formatted Input.
|
||
* stack: Trace.
|
||
* stack-all: Debug.
|
||
* string->list: Rev4 Optional Procedures.
|
||
* string-capitalize: String-Case.
|
||
* string-captialize!: String-Case.
|
||
* string-ci->symbol: String-Case.
|
||
* string-copy: Rev4 Optional Procedures.
|
||
* string-downcase: String-Case.
|
||
* string-downcase!: String-Case.
|
||
* string-fill!: Rev4 Optional Procedures.
|
||
* string-index: String Search.
|
||
* string-index-ci: String Search.
|
||
* string-join: Batch.
|
||
* string-null?: Rev2 Procedures.
|
||
* string-reverse-index: String Search.
|
||
* string-reverse-index-ci: String Search.
|
||
* string-subst: String Search.
|
||
* string-upcase: String-Case.
|
||
* string-upcase!: String-Case.
|
||
* sub-vicinity: Vicinity.
|
||
* subst: Tree Operations.
|
||
* substq: Tree Operations.
|
||
* substring-ci?: String Search.
|
||
* substring-fill!: Rev2 Procedures.
|
||
* substring-move-left!: Rev2 Procedures.
|
||
* substring-move-right!: Rev2 Procedures.
|
||
* substring?: String Search.
|
||
* substv: Tree Operations.
|
||
* supported-key-type?: Base Table.
|
||
* supported-type?: Base Table.
|
||
* symbol-append: String-Case. |
|
||
* symmetric:modulus: Modular Arithmetic.
|
||
* sync-base: Base Table.
|
||
* sync-database: Relational Database Operations. |
|
||
* syncase:eval: Syntax-Case Macros.
|
||
* syncase:expand: Syntax-Case Macros.
|
||
* syncase:load: Syntax-Case Macros.
|
||
* synclo:eval: Syntactic Closures.
|
||
* synclo:expand: Syntactic Closures.
|
||
* synclo:load: Syntactic Closures.
|
||
* syntax-rules: Macro by Example.
|
||
* system: System Interface.
|
||
* table->linked-html: HTML Tables. |
|
||
* table->linked-page: HTML Tables. |
|
||
* table-exists?: Relational Database Operations.
|
||
* table-name->filename: HTML Tables.
|
||
* TAG: Structures.
|
||
* tek40:draw: Tektronix Graphics Support.
|
||
* tek40:graphics: Tektronix Graphics Support.
|
||
* tek40:init: Tektronix Graphics Support.
|
||
* tek40:linetype: Tektronix Graphics Support.
|
||
* tek40:move: Tektronix Graphics Support.
|
||
* tek40:put-text: Tektronix Graphics Support.
|
||
* tek40:reset: Tektronix Graphics Support.
|
||
* tek40:text: Tektronix Graphics Support.
|
||
* tek41:draw: Tektronix Graphics Support.
|
||
* tek41:encode-int: Tektronix Graphics Support.
|
||
* tek41:encode-x-y: Tektronix Graphics Support.
|
||
* tek41:graphics: Tektronix Graphics Support.
|
||
* tek41:init: Tektronix Graphics Support.
|
||
* tek41:move: Tektronix Graphics Support.
|
||
* tek41:point: Tektronix Graphics Support.
|
||
* tek41:reset: Tektronix Graphics Support.
|
||
* time-zone: Time Zone.
|
||
* tmpnam: Input/Output.
|
||
* tok:char-group: Token definition.
|
||
* topological-sort: Topological Sort.
|
||
* trace: Trace.
|
||
* trace-all: Debug.
|
||
* tracef: Trace.
|
||
* track: Trace.
|
||
* track-all: Debug.
|
||
* transcript-off: Transcripts.
|
||
* transcript-on: Transcripts.
|
||
* transformer: Syntactic Closures.
|
||
* truncate-up-to: Batch.
|
||
* tsort: Topological Sort.
|
||
* two-arg:-: Multi-argument / and -.
|
||
* two-arg:/: Multi-argument / and -.
|
||
* two-arg:apply: Multi-argument Apply.
|
||
* type-of: Type Coercion. |
|
||
* tz:params: Time Zone.
|
||
* tzset: Time Zone.
|
||
* unbreak: Breakpoints.
|
||
* unbreakf: Breakpoints.
|
||
* union: Lists as sets.
|
||
* unmake-method!: Object.
|
||
* unstack: Trace.
|
||
* untrace: Trace.
|
||
* untracef: Trace.
|
||
* untrack: Trace.
|
||
* uri->tree: URI. |
|
||
* uric:decode: URI. |
|
||
* uric:encode: URI. |
|
||
* user-email-address: System Interface.
|
||
* user-vicinity: Vicinity.
|
||
* values: Values.
|
||
* variant-case: Structures.
|
||
* vector->list: Rev4 Optional Procedures.
|
||
* vector-fill!: Rev4 Optional Procedures.
|
||
* with-input-from-file: With-File.
|
||
* with-output-to-file: With-File.
|
||
* write-base: Base Table.
|
||
* write-byte: Byte.
|
||
* write-database: Relational Database Operations.
|
||
* write-line: Line I/O.
|
||
* wt-tree/add: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/add!: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/delete: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/delete!: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/delete-min: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/delete-min!: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/difference: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/empty?: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/fold: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/for-each: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/index: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/index-datum: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/index-pair: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/intersection: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/lookup: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/member?: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/min: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/min-datum: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/min-pair: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/rank: Indexing Operations on Weight-Balanced Trees.
|
||
* wt-tree/set-equal?: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/size: Basic Operations on Weight-Balanced Trees.
|
||
* wt-tree/split<: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/split>: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/subset?: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree/union: Advanced Operations on Weight-Balanced Trees.
|
||
* wt-tree?: Basic Operations on Weight-Balanced Trees.
|
||
|
||
Variable Index
|
||
**************
|
||
|
||
This is an alphabetical list of all the global variables in SLIB.
|
||
|
||
* Menu:
|
||
|
||
* *catalog*: Require.
|
||
* *features*: Require.
|
||
* *http:byline*: HTTP and CGI.
|
||
* *modules*: Require.
|
||
* *optarg*: Getopt.
|
||
* *optind*: Getopt.
|
||
* *qp-width*: Quick Print.
|
||
* *random-state*: Random Numbers.
|
||
* *ruleset*: Commutative Rings.
|
||
* *syn-defs*: Ruleset Definition and Use.
|
||
* *syn-ignore-whitespace*: Ruleset Definition and Use.
|
||
* *timezone*: Time Zone.
|
||
* batch:platform: Batch.
|
||
* catalog-id: Base Table.
|
||
* char-code-limit: Configuration.
|
||
* charplot:height: Plotting.
|
||
* charplot:width: Plotting.
|
||
* column-domains: Table Operations.
|
||
* column-foreigns: Table Operations.
|
||
* column-names: Table Operations.
|
||
* column-types: Table Operations.
|
||
* daylight?: Time Zone.
|
||
* debug:max-count: Trace.
|
||
* distribute*: Commutative Rings.
|
||
* distribute/: Commutative Rings.
|
||
* most-positive-fixnum: Configuration.
|
||
* nil: Legacy.
|
||
* number-wt-type: Construction of Weight-Balanced Trees.
|
||
* primary-limit: Table Operations.
|
||
* prime:prngs: Prime Numbers.
|
||
* prime:trials: Prime Numbers.
|
||
* slib:form-feed: Configuration.
|
||
* slib:tab: Configuration.
|
||
* stderr: Standard Formatted I/O.
|
||
* stdin: Standard Formatted I/O.
|
||
* stdout: Standard Formatted I/O.
|
||
* string-wt-type: Construction of Weight-Balanced Trees.
|
||
* t: Legacy.
|
||
* tok:decimal-digits: Token definition.
|
||
* tok:lower-case: Token definition.
|
||
* tok:upper-case: Token definition.
|
||
* tok:whitespaces: Token definition.
|
||
* tzname: Time Zone.
|
||
|
||
Concept and Feature Index
|
||
*************************
|
||
|
||
* Menu:
|
||
|
||
* alist: Association Lists.
|
||
* alist-table <1>: Creating and Opening Relational Databases.
|
||
* alist-table: Base Table.
|
||
* ange-ftp: System Interface.
|
||
* array: Arrays.
|
||
* array-for-each: Array Mapping.
|
||
* attribute-value: HTML.
|
||
* balanced binary trees: Weight-Balanced Trees.
|
||
* base: URI. |
|
||
* batch: Batch.
|
||
* binary trees: Weight-Balanced Trees.
|
||
* binary trees, as discrete maps: Weight-Balanced Trees.
|
||
* binary trees, as sets: Weight-Balanced Trees.
|
||
* break: Breakpoints.
|
||
* byte: Byte.
|
||
* calendar time <1>: Posix Time.
|
||
* calendar time: Time and Date.
|
||
* Calendar-Time: Posix Time.
|
||
* caltime: Posix Time.
|
||
* careful: Commutative Rings.
|
||
* catalog: Requesting Features.
|
||
* Catalog File: Library Catalogs.
|
||
* chapter-order: Chapter Ordering.
|
||
* charplot: Plotting.
|
||
* coerce: Type Coercion. |
|
||
* collect: Collections.
|
||
* command line: Command Line.
|
||
* commentfix: Precedence Parsing Overview.
|
||
* common-list-functions <1>: Common List Functions.
|
||
* common-list-functions: Collections.
|
||
* commutative-ring: Commutative Rings.
|
||
* Coordinated Universal Time: Posix Time.
|
||
* database-utilities <1>: Database Utilities.
|
||
* database-utilities: Batch.
|
||
* debug <1>: Breakpoints.
|
||
* debug: Debug.
|
||
* defmacroexpand <1>: Pretty-Print.
|
||
* defmacroexpand: Defmacro.
|
||
* delim: Precedence Parsing Overview.
|
||
* discrete maps, using binary trees: Weight-Balanced Trees.
|
||
* DrScheme: Installation.
|
||
* dynamic: Dynamic Data Type.
|
||
* dynamic-wind: Dynamic-Wind.
|
||
* escaped: URI. |
|
||
* Euclidean Domain: Commutative Rings.
|
||
* factor: Prime Numbers.
|
||
* feature <1>: About this manual.
|
||
* feature <2>: Requesting Features.
|
||
* feature: Feature.
|
||
* fft: Fast Fourier Transform.
|
||
* fluid-let <1>: Database Utilities.
|
||
* fluid-let: Fluid-Let.
|
||
* form: HTML.
|
||
* format: Format.
|
||
* generic-write: Generic-Write.
|
||
* getit: System Interface.
|
||
* getopt <1>: Database Utilities.
|
||
* getopt: Getopt.
|
||
* glob <1>: Batch.
|
||
* glob: Filenames.
|
||
* hash: Hashing.
|
||
* hash-table: Hash Tables.
|
||
* HOME <1>: Vicinity.
|
||
* HOME: Library Catalogs.
|
||
* homecat: Catalog Compilation.
|
||
* implcat: Catalog Compilation.
|
||
* infix: Precedence Parsing Overview.
|
||
* inmatchfix: Precedence Parsing Overview.
|
||
* Left Denotation, led: Nud and Led Definition.
|
||
* line-i: Line I/O.
|
||
* logical: Bit-Twiddling.
|
||
* macro <1>: Repl.
|
||
* macro: R4RS Macros.
|
||
* macro-by-example: Macro by Example.
|
||
* macros-that-work: Macros That Work.
|
||
* make-crc: Cyclic Checksum.
|
||
* match: Base Table.
|
||
* match-keys <1>: Table Operations.
|
||
* match-keys: Base Table.
|
||
* matchfix: Precedence Parsing Overview.
|
||
* metric-units: Metric Units. |
|
||
* minimize: Minimizing.
|
||
* minimum field width (printf): Standard Formatted Output.
|
||
* mkimpcat.scm: Catalog Compilation.
|
||
* mklibcat.scm: Catalog Compilation.
|
||
* modular: Modular Arithmetic.
|
||
* multiarg-apply: Multi-argument Apply.
|
||
* mutliarg: Multi-argument / and -.
|
||
* MzScheme: Installation.
|
||
* nary: Precedence Parsing Overview.
|
||
* net-clients: System Interface.
|
||
* new-catalog: Catalog Compilation. |
|
||
* nofix: Precedence Parsing Overview.
|
||
* null: HTML Tables. |
|
||
* Null Denotation, nud: Nud and Led Definition.
|
||
* object: Object.
|
||
* object->string: Object-To-String.
|
||
* oop: Yasos.
|
||
* option, run-time-loadable: Weight-Balanced Trees.
|
||
* options file: Command Line.
|
||
* parameters <1>: Database Utilities.
|
||
* parameters <2>: Batch.
|
||
* parameters: Parameter lists.
|
||
* parse: Precedence Parsing.
|
||
* plain-text: HTML.
|
||
* PLT Scheme: Installation.
|
||
* posix-time: Posix Time.
|
||
* postfix: Precedence Parsing Overview.
|
||
* pprint-file: Pretty-Print.
|
||
* PRE: HTML.
|
||
* precedence: Precedence Parsing.
|
||
* precision (printf): Standard Formatted Output.
|
||
* prefix: Precedence Parsing Overview.
|
||
* prestfix: Precedence Parsing Overview.
|
||
* pretty-print: Pretty-Print.
|
||
* primes: Prime Numbers.
|
||
* printf: Standard Formatted Output.
|
||
* priority-queue: Priority Queues.
|
||
* PRNG: Random Numbers.
|
||
* process: Multi-Processing.
|
||
* promise: Promises.
|
||
* qp <1>: Quick Print.
|
||
* qp: Getopt.
|
||
* query-string: HTTP and CGI.
|
||
* queue: Queues.
|
||
* random: Random Numbers.
|
||
* rationalize: Rationalize.
|
||
* read-command: Command Line.
|
||
* record: Records.
|
||
* relational-database: Relational Database.
|
||
* repl <1>: Repl.
|
||
* repl: Syntax-Case Macros.
|
||
* reset: HTML.
|
||
* rev2-procedures: Rev2 Procedures.
|
||
* rev3-report: Coding Guidelines.
|
||
* rev4-optional-procedures: Rev4 Optional Procedures.
|
||
* ring, commutative: Commutative Rings.
|
||
* RNG: Random Numbers.
|
||
* root: Root Finding.
|
||
* run-time-loadable option: Weight-Balanced Trees.
|
||
* scanf: Standard Formatted Input.
|
||
* Scheme48: Installation.
|
||
* schmooz: Schmooz.
|
||
* SCM: Installation.
|
||
* Server-based Naming Authority: URI. |
|
||
* session: Feature.
|
||
* sets, using binary trees: Weight-Balanced Trees.
|
||
* sierpinski: Hashing.
|
||
* sitecat: Catalog Compilation.
|
||
* slibcat: Catalog Compilation.
|
||
* sort: Sorting.
|
||
* soundex: Hashing.
|
||
* stdio: Standard Formatted I/O.
|
||
* string-case: String-Case.
|
||
* string-port: String Ports.
|
||
* string-search: String Search.
|
||
* struct: Structures.
|
||
* syntactic-closures: Syntactic Closures.
|
||
* syntax-case: Syntax-Case Macros.
|
||
* time: Time and Date.
|
||
* time-zone: Time Zone.
|
||
* topological-sort: Topological Sort.
|
||
* trace: Trace.
|
||
* transcript: Transcripts.
|
||
* tree: Tree Operations.
|
||
* trees, balanced binary: Weight-Balanced Trees.
|
||
* tsort: Topological Sort.
|
||
* TZ-string: Time Zone.
|
||
* Uniform Resource Identifiers: URI. |
|
||
* Uniform Resource Locator: System Interface.
|
||
* Unique Factorization: Commutative Rings.
|
||
* unsafe: URI. |
|
||
* URI: HTTP and CGI.
|
||
* usercat: Catalog Compilation.
|
||
* UTC: Posix Time.
|
||
* values: Values.
|
||
* VSCM: Installation.
|
||
* weight-balanced binary trees: Weight-Balanced Trees.
|
||
* wild-card: Base Table.
|
||
* with-file: With-File.
|
||
* wt-tree: Weight-Balanced Trees.
|
||
* yasos: Yasos.
|
||
|
||
|
||
|
||
Tag Table:
|
||
Node: Top1026
|
||
Node: The Library System1740
|
||
Node: Feature2054
|
||
Node: Requesting Features3004
|
||
Node: Library Catalogs4363
|
||
Node: Catalog Compilation6815
|
||
Node: Built-in Support9624
|
||
Node: Require10255
|
||
Node: Vicinity12747
|
||
Node: Configuration15714
|
||
Node: Input/Output18655
|
||
Node: Legacy20254
|
||
Node: System21096
|
||
Node: About this manual23588
|
||
Node: Scheme Syntax Extension Packages24145
|
||
Node: Defmacro24830
|
||
Node: R4RS Macros26781
|
||
Node: Macro by Example28036
|
||
Node: Macros That Work30913
|
||
Node: Syntactic Closures36971
|
||
Node: Syntax-Case Macros54405
|
||
Node: Fluid-Let58531
|
||
Node: Yasos59472
|
||
Node: Yasos terms60265
|
||
Node: Yasos interface61289
|
||
Node: Setters63364
|
||
Node: Yasos examples66005
|
||
Node: Textual Conversion Packages68999
|
||
Node: Precedence Parsing69697
|
||
Node: Precedence Parsing Overview70360
|
||
Ref: Precedence Parsing Overview-Footnote-172358
|
||
Node: Ruleset Definition and Use72561
|
||
Node: Token definition74942
|
||
Node: Nud and Led Definition77211
|
||
Node: Grammar Rule Definition79660
|
||
Node: Format87234
|
||
Node: Format Interface87482
|
||
Node: Format Specification89219
|
||
Node: Standard Formatted I/O99349
|
||
Node: Standard Formatted Output99915
|
||
Node: Standard Formatted Input109182
|
||
Node: Programs and Arguments115842
|
||
Node: Getopt116342
|
||
Node: Command Line122184
|
||
Node: Parameter lists125373
|
||
Node: Getopt Parameter lists129358
|
||
Node: Filenames133527
|
||
Node: Batch136757
|
||
Node: HTML144550
|
||
Node: HTML Tables155838
|
||
Node: HTTP and CGI166135
|
||
Node: URI171452
|
||
Node: Printing Scheme177162
|
||
Node: Generic-Write177550
|
||
Node: Object-To-String178953
|
||
Node: Pretty-Print179357
|
||
Node: Time and Date184343
|
||
Node: Time Zone185370
|
||
Node: Posix Time189931
|
||
Node: Common-Lisp Time192067
|
||
Node: Vector Graphics193646
|
||
Node: Tektronix Graphics Support193835
|
||
Node: Schmooz195209
|
||
Node: Mathematical Packages199435
|
||
Node: Bit-Twiddling200069
|
||
Node: Modular Arithmetic204660
|
||
Node: Prime Numbers206794
|
||
Node: Random Numbers208477
|
||
Node: Fast Fourier Transform213113
|
||
Node: Cyclic Checksum214031
|
||
Node: Plotting216292
|
||
Node: Root Finding219151
|
||
Node: Minimizing223138
|
||
Ref: Minimizing-Footnote-1208597
|
||
Node: Commutative Rings225178
|
||
Node: Determinant236562
|
||
Node: Database Packages237120
|
||
Node: Base Table237384
|
||
Node: Relational Database247798
|
||
Node: Motivations248582
|
||
Node: Creating and Opening Relational Databases253629
|
||
Node: Relational Database Operations256061
|
||
Node: Table Operations259258
|
||
Node: Catalog Representation267136
|
||
Node: Unresolved Issues270034
|
||
Node: Database Utilities272985
|
||
Node: Database Reports289598
|
||
Node: Database Browser292352
|
||
Node: Weight-Balanced Trees293413
|
||
Node: Construction of Weight-Balanced Trees297284
|
||
Node: Basic Operations on Weight-Balanced Trees300734
|
||
Node: Advanced Operations on Weight-Balanced Trees303699
|
||
Node: Indexing Operations on Weight-Balanced Trees309721
|
||
Node: Other Packages313635
|
||
Node: Data Structures314034
|
||
Node: Arrays314790
|
||
Node: Array Mapping317744
|
||
Node: Association Lists319661
|
||
Node: Byte321912
|
||
Node: Portable Image Files324152
|
||
Node: Collections325699
|
||
Node: Dynamic Data Type331817
|
||
Node: Hash Tables333078
|
||
Node: Hashing335195
|
||
Node: Object339989
|
||
Node: Priority Queues348225
|
||
Node: Queues349068
|
||
Node: Records350194
|
||
Node: Structures353705
|
||
Node: Procedures355005
|
||
Node: Common List Functions355852
|
||
Node: List construction356276
|
||
Node: Lists as sets357939
|
||
Node: Lists as sequences365060
|
||
Node: Destructive list operations370366
|
||
Node: Non-List functions373029
|
||
Node: Tree Operations374174
|
||
Node: Type Coercion375796
|
||
Node: Chapter Ordering377022
|
||
Node: Sorting378719
|
||
Node: Topological Sort384496
|
||
Node: String-Case386183
|
||
Node: String Ports387284
|
||
Node: String Search388048
|
||
Node: Line I/O390415
|
||
Node: Multi-Processing392065
|
||
Node: Metric Units393248
|
||
Node: Standards Support408689
|
||
Node: With-File409423
|
||
Node: Transcripts409699
|
||
Node: Rev2 Procedures410020
|
||
Node: Rev4 Optional Procedures411727
|
||
Node: Multi-argument / and -412297
|
||
Node: Multi-argument Apply412948
|
||
Node: Rationalize413434
|
||
Node: Promises414876
|
||
Node: Dynamic-Wind415293
|
||
Node: Eval416547
|
||
Node: Values419884
|
||
Node: Session Support420671
|
||
Node: Repl421139
|
||
Node: Quick Print422422
|
||
Node: Debug423535
|
||
Node: Breakpoints424421
|
||
Node: Trace426444
|
||
Node: System Interface429555
|
||
Node: Extra-SLIB Packages433443
|
||
Node: About SLIB435743
|
||
Node: Installation436407
|
||
Node: Porting439635
|
||
Ref: Porting-Footnote-1413781
|
||
Node: Coding Guidelines441153
|
||
Node: Copyrights443234
|
||
Node: Index446519
|
||
|
||
End Tag Table
|