racket/collects/mzlib/scribblings/etc.scrbl
2008-04-25 21:36:37 +00:00

280 lines
9.0 KiB
Racket

#lang scribble/doc
@(require "common.ss"
scribble/eval
(for-label mzlib/etc
scheme/bool
scheme/local
setup/dirs
(only-in scheme build-list build-string build-vector
symbol=?)))
@(define etc-eval (make-base-eval))
@interaction-eval[#:eval etc-eval (require mzlib/etc)]
@(begin
(define-syntax-rule (bind id else-id)
(begin
(require (for-label scheme/base))
(define id (scheme lambda))
(define else-id (scheme else))))
(bind base-lambda base-else))
@mzlib[#:mode title etc]
The @schememodname[mzlib/etc] library re-exports the following
@schememodname[scheme/base] and other libraries:
@schemeblock[
boolean=?
true
false
build-list
build-string
build-vector
compose
local
symbol=?
]
@defform[(begin-lifted expr ...+)]
Lifts the @scheme[expr]s so that they are evaluated once at the ``top
level'' of the current context, and the result of the last
@scheme[expr] is used for every evaluation of the
@scheme[begin-lifted] form.
When this form is used as a run-time expression within a module, the
``top level'' corresponds to the module's top level, so that each
@scheme[expr] is evaluated once for each invocation of the
module. When it is used as a run-time expression outside of a module,
the ``top level'' corresponds to the true top level. When this form is
used in a @scheme[define-syntax], @scheme[letrec-syntax],
etc. binding, the ``top level'' corresponds to the beginning of the
binding's right-hand side. Other forms may redefine ``top level''
(using @scheme[local-expand/capture-lifts]) for the expressions that
they enclose.
@defform[(begin-with-definitions defn-or-expr ...)]{
Supports a mixture of expressions and mutually recursive definitions,
much like a @scheme[module] body. Unlike in a @scheme[module],
however, syntax definitions cannot be used to generate other immediate
definitions (though they can be used for expressions).
The result of the @scheme[begin-with-definitions] form is the result
of the last @scheme[defn-or-expr] if it is an expression,
@|void-const| otherwise. If no @scheme[defn-or-expr] is provided
(after flattening @scheme[begin] forms), the result is @|void-const|.}
@defform[(define-syntax-set (id ...) defn ...)]{
Similar to @scheme[define-syntaxes], but instead of a single body
expression, a sequence of definitions follows the sequence of defined
identifiers. For each @scheme[identifier], the @scheme[defn]s should
include a definition for @scheme[id]@schemeidfont{/proc}. The value
for @scheme[id]@schemeidfont{/proc} is used as the (expansion-time)
value for @scheme[id].
The @scheme[define-syntax-set] form is useful for defining a set of
syntax transformers that share helper functions, though
@scheme[begin-for-syntax] now serves essentially the same purposes.
@as-examples[
@schemeblock[
(define-syntax-set (let-current-continuation
let-current-escape-continuation)
(define (mk call-id)
(lambda (stx)
(syntax-case stx ()
[(_ id body1 body ...)
(with-syntax ([call call-id])
(syntax (call (lambda (id) body1 body ...))))])))
(define let-current-continuation/proc
(mk (quote-syntax call/cc)))
(define let-current-escape-continuation/proc
(mk (quote-syntax call/ec))))
]]}
@defform*[#:literals (else)
[(evcase key-expr (value-expr body-expr ...) ...+)
(evcase key-expr (value-expr body-expr ...) ... [else body-expr ...])]]{
The @scheme[evcase] form is similar to @scheme[case], except that
expressions are provided in each clause instead of a sequence of
data. After @scheme[key-expr] is evaluated, each @scheme[value-expr]
is evaluated until a value is found that is @scheme[eqv?] to the key
value; when a matching value is found, the corresponding
@scheme[body-expr]s are evaluated and the value(s) for the last is the
result of the entire @scheme[evcase] expression.
The @scheme[else] literal is recognized either as unbound (like in the
@schememodname[mzscheme] language) or bound as @|base-else| from
@schememodname[scheme/base].}
@defproc[(identity [v any/c]) any/c]{
Returns @scheme[v].}
@defform/subs[#:literals (val rec vals recs _ values)
(let+ clause body-expr ...+)
([clause (val target expr)
(rec target expr)
(vals (target ...) expr)
(recs (target expr) ...)
(_ expr ...)]
[target id
(values id ...)])]{
A binding construct that specifies scoping on a per-binding basis
instead of a per-expression basis. It helps eliminate rightward-drift
in programs. It looks similar to @scheme[let], except each clause has
an additional keyword tag before the binding variables.
Each @scheme[clause] has one of the following forms:
@itemize{
@item{@scheme[(val target expr)] : Binds @scheme[target]
non-recursively to @scheme[expr].}
@item{@scheme[(rec target expr)] : Binds @scheme[target] recursively to
@scheme[expr].}
@item{@scheme[(vals (target expr) ...)] : The @scheme[target]s are
bound to the @scheme[expr]s. The environment of the @scheme[expr]s is
the environment active before this clause.}
@item{@scheme[(recs (target expr) ...)] : The @scheme[targets]s are
bound to the @scheme[expr]s. The environment of the @scheme[expr]s
includes all of the @scheme[targets]s.}
@item{@scheme[(_ expr ...)] : Evaluates the @scheme[expr]s without
binding any variables.}
}
The clauses bind left-to-right. When a @scheme[target] is
@scheme[(values id ...)], multiple values returned by the
corresponding expression are bound to the multiple variables.
@examples[
#:eval etc-eval
(let+ ([val (values x y) (values 1 2)])
(list x y))
(let ([x 1])
(let+ ([val x 3]
[val y x])
y))
]}
@defproc[(loop-until [start any/c] [done? (any/c . -> . any)]
[next (any/c . -> . any/c)]
[f (any/c . -> . any)])
void?]{
Repeatedly invokes the @scheme[f] procedure until the @scheme[done?]
procedure returns @scheme[#t]:
@schemeblock[
(define (loop-until start done? next f)
(let loop ([i start])
(unless (done? i)
(f i)
(loop (next i)))))
]}
@defproc[(namespace-defined? [sym symbol?]) boolean?]{
Returns @scheme[#t] if @scheme[namespace-variable-value] would return
a value for @scheme[sym], @scheme[#f] otherwise.}
@defform[(nand expr ...)]{
Same as @scheme[(not (and expr ...))].}
@defform[(nor expr ...)]{
Same as @scheme[(not (or expr ...))].}
@defform[(opt-lambda formals body ...+)]{
Supports optional (but not keyword) arguments like @base-lambda from
@scheme[scheme/base].}
@defform[(recur id bindings body ...+)]{
Equivalent to @scheme[(let id bindings body ...+)].}
@defform*[[(rec id value-expr)
(rec (id arg-id ...) expr)
(rec (id arg-id ... . rest-id) expr)]]{
Equivalent, respectively, to
@schemeblock[
(letrec ([id value-expr]) id)
(letrec ([id (lambda (arg-id ...) value-expr)]) id)
(letrec ([id (lambda (arg-id ... . rest-id) value-expr)]) id)
]}
@defform*[[(this-expression-source-directory)
(this-expression-source-directory datum)]]{
@margin-note{See @schememodname[scheme/runtime-path] for a definition form
that works better when creating executables.}
Expands to an expression that evaluates to the directory of the file
containing the source @scheme[datum]. If @scheme[datum] is not
supplied, then the entire @scheme[(this-expression-source-directory)]
expression is used as @scheme[datum].
If @scheme[datum] has a source module, then the expansion attempts to
determine the module's run-time location. This location is determined
by preserving the lexical context of @scheme[datum] in a syntax
object, extracting its source module path at run time, and then
resolving the module path.
Otherwise, @scheme[datum]'s source file is determined through source
location information associated with @scheme[datum], if it is
present. As a last resort, @scheme[current-load-relative-directory] is
used if it is not @scheme[#f], and @scheme[current-directory] is used
if all else fails.
A directory path derived from source location is always stored in
bytes in the expanded code, unless the file is within the result of
@scheme[find-collects-dir], in which case the expansion records the
path relative to @scheme[(find-collects-dir)] and then reconstructs it
using @scheme[(find-collects-dir)] at run time.}
@defform*[[(this-expression-file-name)
(this-expression-file-name datum)]]{
Similar to @scheme[this-expression-source-directory], except that only
source information associated with @scheme[datum] or
@scheme[(this-expression-file-name)] is used to extract a filename. If
no filename is available, the result is @scheme[#f].}
@defform[#:literals (quote unsyntax scheme)
(hash-table (#,(scheme quote) flag) ... (key-expr val-expr) ...)]{
Creates a new hash-table providing the quoted flags (if any) to
@scheme[make-hash-table], and then mapping each key to the
corresponding values.}