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.
P
is a convenient alias forpretty-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)))))
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
#f
before callingstrongly-connected-components
, and the slots are reverted to#f
beforestrongly-connected-components
returns.
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.
Either
evaluates to the value of any one of the options. It is equivalent to McCarthy'sAMB
. 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 tovalues
).All-values
returns 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.
Error
signals an error whose message is formatted byformat
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 level.
Negations of the
eq?
and=
predicates.
These simply return their arguments. The difference between them is that
no-op
is guaranteed not to be integrated by the compiler, whereasidentity
may be.
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.
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
#t
if object is a member of list, as determined byeq?
; or#f
if not.
#f
#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 thatany
may choose any element of the list, whereasfirst
explicitly returns the first element that satisfies predicate.
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.
These return a list of all elements in list that satisfy predicate.
Filter
is not allowed to modify list's structure;filter!
may, however.
This is a combination of
filter
andmap
. 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.
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.
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.
These return a list containing all elements of list except for object.
Delq
is 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 oflet
or 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...))))
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.
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.