Previous: Common-Lisp-style formatting, Up: Libraries
Scheme48 provides various miscellaneous library utilities for common general-purpose tasks.
The destructuring structure exports a form for destructuring
S-expressions.
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)binds x to
5, y to3, a to(1 2), b to3, and c to(4 5), in body.
The pp structure exports a simple pretty-printer.
Pis a convenient alias forpretty-print; it passes 0 for position and the value of(current-output-port)if port is not passed.Pretty-printpretty-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)))))
The pretty-printer is somewhat extensible as well:
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))
The strong structure exports a routine for finding a list of the
strongly connected components in a graph.
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
#fbefore callingstrongly-connected-components, and the slots are reverted to#fbeforestrongly-connected-componentsreturns.
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.
Initializes the nondeterminism system and calls thunk; this returns the values thunk returns after then tearing down what was set up.
Eitherevaluates to the value of any one of the options. It is equivalent to McCarthy'sAMB. It may return any number of times.One-valuereturns 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 tovalues).All-valuesreturns a list of all of the single values, not multiple values, that exp could nondeterministically evaluate to.
Signals a nondeterministic failure. This is invalid outside of a
with-nondeterminism-protected dynamic extent.
The big-util structure exports a variety of miscellaneous
utilities.
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.
Errorsignals an error whose message is formatted byformatwith the given formatting template string and arguments.Breakpointsignals a breakpoint with a message similarly constructed and causes the command processor to push a new command level.
Negations of the
eq?and=predicates.
These simply return their arguments. The difference between them is that
no-opis guaranteed not to be integrated by the compiler, whereasidentitymay be.
Returns
#tif object is the null list, returns#fif object is a pair, or signals an error if object is neither the null list nor a pair.
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.
Returns
#tif object is a member of list, as determined byeq?; or#fif not.
#f#f
Firstreturns the first element of list that satisfies predicate, or#fif no element does.Anyreturns an element of list that satisfies predicate. Note thatanymay choose any element of the list, whereasfirstexplicitly returns the first element that satisfies predicate.
Any?returns#tif any element of list satisfies predicate, or#fif none do.Every?returns#tif every element of list satisfies predicate, or#fif there exists an element that does not.
These return a list of all elements in list that satisfy predicate.
Filteris not allowed to modify list's structure;filter!may, however.
This is a combination of
filterandmap. For each element e in list: if(proc e)returns a true value, that true value is collected in the output list.Filter-mapdoes not modify list's structure.
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-duplicatesdoes not modify list's structure.
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-listis not allowed to modify list's structure;partition-list!is.
These return a list containing all elements of list except for object.
Delqis not allowed to modify list's structure;delq!is.
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.
Returns an immutable string with string's contents. If string is already immutable, it is returned; otherwise, an immutable copy is returned.
The receiving structure exports the receive macro, a
convenient syntax atop R5RS's call-with-values.
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))
For sequences of multiple value bindings, the mvlet structure
exports two convenient macros.
Mvlet*is a multiple-value version ofletor a linearly nested version ofreceive:(mvlet* ((formals0 producer0) (formals1 producer1) ...) body) == (call-with-values (lambda () producer0) (lambda formals0 (call-with-values (lambda () producer1) (lambda formals1 ...body...))))
Mvletis 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.
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.
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.
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.
The time structure exports a simple facility for accessing time
offsets in two different flavours.
Returns the real time in milliseconds that has passed since some unspecified moment in time.1 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.
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.
[1] 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.