Library utilities
=================

Scheme48 provides various miscellaneous library utilities for common general-purpose tasks.

Destructuring
-------------

The destructuring structure exports a form for destructuring S-expressions.

 -- syntax: destructure ((pattern value) ...) body
     For each (PATTERN VALUE) pair, binds every name in PATTERN to the corresponding location in the S-expression VALUE.  For example,

          (destructure (((x . y) (cons 5 3))
                        ((#(a b) c) '(#((1 2) 3) (4 5))))
            BODY) lisp

          binds X to 5, Y to 3, A to
          (1 2), B to 3, and C to (4 5), in
          BODY.

Pretty-printing
---------------

The pp structure exports a simple pretty-printer.

 -- procedure: p object [port] returns unspecified
 -- procedure: pretty-print object port position returns unspecified
     P is a convenient alias for pretty-print; it passes 0 for POSITION and the value of (current-output-port) if PORT is not passed.  Pretty-print pretty-prints OBJECT to PORT, using a left margin of POSITION.  For example:

          (p '(define (fact n)
                (let loop ((p 1) (c 1))
                  (if (> c n) p (loop (* p c) (+ c 1))))))
              -| (define (fact n)
              -|   (let loop ((p 1) (c 1))
              -|     (if (> c n)
              -|         p
              -|         (loop (* p c) (+ c 1))))) lisp

The pretty-printer is somewhat extensible as well:

 -- procedure: define-indentation name count returns unspecified
     Sets the number of subforms to be indented past NAME in pretty-printed output to be COUNT.  For example:

          (define-indentation 'frobozz 3)
          (p '(frobozz (foo bar baz quux zot) (zot quux baz bar foo)
                       (mumble frotz gargle eek) (froomble zargle hrumph)))
              -| (frobozz (foo bar baz quux zot)
              -|          (zot quux baz bar foo)
              -|          (mumble frotz gargle eek)
              -|   (froomble zargle hrumph)) lisp

Strongly connected graph components
-----------------------------------

The strong structure exports a routine for finding a list of the strongly connected components in a graph.

 -- procedure: strongly-connected-components vertices to slot set-slot! returns sorted-strong-vertices
     Returns the components of a graph containing vertices from the list VERTICES that are strongly connected, in a reversed topologically sorted list.  TO should be a procedure of one argument, a vertex, that returns a list of all vertices that have an edge to its argument. SLOT & SET-SLOT! should be procedures of one & two arguments, respectively, that access & modify arbitrary slots used by the algorithm.  The slot for every vertex should initially be #f before calling strongly-connected-components, and the slots are reverted to #f before strongly-connected-components returns.

Nondeterminism
--------------

The nondeterminism structure provides a simple nondeterministic ambivalence operator, like McCarthy's AMB, and a couple utilities atop it, built with Scheme's call-with-current-continuation.

 -- procedure: with-nondeterminism thunk returns values
     Initializes the nondeterminism system and calls THUNK; this returns the values THUNK returns after then tearing down what was set up.

 -- syntax: either option ... returns value
 -- syntax: one-value exp returns value
 -- syntax: all-values exp returns list
     Either evaluates to the value of any one of the options.  It is equivalent to McCarthy's AMB.  It may return any number of times. One-value returns the only value that EXP could produce; it will return only once, although it may actually return any number of values (if EXP contains a call to values). All-values returns a list of all of the single values, not multiple values, that EXP could nondeterministically evaluate to.

 -- procedure: fail returns does not return
     Signals a nondeterministic failure.  This is invalid outside of a with-nondeterminism-protected dynamic extent.

Miscellaneous utilities
-----------------------

The big-util structure exports a variety of miscellaneous utilities.

 -- procedure: concatenate-symbol elt ... returns symbol
     Returns a symbol containing the contents of the sequence ELT ....  Each ELT may be another symbol, a string, or a number. Numbers are converted to strings in base ten.

 -- procedure: error format-string argument ... returns values (may not return)
 -- procedure: breakpoint format-string argument ... returns values (may not return)
     Error signals an error whose message is formatted by Common-Lisp-style formatting, format with the given formatting template string and arguments.  Breakpoint signals a breakpoint with a message similarly constructed and causes the command processor to push a new Command levels,command level.

 -- procedure: atom? x returns boolean
     Returns true if X is not a pair or false if it is.

 -- procedure: neq? x y returns boolean
 -- procedure: n= x y returns boolean
     Negations of the eq? and = predicates.

 -- procedure: identity value returns value
 -- procedure: no-op value returns value
     These simply return their arguments.  The difference between them is that no-op is guaranteed not to be integrated by the compiler, whereas identity may be.

 -- procedure: null-list? object returns boolean
     Returns #t if OBJECT is the null list, returns #f if OBJECT is a pair, or signals an error if OBJECT is neither the null list nor a pair.

 -- procedure: reverse! list returns reversed-list
     Returns a list containing the reverse elements of LIST.  Note that the original LIST is not reversed; it becomes garbage.  Reverse! simply re-uses its structure.

 -- procedure: memq? object list returns boolean
     Returns #t if OBJECT is a member of LIST, as determined by eq?; or #f if not.

 -- procedure: first predicate list returns elt or #f
 -- procedure: any predicate list returns elt or #f
     First returns the first element of LIST that satisfies PREDICATE, or #f if no element does.  Any returns an element of LIST that satisfies PREDICATE.  Note that any may choose any element of the list, whereas first explicitly returns the first element that satisfies PREDICATE.

 -- procedure: any? predicate list returns boolean
 -- procedure: every? predicate list returns boolean
     Any? returns #t if any element of LIST satisfies PREDICATE, or #f if none do.  Every? returns #t if every element of LIST satisfies PREDICATE, or #f if there exists an element that does not.

 -- procedure: filter predicate list returns filtered-list
 -- procedure: filter! predicate list returns filtered-list
     These return a list of all elements in LIST that satisfy PREDICATE.  Filter is not allowed to modify LIST's structure; filter! may, however.

 -- procedure: filter-map proc list returns list
     This is a combination of filter and map.  For each element E in LIST: if (PROC E) returns a true value, that true value is collected in the output list. Filter-map does not modify LIST's structure.

 -- procedure: remove-duplicates list returns uniquified-list
     Returns a unique list of all elements in LIST; that is, if there were any duplicates of any element E in LIST, only a single E will occur in the returned list.  Remove-duplicates does not modify LIST's structure.

 -- procedure: partition-list predicate list returns [satisfied unsatisfied]
 -- procedure: partition-list! predicate list returns [satisfied unsatisfied]
     These return two values: a list of all elements in LIST that do satisfy PREDICATE and a list of all elements that do not. Partition-list is not allowed to modify LIST's structure; partition-list! is.

 -- procedure: delq object list returns list
 -- procedure: delq! object list returns list
     These return a list containing all elements of LIST except for OBJECT.  Delq is not allowed to modify LIST's structure; delq! is.

 -- procedure: delete predicate list returns list
     Returns a list of all elements in LIST that do not satisfy PREDICATE.  Note that, despite the lack of exclamation mark in the name, this may modify LIST's structure.

 -- procedure: string->immutable-string string returns immutable-string
     Returns an immutable string with STRING's contents.  If STRING is already immutable, it is returned; otherwise, an immutable copy is returned.

Multiple value binding
----------------------

The receiving structure exports the receive macro, a convenient syntax atop R5RS's call-with-values.

 -- syntax: receive formals producer body
     Binds the variables in the lambda parameter list FORMALS to the return values of PRODUCER in BODY.

          (receive FORMALS
                   PRODUCER
            BODY)
              ==
          (call-with-values
              (lambda () PRODUCER)
            (lambda FORMALS BODY)) lisp

For sequences of multiple value bindings, the mvlet structure exports two convenient macros.

 -- syntax: mvlet*
 -- syntax: mvlet
     Mvlet* is a multiple-value version of let or a linearly nested version of receive:

          (mvlet* ((FORMALS0 PRODUCER0)
                   (FORMALS1 PRODUCER1)
                   ...)
            BODY)
              ==
          (call-with-values
              (lambda () PRODUCER0)
            (lambda FORMALS0
              (call-with-values
                  (lambda () PRODUCER1)
                (lambda FORMALS1
                  ...BODY...)))) lisp

          Mvlet is similar, but each PRODUCER is evaluated in an
          environment where none of the variables in any of the FORMALS is
          bound, and the order in which each producer expression is evaluated is
          unspecified.

Object dumper
-------------

Scheme48 has a rudimentary object dumper and retriever in the structure dump/restore.  It is not a `real' object dumper in the sense that it will not handle cycles in object graphs correctly; it simply performs a recursive descent and will diverge if it reaches a cycle or stop after a recursive depth parameter.

The types of objects that the dumper supports are: several miscellaneous constants ((), #t, #f, & the unspecific token), pairs, vectors, symbols, numbers, strings, characters, and byte vectors.

 -- procedure: dump object char-writer depth returns unspecified
     Dumps OBJECT by repeatedly calling CHAR-WRITER, which must be a procedure that accepts exactly one character argument, on the characters of the serialized representation.  If the dumper descends into the object graph whose root is OBJECT for more than DEPTH recursions, an ellipsis token is dumped in the place of the vertex at DEPTH.

 -- procedure: restore char-reader returns object
     Restores the object whose serialized components are retrieved by repeatedly calling CHAR-READER, which must be a procedure that accepts zero arguments and returns a character.

Simple time access
------------------

The time structure exports a simple facility for accessing time offsets in two different flavours.

 -- procedure: real-time returns milliseconds
     Returns the real time in milliseconds that has passed since some unspecified moment in time. (In the current implementation on Unix, this moment happens to be the first call to real-time; on Win32, this is the start of the Scheme process.)  Though not suitable for measurements relative to entities outside the Scheme48 image, the real time is useful for measuring time differences within the Scheme image with reasonable precision; for example, thread sleep timing is implemented with this real time primitive.

 -- procedure: run-time returns ticks
     Returns the run time as an integer representing processor clock ticks since the start of the Scheme48 process.  This is much less precise than the real time, but it is useful for measuring time actually spent in the Scheme48 process, as opposed to time in general.