racket/collects/scribblings/reference/procedures.scrbl
Matthew Flatt 39cedb62ed v3.99.0.2
svn: r7706
2007-11-13 12:40:00 +00:00

267 lines
9.9 KiB
Racket

#lang scribble/doc
@require["mz.ss"]
@title[#:tag "procedures"]{Procedures}
@defproc[(procedure? [v any/c]) boolean]{ Returns @scheme[#t] if
@scheme[v] is a procedure, @scheme[#f] otherwise.}
@defproc[(apply [proc procedure?] [v any/c] ... [lst list?]) any]{
@guideintro["apply"]{@scheme[apply]}
Applies @scheme[proc] using the content of @scheme[(list* v ... lst)]
as the (by-position) arguments. The given @scheme[proc] must accept as
many arguments as the number of @scheme[v]s plus length of
@scheme[lst], and it must not require any keyword arguments;
otherwise, the @exnraise[exn:fail:contract]. The given @scheme[proc]
is called in tail position with respect to the @scheme[apply] call.
@examples[
(apply + '(1 2 3))
(apply + 1 2 '(3))
(apply + '())
]}
@; ----------------------------------------
@section{Keywords and Arity}
@declare-exporting[(lib "scheme/procedure")]
@defproc[(keyword-apply [proc procedure?]
[kw-lst (listof keyword?)]
[kw-val-lst list?]
[v any/c] ...
[lst list?])
any]{
@guideintro["apply"]{@scheme[keyword-apply]}
Like @scheme[apply], but @scheme[kw-lst] and @scheme[kw-val-lst]
supply by-keyword arguments in addition to the by-position arguments
of the @scheme[v]s and @scheme[lst]. The given @scheme[kw-lst] must be
sorted using @scheme[keyword<], and no keyword can appear twice in
@scheme[kw-lst], otherwise, the @exnraise[exn:fail:contract]. The
given @scheme[kw-val-lst] must have the same length as
@scheme[kw-lst], otherwise, the @exnraise[exn:fail:contract]. The
given @scheme[proc] must accept all of the keywords in
@scheme[kw-lst], it must not require any other keywords, and it must
accept as many by-position arguments as supplied via the @scheme[v]s
and @scheme[lst]; otherwise, the @exnraise[exn:fail:contract].
@defexamples[
(define (f x #:y y #:z [z 10])
(list x y z))
(keyword-apply f '(#:y) '(2) '(1))
(keyword-apply f '(#:y #:z) '(2 3) '(1))
]}
@defproc[(procedure-arity [proc procedure?])
arity?]{
Returns information about the number of by-position arguments accepted
by @scheme[proc]. See also @scheme[arity?].}
@defproc[(arity? [v any/c]) boolean?]{
A valid arity is one of the following:
@itemize{
@item{An exact non-negative integer, which means that the procedure
accepts @scheme[_a] arguments, only.}
@item{A @scheme[arity-at-least] instance, which means that the
procedure accepts @scheme[(arity-at-least-value _a)] or more
arguments.}
@item{A list containing integers and @scheme[arity-at-least]
instances, which means that the procedure accepts any number of
arguments that can match one of the elements of @scheme[_a].}
}
@examples[
(procedure-arity cons)
(procedure-arity list)
(arity-at-least? (procedure-arity list))
(arity-at-least-value (procedure-arity list))
(arity-at-least-value (procedure-arity (lambda (x . y) x)))
(procedure-arity (case-lambda [(x) 0] [(x y) 1]))
]}
@defproc[(procedure-arity-includes? [proc procedure?] [k exact-nonnegative-integer?])
boolean?]{
Returns @scheme[#t] if the procedure can accept @scheme[k] arguments
when no keyword arguments are supplied, @scheme[#f] otherwise.
@examples[
(procedure-arity-includes? cons 2)
(procedure-arity-includes? display 3)
]}
@defproc[(procedure-reduce-arity [proc procedure?]
[arity arity?])
procedure?]{
Returns a procedure that is the same as @scheme[proc] (including
the same name returned by @scheme[object-name]), but that accepts
only arguments consistent with @scheme[arity]. In particular,
when @scheme[procedure-arity] is applied to the generated
procedure, it returns a value that is @scheme[equal?] to
@scheme[arity].
If the @scheme[arity] specification allows arguments that are not
in @scheme[(procedure-arity proc)], the @exnraise[exn:fail:contract].}
@defproc[(procedure-keywords [proc procedure?])
(values
(listof keyword?)
(or/c (listof keyword?)
false/c))]{
Returns information about the keyword arguments required and accepted
by a procedure. The first result is a list of keywords (sorted by
@scheme[keyword<]) that are required when applying @scheme[proc]. The
second result is a list of accepted keywords (sorted by
@scheme[keyword<]), or @scheme[#f] to mean that any keyword is
accepted. When the second result is a list, every element in the first
list is also in the second list.
@examples[
(procedure-keywords +)
(procedure-keywords (lambda (#:tag t #:mode m) t))
(procedure-keywords (lambda (#:tag t #:mode [m #f]) t))
]}
@defproc[(make-keyword-procedure
[proc (((listof keyword?) list?) list? . ->* . any)]
[plain-proc procedure? (lambda args (apply proc null null args))])
procedure?]{
Returns a procedure that accepts all keyword arguments (without
requiring any keyword arguments).
When the result is called with keyword arguments, then @scheme[proc]
is called; the first argument is a list of keywords sorted by
@scheme[keyword<], the second argument is a parllel list containing a
value for each keyword, and the remaining arguments are the
by-position arguments.
When the result is called without keyword arguments, then
@scheme[plain-proc] is called. Furthermore, @scheme[procedure-arity]
obtains its result frmo @scheme[plain-proc].
@defexamples[
(define show
(make-keyword-procedure (lambda (kws kw-args . rest)
(list kws kw-args rest))))
(show 1)
(show #:init 0 1 2 3 #:extra 4)
]}
@defstruct[arity-at-least ([value nonnegative-exact-integer?])]{
This structure type is used for the result of @scheme[procedure-arity].
See also @scheme[arity?].}
@defthing[prop:procedure struct-type-property?]{
A @tech{structure type property} to indentify structure types whose
instances can be applied as procedures. In particular, when
@scheme[procedure?] is applied to the instance, the result will be
@scheme[#t], and when an instance is used in the function position of
an application expression, a procedure is extracted from the instance
and used to complete the procedure call.
If the @scheme[prop:procedure] property value is an integer, it
designates a field within the structure that should contain a
procedure. The integer must be between @scheme[0] (inclusive) and the
number of non-automatic fields in the structure type (exclusive, not
counting supertype fields). The designated field must also be
specified as immutable, so that after an instance of the structure is
created, its procedure cannot be changed. (Otherwise, the arity and
name of the instance could change, and such mutations are generally
not allowed for procedures.) When the instance is used as the
procedure in an application expression, the value of the designated
field in the instance is used to complete the procedure call. (This
procedure can be another structure that acts as a procedure; the
immutability of procedure fields disallows cycles in the procedure
graph, so that the procedure call will eventually continue with a
non-structure procedure.) That procedure receives all of the arguments
from the application expression. The procedure's name (see
@scheme[object-name]) and arity (see @scheme[procedure-arity]) are also
used for the name and arity of the structure. If the value in the
designated field is not a procedure, then the instance behaves like
@scheme[(case-lambda)] (i.e., a procedure which does not accept any
number of arguments).
Providing an integer @scheme[proc-spec] argument to
@scheme[make-struct-type] is the same as both supplying the value with
the @scheme[prop:procedure] property and designating the field as
immutable (so that a property binding or immutable designation is
redundant and disallowed).
@examples[
(define-struct annotated-proc (base note)
#:property prop:procedure (struct-field-index base))
(define plus1 (make-annotated-proc
(lambda (x) (+ x 1))
"adds 1 to its argument"))
(procedure? plus1)
(annotated-proc? plus1)
(plus1 10)
(annotated-proc-note plus1)
]
When the @scheme[prop:procedure] value is a procedure, it should
accept at least one argument. When an instance of the structure is
used in an application expression, the property-value procedure is
called with the instance as the first argument. The remaining
arguments to the property-value procedure are the arguments from the
application expression. Thus, if the application expression contained
five arguments, the property-value procedure is called with six
arguments. The name of the instance (see @scheme[object-name]) is
unaffected by the property-value procedure, but the instance's arity
is determined by subtracting one from every possible argument count of
the property-value procedure. If the property-value procedure cannot
accept at least one argument, then the instance behaves like
@scheme[(case-lambda)].
Providing a procedure @scheme[proc-spec] argument to
@scheme[make-struct-type] is the same as supplying the value with the
@scheme[prop:procedure] property (so that a specific property binding
is disallowed).
@examples[
(define-struct fish (weight color)
#:property
prop:procedure
(lambda (f n) (set-fish-weight! f (+ n (fish-weight f)))))
(define wanda (make-fish 12 'red))
(fish? wanda)
(procedure? wanda)
(fish-weight wanda)
(for-each wanda '(1 2 3))
(fish-weight wanda)
]
If a structure type generates procedure instances, then subtypes of
the type also generate procedure instances. The instances behave the
same as instances of the original type. When a @scheme[prop:procedure]
property or non-@scheme[#f] @scheme[proc-spec] is supplied to
@scheme[make-struct-type] with a supertype that already behaves as a
procedure, the @exnraise[exn:fail:contract].}
@defproc[(procedure-struct-type? [type struct-type?]) boolean?]{
Returns @scheme[#t] if instances of the structure type represented by
@scheme[type] are procedures (according to @scheme[procedure?]),
@scheme[#f] otherwise.}