work on docs for keyword arguments
svn: r6581
This commit is contained in:
parent
0a7e47e495
commit
05607ad661
|
@ -25,6 +25,8 @@
|
|||
|
||||
opt-lambda
|
||||
define-opt
|
||||
keyword-apply
|
||||
make-keyword-procedure
|
||||
|
||||
local
|
||||
recur
|
||||
|
@ -192,6 +194,34 @@
|
|||
(define id (opt-lambda args body1 body ...))]
|
||||
[(_ . rest) (define . rest)]))
|
||||
|
||||
(define (keyword-apply f kw-args normal-args . normal-argss)
|
||||
(apply f (append (apply append
|
||||
(map (lambda (p) (list (car p) (cdr p))) kw-args))
|
||||
(if (null? normal-argss)
|
||||
normal-args
|
||||
(cons normal-args
|
||||
(let loop ([normal-argss normal-argss])
|
||||
(if (null? (cdr normal-argss))
|
||||
(car normal-argss)
|
||||
(cons (car normal-argss)
|
||||
(loop (cdr normal-argss))))))))))
|
||||
|
||||
(define (make-keyword-procedure f)
|
||||
(lambda args
|
||||
(let loop ([args args]
|
||||
[normal null]
|
||||
[kw null])
|
||||
(cond
|
||||
[(null? args) (apply f kw (reverse normal))]
|
||||
[(and (keyword? (car args))
|
||||
(pair? (cdr args)))
|
||||
(loop (cddr args)
|
||||
normal
|
||||
(cons (cons (car args) (cadr args)) kw))]
|
||||
[else (loop (cdr args)
|
||||
(cons (car args) normal)
|
||||
kw)]))))
|
||||
|
||||
(define (sort-kws len need-kw l)
|
||||
(for-each (lambda (kw)
|
||||
(unless (memq kw l)
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
(make-element 'subscript (decode-content str)))
|
||||
|
||||
(define/kw (superscript #:body str)
|
||||
(make-element superscript (decode-content str)))
|
||||
(make-element 'superscript (decode-content str)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
|
||||
(provide onscreen menuitem defterm
|
||||
schemefont schemevalfont schemeresultfont schemeidfont
|
||||
schemeparenfont schemekeywordfont
|
||||
schemeparenfont schemekeywordfont schememetafont
|
||||
file exec
|
||||
link procedure
|
||||
idefterm)
|
||||
|
@ -116,6 +116,8 @@
|
|||
(make-element "schemesymbol" (decode-content str)))
|
||||
(define/kw (schemeparenfont #:body str)
|
||||
(make-element "schemeparen" (decode-content str)))
|
||||
(define/kw (schememetafont #:body str)
|
||||
(make-element "schememeta" (decode-content str)))
|
||||
(define/kw (schemekeywordfont #:body str)
|
||||
(make-element "schemekeyword" (decode-content str)))
|
||||
(define/kw (file #:body str)
|
||||
|
@ -161,9 +163,9 @@
|
|||
(schemeresultfont "#<undefined>"))
|
||||
|
||||
(define dots0
|
||||
(make-element "schemeparen" (list "...")))
|
||||
(make-element "schememeta" (list "...")))
|
||||
(define dots1
|
||||
(make-element "schemeparen" (list "..." (superscript "+"))))
|
||||
(make-element "schememeta" (list "...+")))
|
||||
|
||||
(define-syntax (arg-contract stx)
|
||||
(syntax-case stx (... ...+)
|
||||
|
@ -322,7 +324,7 @@
|
|||
(if (keyword? (car i))
|
||||
(cadr i)
|
||||
(car i))))
|
||||
(apply append (map cdr prototypes)))])
|
||||
(apply append (map cdr prototypes)))])
|
||||
(make-splice
|
||||
(cons
|
||||
(make-table
|
||||
|
@ -437,21 +439,22 @@
|
|||
(make-paragraph
|
||||
(list
|
||||
(to-element
|
||||
`(struct ,(make-target-element*
|
||||
(to-element name)
|
||||
(let ([name (if (pair? name)
|
||||
(car name)
|
||||
name)])
|
||||
(list* (list name)
|
||||
(list name '?)
|
||||
(list 'make- name)
|
||||
(append
|
||||
(map (lambda (f)
|
||||
(list name '- (car f)))
|
||||
fields)
|
||||
(map (lambda (f)
|
||||
(list 'set- name '- (car f) '!))
|
||||
fields)))))
|
||||
`(,(schemeparenfont "struct")
|
||||
,(make-target-element*
|
||||
(to-element name)
|
||||
(let ([name (if (pair? name)
|
||||
(car name)
|
||||
name)])
|
||||
(list* (list name)
|
||||
(list name '?)
|
||||
(list 'make- name)
|
||||
(append
|
||||
(map (lambda (f)
|
||||
(list name '- (car f)))
|
||||
fields)
|
||||
(map (lambda (f)
|
||||
(list 'set- name '- (car f) '!))
|
||||
fields)))))
|
||||
,(map car fields))))))))
|
||||
(map (lambda (v)
|
||||
(cond
|
||||
|
@ -506,7 +509,8 @@
|
|||
[(pair? form) (append (loop (car form))
|
||||
(loop (cdr form)))]
|
||||
[else null])))
|
||||
forms))])
|
||||
forms))]
|
||||
[current-meta-list '(... ...+)])
|
||||
(make-splice
|
||||
(cons
|
||||
(make-table
|
||||
|
@ -550,7 +554,8 @@
|
|||
[(pair? form) (append (loop (car form))
|
||||
(loop (cdr form)))]
|
||||
[else null]))
|
||||
(current-variable-list))])
|
||||
(current-variable-list))]
|
||||
[current-meta-list '(... ...+)])
|
||||
(make-blockquote
|
||||
"leftindent"
|
||||
(cons
|
||||
|
|
|
@ -15,14 +15,16 @@
|
|||
syntax-ize-hook
|
||||
current-keyword-list
|
||||
current-variable-list
|
||||
current-meta-list
|
||||
|
||||
(struct shaped-parens (val shape)))
|
||||
|
||||
(define no-color "schemeplain")
|
||||
(define meta-color "schemeplain")
|
||||
(define reader-color "schemeplain")
|
||||
(define keyword-color "schemekeyword")
|
||||
(define comment-color "schemecomment")
|
||||
(define paren-color "schemeparen")
|
||||
(define meta-color "schememeta")
|
||||
(define value-color "schemevalue")
|
||||
(define symbol-color "schemesymbol")
|
||||
(define variable-color "schemevariable")
|
||||
|
@ -39,6 +41,8 @@
|
|||
set!)))
|
||||
(define current-variable-list
|
||||
(make-parameter null))
|
||||
(define current-meta-list
|
||||
(make-parameter null))
|
||||
|
||||
(define defined-names (make-hash-table))
|
||||
|
||||
|
@ -246,7 +250,7 @@
|
|||
[(unsyntax) (values "#," 0)])])
|
||||
(out str (if (positive? (+ quote-depth quote-delta))
|
||||
value-color
|
||||
meta-color))
|
||||
reader-color))
|
||||
(let ([i (cadr (syntax->list c))])
|
||||
(set! src-col (or (syntax-column i) src-col))
|
||||
(hash-table-put! next-col-map src-col dest-col)
|
||||
|
@ -339,8 +343,6 @@
|
|||
(char=? (string-ref s 0) #\_))
|
||||
(values (substring s 1) #t #f)
|
||||
(values s #f #f))))]
|
||||
[(is-kw?) (and (identifier? c)
|
||||
(memq (syntax-e c) (current-keyword-list)))]
|
||||
[(is-var?) (and (identifier? c)
|
||||
(memq (syntax-e c) (current-variable-list)))])
|
||||
(if (element? (syntax-e c))
|
||||
|
@ -375,8 +377,12 @@
|
|||
value-color]
|
||||
[(identifier? c)
|
||||
(cond
|
||||
[is-kw?
|
||||
[(and (identifier? c)
|
||||
(memq (syntax-e c) (current-keyword-list)))
|
||||
keyword-color]
|
||||
[(and (identifier? c)
|
||||
(memq (syntax-e c) (current-meta-list)))
|
||||
meta-color]
|
||||
[is-var?
|
||||
variable-color]
|
||||
[it? variable-color]
|
||||
|
@ -526,7 +532,9 @@
|
|||
(list #f 1 col (+ 1 col)
|
||||
(+ 2
|
||||
vec-sz
|
||||
(sub1 (length l))
|
||||
(if (zero? (length l))
|
||||
0
|
||||
(sub1 (length l)))
|
||||
(apply + (map syntax-span l)))))))]
|
||||
[(pair? v)
|
||||
(let* ([a (syntax-ize (car v) (+ col 1))]
|
||||
|
|
|
@ -165,6 +165,11 @@
|
|||
font-family: Courier; font-size: 80%;
|
||||
}
|
||||
|
||||
.schememeta {
|
||||
color: #262680;
|
||||
font-family: Courier; font-size: 80%;
|
||||
}
|
||||
|
||||
.schemeopt {
|
||||
color: black;
|
||||
}
|
||||
|
|
|
@ -37,13 +37,15 @@ procedure's @idefterm{arity} is the number(s) of arguments that it
|
|||
accepts.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Keyword Arguments}
|
||||
@section[#:tag "guide:keyword-args"]{Keyword Arguments}
|
||||
|
||||
Some procedures accept @defterm{keyword arguments} in addition to
|
||||
by-position arguments. For that case, an @scheme[_arg] can be an
|
||||
@scheme[_arg-keyword _arg-expr] sequence instead of just a
|
||||
@scheme[_arg-expr]:
|
||||
|
||||
@margin-note{For an introduction to keywords, see @secref["guide:keywords"].}
|
||||
|
||||
@specform/subs[
|
||||
(_proc-expr _arg ...)
|
||||
([arg arg-expr
|
||||
|
@ -55,23 +57,24 @@ For example,
|
|||
@schemeblock[(go "super.ss" #:mode 'fast)]
|
||||
|
||||
calls the procedure bound to @scheme[go] with @scheme["super.ss"] as a
|
||||
by-position argument, and with @scheme['fast] as an argument associated
|
||||
with the @scheme[#:mode] keyword. Thus, a keyword is implicitly paired
|
||||
with the expression that follows it. Since a keyword by itself is not
|
||||
an expression, then
|
||||
by-position argument, and with @scheme['fast] as an argument
|
||||
associated with the @scheme[#:mode] keyword. A keyword is implicitly
|
||||
paired with the expression that follows it.
|
||||
|
||||
Since a keyword by itself is not an expression, then
|
||||
|
||||
@schemeblock[(go "super.ss" #:mode #:fast)]
|
||||
|
||||
is a syntax error---because @scheme[#:fast] is not an expression.
|
||||
is a syntax error. The @scheme[#:mode] keyword must be followed by an
|
||||
expression to produce an argument value, and @scheme[#:fast] is not an
|
||||
expression.
|
||||
|
||||
The order of keyword @scheme[_arg]s determines the order in which
|
||||
@scheme[_arg-expr]s are evaluated, but a procedure accepts (or
|
||||
declines) keyword arguments independent of their position in the
|
||||
argument list. That is, keyword arguments are recognized by an applied
|
||||
procedure using only the associated keyword. The above call to
|
||||
@scheme[go] can be equivalently written
|
||||
@scheme[_arg-expr]s are evaluated, but a procedure accepts keyword
|
||||
arguments independent of their position in the argument list. The
|
||||
above call to @scheme[go] can be equivalently written
|
||||
|
||||
@schemeblock[(go #:mode #:fast "super.ss")]
|
||||
@schemeblock[(go #:mode 'fast "super.ss")]
|
||||
|
||||
@refdetails["mz:application"]{procedure applications}
|
||||
|
||||
|
@ -98,8 +101,8 @@ of the items in the list:
|
|||
(avg '(1 2))
|
||||
]
|
||||
|
||||
The @scheme[apply] procedure offers a way around this restriction, It
|
||||
takes another procedure a @italic{list} arguments, and it applies the
|
||||
The @scheme[apply] procedure offers a way around this restriction. It
|
||||
takes a procedure and a @italic{list} arguments, and it applies the
|
||||
procedure to the arguments:
|
||||
|
||||
@def+int[
|
||||
|
@ -109,3 +112,26 @@ procedure to the arguments:
|
|||
(avg '(1 2))
|
||||
(avg '(1 2 3 4))
|
||||
]
|
||||
|
||||
As a convenience, the @scheme[apply] produce accepts additional
|
||||
arguments between the procedure and the list. The additional arguments
|
||||
are effectively @scheme[cons]ed onto the argument list:
|
||||
|
||||
@def+int[
|
||||
(define (anti-sum lst)
|
||||
(apply - 0 lst))
|
||||
(anti-sum '(1 2 3))
|
||||
]
|
||||
|
||||
The @scheme[apply] procedure supports only by-position arguments. To
|
||||
apply a procedure with keyword arguments, use the
|
||||
@scheme[keyword-apply] procedure, which accepts a procedure to apply
|
||||
and two lists. The first list contains contains pairs, each matching a
|
||||
keyword with its corresponding value. The second list contains
|
||||
by-position procedure arguments, as for @scheme[apply].
|
||||
|
||||
@schemeblock[
|
||||
(keyword-apply go
|
||||
(list (cons '#:mode 'fast))
|
||||
(list "super.ss"))
|
||||
]
|
||||
|
|
|
@ -23,5 +23,6 @@ built-in datatypes for simple forms of data.
|
|||
@include-section["boxes.scrbl"]
|
||||
@include-section["hash-tables.scrbl"]
|
||||
@include-section["paths.scrbl"]
|
||||
@include-section["regexps-data.scrbl"]
|
||||
@include-section["keywords.scrbl"]
|
||||
@include-section["void-and-undef.scrbl"]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
@interaction-eval[(require (rename (lib "etc.ss") define define-opt))]
|
||||
|
||||
@title{Definitions: @scheme[define] and @scheme[define-values]}
|
||||
@title{Definitions: @scheme[define]}
|
||||
|
||||
A basic definition has the form
|
||||
|
||||
|
@ -65,7 +65,7 @@ which is a shorthand
|
|||
]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "guide:multiple-values"]{Multiple Values}
|
||||
@section[#:tag "guide:multiple-values"]{Multiple Values and @scheme[define-values]}
|
||||
|
||||
A Scheme expression normally produces a single result, but some
|
||||
expressions can produce multiple results. For example,
|
||||
|
@ -78,7 +78,7 @@ but @scheme[quotient/remainder] produces the same two values at once:
|
|||
(quotient/remainder 13 3)
|
||||
]
|
||||
|
||||
As shown abpve, the REPL prints each result value on its own line.
|
||||
As shown above, the REPL prints each result value on its own line.
|
||||
|
||||
Multiple-valued procedures can be implemented in terms of the
|
||||
@scheme[values] procedure, which takes any number of values and
|
||||
|
|
|
@ -51,10 +51,10 @@ forms, where square brackets are normally used (by convention). That
|
|||
is square brackets @italic{do not} mean optional parts of the
|
||||
syntactic form.
|
||||
|
||||
A @scheme[...] indicates zero or more repetitions of the preceding
|
||||
form, and @scheme[...+] indicates one or more repetitions of the
|
||||
preceding datum. Otherwise, non-italicized identifiers stand form
|
||||
themselves.
|
||||
A @schememetafont{...} indicates zero or more repetitions of the
|
||||
preceding form, and @schememetafont{...+} indicates one or more
|
||||
repetitions of the preceding datum. Otherwise, non-italicized
|
||||
identifiers stand form themselves.
|
||||
|
||||
Based on the above grammar, then, here are a few legal uses of
|
||||
@schemekeywordfont{something}:
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@title[#:tag "keywords"]{Keywords}
|
||||
@title[#:tag "guide:keywords"]{Keywords}
|
||||
|
||||
A @defterm{keyword} is similar to a symbol (see @secref["guide:symbols"]),
|
||||
but its printed form is prefixed with @litchar{#:}.
|
||||
A @defterm{keyword} value is similar to a symbol (see
|
||||
@secref["guide:symbols"]), but its printed form is prefixed with
|
||||
@litchar{#:}.
|
||||
|
||||
@refdetails/gory["mz:parse-keyword"]{the syntax of keywords}
|
||||
|
||||
|
@ -16,17 +17,22 @@ but its printed form is prefixed with @litchar{#:}.
|
|||
(eq? '#:apple (string->keyword "apple"))
|
||||
]
|
||||
|
||||
Although keywords are values, an unquoted keyword is not an
|
||||
expression, just as an unquoted identifier does not produce a symbol:
|
||||
More precisely, a keyword is analogous to an identifier; in the same
|
||||
way that an identifier can be quoted to produce a symbol, a keyword
|
||||
can be quoted to produce a value. The same term ``keyword'' is used in
|
||||
both cases, but we sometimes use @defterm{keyword value} to refer more
|
||||
specifically to the result of a quote-keyword expression or of
|
||||
@scheme[string->keyword]. An unquoted keyword is not an expression,
|
||||
just as an unquoted identifier does not produce a symbol:
|
||||
|
||||
@examples[
|
||||
not-a-symbol-expression
|
||||
#:not-a-keyword-expression
|
||||
]
|
||||
|
||||
Despite their similarities, keywords are used differently than
|
||||
symbols. Keywords are intented for use (unquoted) as special markers
|
||||
in argument lists and in certain syntactic forms.
|
||||
Despite their similarities, keywords are used in a different way than
|
||||
identifiers or symbols. Keywords are intented for use (unquoted) as
|
||||
special markers in argument lists and in certain syntactic forms.
|
||||
|
||||
@italic{Need some examples here, once we have more keyword-based
|
||||
procedures and syntax in place...}
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
@require["guide-utils.ss"]
|
||||
|
||||
@interaction-eval[(require (rename (lib "etc.ss") lambda opt-lambda))]
|
||||
@interaction-eval[(require (only (lib "etc.ss") keyword-apply
|
||||
make-keyword-procedure))]
|
||||
|
||||
@title[#:tag "guide:lambda"]{Procedures: @scheme[lambda] and @scheme[case-lambda]}
|
||||
@title[#:tag "guide:lambda"]{Procedures: @scheme[lambda]}
|
||||
|
||||
A @scheme[lambda] expression creates a procedure. In the simplest
|
||||
Such a @scheme[lambda] expression creates a procedure. In the simplest
|
||||
case, a @scheme[lambda] expression has the form
|
||||
|
||||
@specform[
|
||||
|
@ -28,7 +30,7 @@ A @scheme[lambda] form with @math{n} @scheme[_arg-id]s accepts
|
|||
]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Rest Arguments}
|
||||
@section{Declaring a Rest Argument}
|
||||
|
||||
A @scheme[lambda] expression can also have the form
|
||||
|
||||
|
@ -50,8 +52,8 @@ into a list bound to @scheme[_rest-id].
|
|||
1 2 3)
|
||||
]
|
||||
|
||||
Procedures of this form often use @scheme[apply] to call another
|
||||
procedure that accepts any number of arguments.
|
||||
Procedures with a @scheme[_rest-id] often use @scheme[apply] to call
|
||||
another procedure that accepts any number of arguments.
|
||||
|
||||
@margin-note{See @secref["guide:apply"] for more information on
|
||||
@scheme[apply].}
|
||||
|
@ -65,17 +67,17 @@ procedure that accepts any number of arguments.
|
|||
(max-mag 1 -2 0)
|
||||
]
|
||||
|
||||
Generalizing the fixed-arity and any-arity style, a @scheme[lambda]
|
||||
expression can have the form
|
||||
The @scheme[lambda] form also supports required arguments combined
|
||||
with a @scheme[_rest-id]:
|
||||
|
||||
@specform[
|
||||
(lambda (arg-id ...+ . rest-id)
|
||||
body ...+)
|
||||
]
|
||||
|
||||
The result is a procedure that requires at least as many arguments as
|
||||
@scheme[_arg-id]s, and also accepts any number of additional
|
||||
arguments.
|
||||
The result of this form is a procedure that requires at least as many
|
||||
arguments as @scheme[_arg-id]s, and also accepts any number of
|
||||
additional arguments.
|
||||
|
||||
@defexamples[
|
||||
(define max-mag
|
||||
|
@ -90,16 +92,19 @@ A @scheme[_rest-id] variable is sometimes called a @defterm{rest
|
|||
argument}, because it accepts the ``rest'' of the procedure arguments.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Optional Arguments}
|
||||
@section{Declaring Optional Arguments}
|
||||
|
||||
Instead of just an identifier, an argument (other than a rest
|
||||
argument) in a @scheme[lambda] form can be specified with an
|
||||
identifier and a default value:
|
||||
|
||||
@specform/subs[
|
||||
(lambda (arg ...+ . rest-id)
|
||||
(lambda gen-formals
|
||||
body ...+)
|
||||
([arg arg-id
|
||||
([gen-formals (arg ...)
|
||||
rest-id
|
||||
(arg ...+ . rest-id)]
|
||||
[arg arg-id
|
||||
[arg-id default-expr]])
|
||||
]{}
|
||||
|
||||
|
@ -129,15 +134,18 @@ and every following @scheme[_arg-id] must have a default as well.
|
|||
(greet "Adam")
|
||||
]
|
||||
|
||||
@section{Keyword Arguments}
|
||||
@section[#:tag "guide:lambda-keywords"]{Declaring Keyword Arguments}
|
||||
|
||||
A @scheme[lambda] form can declare an argument to be passed by
|
||||
keyword, instead of position. Keyword arguments can be mixed with
|
||||
by-position arguments, and default-value expressions can be supplied
|
||||
for either kind of argument:
|
||||
|
||||
@margin-note{For an introduction to applications with keywords,
|
||||
see @secref["guide:keyword-args"].}
|
||||
|
||||
@specform/subs[
|
||||
(lambda (arg ...+ . rest-id)
|
||||
(lambda gen-formals
|
||||
body ...+)
|
||||
([arg arg-id
|
||||
[arg-id default-expr]
|
||||
|
@ -145,7 +153,7 @@ for either kind of argument:
|
|||
(code:line arg-keyword [arg-id default-expr])])
|
||||
]{}
|
||||
|
||||
As argument specified as @scheme[(code:line _arg-keyword _arg-id)] is
|
||||
An argument specified as @scheme[(code:line _arg-keyword _arg-id)] is
|
||||
supplied by an application using the same @scheme[_arg-keyword]. The
|
||||
position of the keyword--identifier pair in the argument list does not
|
||||
matter for matching with arguments in an application, because it will
|
||||
|
@ -160,7 +168,7 @@ be matched to an argument value by keyword instead of by position.
|
|||
(greet #:last "Doe" "John")
|
||||
]
|
||||
|
||||
A @scheme[(code:line _arg-keyword [_arg-id _default-expr])] argument
|
||||
An @scheme[(code:line _arg-keyword [_arg-id _default-expr])] argument
|
||||
specifies a keyword-based argument with a default value.
|
||||
|
||||
@defexamples[
|
||||
|
@ -174,6 +182,29 @@ specifies a keyword-based argument with a default value.
|
|||
(greet "Karl" #:last "Marx" #:hi "Guten Tag")
|
||||
]
|
||||
|
||||
The @scheme[lambda] form does not directly support the creation
|
||||
of a procedure that accepts ``rest'' keywords. To construct a
|
||||
procedure that accepts any and all keyword arguments, use
|
||||
@scheme[make-keyword-procedure]. The procedure supplied to
|
||||
@scheme[make-keyword-procedure] receives all keyword arguments as
|
||||
a list of pairs through the first (by-position) argument, and
|
||||
then all by-position arguments from an application as the
|
||||
remaining by-position arguments.
|
||||
|
||||
@margin-note{For an introduction to @scheme[keyword-apply], see
|
||||
@secref["guide:apply"].}
|
||||
|
||||
@defexamples[
|
||||
(define (trace-wrap f)
|
||||
(make-keyword-procedure
|
||||
(lambda (kw-args . rest)
|
||||
(printf "Called with ~s ~s\n" kw-args rest)
|
||||
(keyword-apply f kw-args rest))))
|
||||
((trace-wrap greet) "John" #:hi "Howdy")
|
||||
]
|
||||
|
||||
@refdetails["mz:lambda"]{procedure expressions}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Arity-Sensitive Procedures: @scheme[case-lambda]}
|
||||
|
||||
|
@ -190,7 +221,7 @@ that are supplied. A case-lambda expression has the form
|
|||
(arg-id ...+ . rest-id)])
|
||||
]
|
||||
|
||||
where each @scheme[_formals _body ...+] is anlogous to @scheme[(lambda
|
||||
where each @scheme[[_formals _body ...+]] is analogous to @scheme[(lambda
|
||||
_formals _body ...+)]. Applying a procedure produced by
|
||||
@scheme[case-lambda] is like applying a @scheme[lambda] for the first
|
||||
case that matches the number of given arguments.
|
||||
|
@ -208,5 +239,3 @@ case that matches the number of given arguments.
|
|||
|
||||
A @scheme[case-lambda] procedure cannot directly support optional or
|
||||
keyword arguments.
|
||||
|
||||
@refdetails["mz:lambda"]{procedure expressions}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@title[#:tag "paths"]{Paths}
|
||||
@title[#:tag "guide:paths"]{Paths}
|
||||
|
||||
A @defterm{path} encapsulates a filesystem path that (potentially)
|
||||
names a file or directory. Although paths can be converted to and from
|
||||
|
|
8
collects/scribblings/guide/regexps-data.scrbl
Normal file
8
collects/scribblings/guide/regexps-data.scrbl
Normal file
|
@ -0,0 +1,8 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "manual.ss" "scribble")]
|
||||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@title[#:tag "guide:regexp-literals"]{Regexps}
|
||||
|
||||
A @defterm{regexp} is a pattern for regular-expression matching.
|
|
@ -202,7 +202,8 @@ If the @scheme[lst]s are empty, then @scheme[#f] is returned.}
|
|||
@; ----------------------------------------------------------------------
|
||||
@include-section["sequences.scrbl"]
|
||||
|
||||
@section[#:tag "mz:procedures"]{Procedures}
|
||||
@; ----------------------------------------------------------------------
|
||||
@include-section["procedures.scrbl"]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "void"]{Void and Undefined}
|
||||
|
|
149
collects/scribblings/reference/procedures.scrbl
Normal file
149
collects/scribblings/reference/procedures.scrbl
Normal file
|
@ -0,0 +1,149 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@interaction-eval[(require (rename (lib "etc.ss") lambda opt-lambda))]
|
||||
@interaction-eval[(require (only (lib "etc.ss") keyword-apply
|
||||
make-keyword-procedure))]
|
||||
|
||||
@title[#:tag "mz: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["guide: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 + '())
|
||||
]}
|
||||
|
||||
|
||||
@defproc[(keyword-apply [proc procedure?]
|
||||
[kw-lst (listof (cons/c keyword? any/c))]
|
||||
[v any/c] ...
|
||||
[lst list?])
|
||||
any]{
|
||||
|
||||
@guideintro["guide:apply"]{@scheme[keyword-apply]}
|
||||
|
||||
Like @scheme[apply], but @scheme[kw-lst] supplies 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<] on the @scheme[car] of each pair in the list, and no
|
||||
keyword can appear twice in the @scheme[car]s of @scheme[kw-lst]. The
|
||||
given @scheme[proc] must accept all of the keywords in
|
||||
@scheme[kw-lst], and it must not require any other keywords;
|
||||
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 . 2) (#:z . 3)) '(1))
|
||||
]}
|
||||
|
||||
@defproc[(procedure-arity [proc procedure?])
|
||||
(or/c exact-nonnegative-integer?
|
||||
arity-at-least?
|
||||
(listof
|
||||
(or/c exact-nonnegative-integer?
|
||||
arity-at-least?)))]{
|
||||
|
||||
Returns information about the number of arguments accepted by
|
||||
@scheme[proc] when called without keyword arguments. The result
|
||||
@scheme[_a] is one of the following:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{An exact non-negative integer, which means that the procedure
|
||||
always accepts exactly @scheme[_a] arguments.}
|
||||
|
||||
@item{A @scheme[arity-at-least] instance, which means that the
|
||||
procedure takes @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 takes any number of
|
||||
arguments that can match one of the elements of @scheme[_a].}
|
||||
|
||||
}
|
||||
|
||||
If a procedure requires at least one keyword argument, then
|
||||
@scheme[procedure-arity] returns @scheme['()] for the procedure.
|
||||
|
||||
@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[(keyword-procedure-arity [proc procedure?])
|
||||
(values
|
||||
(listof keyword?)
|
||||
(or/c (listof keyword?)
|
||||
false/c)
|
||||
(or/c
|
||||
exact-nonnegative-integer?
|
||||
arity-at-least?
|
||||
(listof
|
||||
(or/c
|
||||
exact-nonnegative-integer?
|
||||
arity-at-least?))))]{
|
||||
|
||||
Similar to @scheme[keyword-procedure-arity], but for the case
|
||||
that keywords are supplied to @scheme[proc]. 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 keyword (sorted by @scheme[keyword<]), or @scheme[#f]
|
||||
to mean that any keyword is accepted. The last result is as for
|
||||
@scheme[procedure-arity] for the by-position arguments of
|
||||
@scheme[proc], except that it is not @scheme['()] when keywords
|
||||
are required.}
|
||||
|
||||
@defproc[(make-keyword-procedure
|
||||
[proc (((listof (cons/c keyword? any/c))) list? . ->* . any)])
|
||||
procedure?]{
|
||||
|
||||
Returns a procedure that accepts any number of arguments and all
|
||||
keyword arguments (without requiring any keyword arguments). The
|
||||
resulting procedure calls @scheme[proc], supplying to @scheme[proc]
|
||||
all keyword arguments given in the original application as a list of
|
||||
keyword--value pairs, sorted by @scheme[keyword<] on the keywords. All
|
||||
by-position arguments supplied in the original application are
|
||||
supplied to @scheme[proc] after the list for keyword arguments.
|
||||
|
||||
@defexamples[
|
||||
(define show
|
||||
(make-keyword-procedure (lambda (kw-args . rest)
|
||||
(list 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].}
|
|
@ -27,25 +27,24 @@ Within such specifications,
|
|||
@item{@scheme[...+] indicates one or
|
||||
more repetitions of the preceding datum.}
|
||||
|
||||
@item{italic meta-identifier play the role of non-terminals; in
|
||||
@item{italic meta-identifiers play the role of non-terminals; in
|
||||
particular,
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{a meta-identifier that ends in @scheme[_id] stands for a
|
||||
syntax-wrapped symbol.}
|
||||
@item{a meta-identifier that ends in @scheme[_id] stands for an
|
||||
identifier.}
|
||||
|
||||
@item{a meta-identifier that ends in @scheme[_keyword] stands
|
||||
for a syntax-wrapped keyword.}
|
||||
for a keyword.}
|
||||
|
||||
@item{a meta-identifier that ends with @scheme[_expr] stands
|
||||
for a sub-form that is expanded as an expression.}
|
||||
|
||||
@item{a meta-identifier that ends with @scheme[_body] stands
|
||||
for a non-empty syntax-wrapped list of sub-forms; the
|
||||
list is expanded as internal-definition sequence
|
||||
followed by at least one expression (see
|
||||
@secref["mz:intdef-body"] for details).}
|
||||
@item{A meta-identifier that ends with @scheme[_body] stands
|
||||
for a sub-form that is expanded in an
|
||||
internal-definition context (see
|
||||
@secref["mz:intdef-body"]).}
|
||||
|
||||
}} }
|
||||
|
||||
|
@ -149,21 +148,21 @@ according to their order in the application form.
|
|||
|
||||
@guideintro["guide:lambda"]{procedure expressions}
|
||||
|
||||
@defform/subs[(lambda formals* . body)
|
||||
@defform/subs[(lambda gen-formals body ...+)
|
||||
([formals (id ...)
|
||||
(id ...+ . rest-id)
|
||||
rest-id]
|
||||
[formals* formals
|
||||
(formal-arg ...)
|
||||
(formal-arg ...+ . rest-id)]
|
||||
[formal-arg id
|
||||
[id default-expr]
|
||||
(code:line keyword id)
|
||||
(code:line keyword [id default-expr])])]{
|
||||
[gen-formals formals
|
||||
(arg ...)
|
||||
(arg ...+ . rest-id)]
|
||||
[arg id
|
||||
[id default-expr]
|
||||
(code:line keyword id)
|
||||
(code:line keyword [id default-expr])])]{
|
||||
|
||||
Produces a procedure. The @scheme[formals*] determines the number of
|
||||
Produces a procedure. The @scheme[gen-formals] determines the number of
|
||||
arguments that the procedure accepts. It is either a simple
|
||||
@scheme[_formals], or one of the extended forms.
|
||||
@scheme[formals], or one of the extended forms.
|
||||
|
||||
A simple @scheme[_formals] has one of the following three forms:
|
||||
|
||||
|
@ -182,11 +181,11 @@ A simple @scheme[_formals] has one of the following three forms:
|
|||
arguments. All arguments are placed into a list that is
|
||||
associated with @scheme[rest-id].}
|
||||
|
||||
Besides the three @scheme[_formals] forms, a @scheme[formals*] can be
|
||||
a sequence of @scheme[_formal-arg]s optionally ending with a
|
||||
Besides the three @scheme[formals] forms, a @scheme[gen-formals] can be
|
||||
a sequence of @scheme[arg]s optionally ending with a
|
||||
@scheme[rest-id]:
|
||||
|
||||
@specsubform[(formal-arg ...)]{ Each @scheme[formal-arg] has the following
|
||||
@specsubform[(arg ...)]{ Each @scheme[arg] has the following
|
||||
four forms:
|
||||
|
||||
@specsubform[id]{Adds one to both the minimum and maximum
|
||||
|
@ -199,7 +198,7 @@ a sequence of @scheme[_formal-arg]s optionally ending with a
|
|||
@scheme[id] is associated with an actual argument by position,
|
||||
and if no such argument is provided, the @scheme[default-expr]
|
||||
is evaluated to produce a value associated with @scheme[id].
|
||||
No @scheme[formal-arg] with a @scheme[default-expr] can appear
|
||||
No @scheme[arg] with a @scheme[default-expr] can appear
|
||||
before an @scheme[id] without a @scheme[default-expr] and
|
||||
without a @scheme[keyword].}
|
||||
|
||||
|
@ -215,41 +214,40 @@ a sequence of @scheme[_formal-arg]s optionally ending with a
|
|||
otherwise, the @scheme[default-expr] is evaluated to obtain a
|
||||
value to associate with @scheme[id].}
|
||||
|
||||
The position of a @scheme[_keyword] @scheme[formal-arg] in
|
||||
@scheme[formals*] does not matter, but each specified
|
||||
The position of a @scheme[_keyword] @scheme[arg] in
|
||||
@scheme[gen-formals] does not matter, but each specified
|
||||
@scheme[_keyword] must be distinct.}
|
||||
|
||||
@specsubform[(formal-arg ...+ . rest-id)]{ Like the previous case, but
|
||||
@specsubform[(arg ...+ . rest-id)]{ Like the previous case, but
|
||||
the procedure accepts any number of non-keyword arguments
|
||||
beyond its minimum number of arguments. When more arguments are
|
||||
provided than non-@scheme[_keyword] arguments among the
|
||||
@scheme[formal-arg]s, the extra arguments are placed into a
|
||||
@scheme[arg]s, the extra arguments are placed into a
|
||||
list that is associated to @scheme[rest-id].}
|
||||
|
||||
The @scheme[formals*] identifiers are bound in the @scheme[body]. (See
|
||||
@secref["mz:intdef-body"] for information on @scheme[body] forms.) When
|
||||
The @scheme[gen-formals] identifiers are bound in the @scheme[body]s. When
|
||||
the procedure is applied, a new location is created for each
|
||||
identifier, and the location is filled with the associated argument
|
||||
value.
|
||||
|
||||
If any identifier appears in @scheme[body] that is not one of the
|
||||
identifiers in @scheme[formals*], then it refers to the same location
|
||||
If any identifier appears in the @scheme[body]s that is not one of the
|
||||
identifiers in @scheme[gen-formals], then it refers to the same location
|
||||
that it would if it appeared in place of the @scheme[lambda]
|
||||
expression. (In other words, variable reference is lexically scoped.)
|
||||
|
||||
When multiple identifiers appear in a @scheme[formals*], they must be
|
||||
When multiple identifiers appear in a @scheme[gen-formals], they must be
|
||||
distinct according to @scheme[bound-identifier=?].
|
||||
|
||||
If the procedure procedure by @scheme[lambda] is applied to fewer or
|
||||
more arguments than it accepts, the @exnraise[exn:fail:contract]. If
|
||||
@scheme[formals*] includes @scheme[keyword]s and an application
|
||||
@scheme[gen-formals] includes @scheme[keyword]s and an application
|
||||
includes too few arguments before the keyword section, the same
|
||||
keyword in multiple positions, or a keyword that is not among the
|
||||
@scheme[formals*] @scheme[_keyword]s, then the
|
||||
@scheme[gen-formals] @scheme[_keyword]s, then the
|
||||
@exnraise[exn:fail:contract].
|
||||
|
||||
The last expression in @scheme[body] is in tail position with respect
|
||||
to the procedure body.
|
||||
The last @scheme[body] expression is in tail position with respect to
|
||||
the procedure body.
|
||||
|
||||
@examples[
|
||||
((lambda (x) x) 10)
|
||||
|
@ -260,9 +258,9 @@ to the procedure body.
|
|||
(f #:arg 2 1)))
|
||||
]}
|
||||
|
||||
@defform[(case-lambda [formals . body] ...)]{
|
||||
@defform[(case-lambda [formals body ...+] ...)]{
|
||||
|
||||
Produces a procedure. Each @scheme[[forms body]]
|
||||
Produces a procedure. Each @scheme[[forms body ...+]]
|
||||
clause is analogous to a single @scheme[lambda] procedure; applying
|
||||
the @scheme[case-lambda]-generated procedure is the same as applying a
|
||||
procedure that corresponds to one of the clauses---the first procedure
|
||||
|
@ -271,7 +269,7 @@ procedure accepts the given number of arguments, the
|
|||
@exnraise[exn:fail:contract].
|
||||
|
||||
Note that a @scheme[case-lambda] clause supports only
|
||||
@scheme[formals], not the more general @scheme[_formals*] of
|
||||
@scheme[formals], not the more general @scheme[_gen-formals] of
|
||||
@scheme[lambda]. That is, @scheme[case-lambda] does not directly
|
||||
support keyword and optional arguments.
|
||||
|
||||
|
@ -290,14 +288,13 @@ support keyword and optional arguments.
|
|||
@;------------------------------------------------------------------------
|
||||
@section{Local Binding: @scheme[let], @scheme[let*], and @scheme[letrec]}
|
||||
|
||||
@defform*[[(let ([id val-expr] ...) . body)
|
||||
(let proc-id ([id init-expr] ...) . body)]]{
|
||||
@defform*[[(let ([id val-expr] ...) body ...+)
|
||||
(let proc-id ([id init-expr] ...) body ...+)]]{
|
||||
|
||||
The first form evaluates the @scheme[val-expr]s left-to-right, creates
|
||||
a new location for each @scheme[id], and places the values into the
|
||||
locations. It then evaluates the @scheme[body], in which the
|
||||
@scheme[id]s are bound. (See @secref["mz:intdef-body"] for information
|
||||
on @scheme[body] forms.) The last expression in @scheme[body] is in
|
||||
locations. It then evaluates the @scheme[body]s, in which the
|
||||
@scheme[id]s are bound. The last @scheme[body] expression is in
|
||||
tail position with respect to the @scheme[let] form. The @scheme[id]s
|
||||
must be distinct according to @scheme[bound-identifier=?].
|
||||
|
||||
|
@ -311,8 +308,8 @@ must be distinct according to @scheme[bound-identifier=?].
|
|||
|
||||
The second form evaluates the @scheme[init-expr]s; the resulting
|
||||
values become arguments in an application of a procedure
|
||||
@scheme[(lambda (id ...) . body)], where @scheme[proc-id] is bound
|
||||
within @scheme[body] to the procedure itself.}
|
||||
@scheme[(lambda (id ...) body ...+)], where @scheme[proc-id] is bound
|
||||
within the @scheme[body]s to the procedure itself.}
|
||||
|
||||
@examples[
|
||||
(let fac ([n 10])
|
||||
|
@ -321,12 +318,12 @@ within @scheme[body] to the procedure itself.}
|
|||
(* n (fac (sub1 n)))))
|
||||
]
|
||||
|
||||
@defform[(let* ([id val-expr] ...) . body)]{
|
||||
@defform[(let* ([id val-expr] ...) body ...+)]{
|
||||
|
||||
Similar to @scheme[let], but evaluates the @scheme[val-expr]s one by
|
||||
one, creating a location for each @scheme[id] as soon as the value is
|
||||
availablek. The @scheme[id]s are bound in the remaining @scheme[val-expr]s
|
||||
as well as the @scheme[body], and the @scheme[id]s need not be
|
||||
as well as the @scheme[body]s, and the @scheme[id]s need not be
|
||||
distinct.
|
||||
|
||||
@examples[
|
||||
|
@ -335,12 +332,12 @@ distinct.
|
|||
(list y x))
|
||||
]}
|
||||
|
||||
@defform[(letrec ([id val-expr] ...) . body)]{
|
||||
@defform[(letrec ([id val-expr] ...) body ...+)]{
|
||||
|
||||
Similar to @scheme[let], but the locations for all @scheme[id]s are
|
||||
created first and filled with @|undefined-const|, and all
|
||||
@scheme[id]s are bound in all @scheme[val-expr]s as well as
|
||||
@scheme[body]. The @scheme[id]s must be distinct according to
|
||||
@scheme[id]s are bound in all @scheme[val-expr]s as well as the
|
||||
@scheme[body]s. The @scheme[id]s must be distinct according to
|
||||
@scheme[bound-identifier=?].
|
||||
|
||||
@examples[
|
||||
|
@ -353,21 +350,21 @@ created first and filled with @|undefined-const|, and all
|
|||
(is-odd? 11))
|
||||
]}
|
||||
|
||||
@defform[(let-values ([(id ...) val-expr] ...) . body)]{ Like
|
||||
@defform[(let-values ([(id ...) val-expr] ...) body ...+)]{ Like
|
||||
@scheme[let], except that each @scheme[val-expr] must produce as many
|
||||
values as corresponding @scheme[id]s. A separate location is created
|
||||
for each @scheme[id], all of which are bound in the @scheme[body].
|
||||
for each @scheme[id], all of which are bound in the @scheme[body]s.
|
||||
|
||||
@examples[
|
||||
(let-values ([(x y) (quotient/remainder 10 3)])
|
||||
(list y x))
|
||||
]}
|
||||
|
||||
@defform[(let*-values ([(id ...) val-expr] ...) . body)]{ Like
|
||||
@defform[(let*-values ([(id ...) val-expr] ...) body ...+)]{ Like
|
||||
@scheme[let*], except that each @scheme[val-expr] must produce as many
|
||||
values as corresponding @scheme[id]s. A separate location is created
|
||||
for each @scheme[id], all of which are bound in the later
|
||||
@scheme[val-expr]s and in the @scheme[body].
|
||||
@scheme[val-expr]s and in the @scheme[body]s.
|
||||
|
||||
@examples[
|
||||
(let*-values ([(x y) (quotient/remainder 10 3)]
|
||||
|
@ -375,12 +372,12 @@ for each @scheme[id], all of which are bound in the later
|
|||
z)
|
||||
]}
|
||||
|
||||
@defform[(letrec-values ([(id ...) val-expr] ...) . body)]{ Like
|
||||
@defform[(letrec-values ([(id ...) val-expr] ...) body ...+)]{ Like
|
||||
@scheme[letrec], except that each @scheme[val-expr] must produce as
|
||||
many values as corresponding @scheme[id]s. A separate location is
|
||||
created for each @scheme[id], all of which are initialized to
|
||||
@|undefined-const| and bound in all @scheme[val-expr]s
|
||||
and in the @scheme[body].
|
||||
and in the @scheme[body]s.
|
||||
|
||||
@examples[
|
||||
(letrec-values ([(is-even? is-odd?)
|
||||
|
|
Loading…
Reference in New Issue
Block a user