some doc edits related to sequences and for
svn: r6582
This commit is contained in:
parent
05607ad661
commit
ab492c3f7c
|
@ -16,15 +16,15 @@ Variants of @scheme[for] accumulate iteration results in different
|
|||
ways, but they all have the same syntactic shape. Simplifying, for
|
||||
now, the syntax of @scheme[for] is
|
||||
|
||||
@schemeblock[
|
||||
(for ([_id _sequence-expr])
|
||||
_body-expr)
|
||||
]
|
||||
@specform[
|
||||
(for ([id sequence-expr] ...)
|
||||
body ...+)
|
||||
]{}
|
||||
|
||||
A @scheme[for] loop iterates through the sequence produced by the
|
||||
@scheme[_sequence-expr]. For each element of the sequence,
|
||||
@scheme[for] binds the element to @scheme[_id], and then it evaluates
|
||||
the @scheme[_body-expr] for side effects.
|
||||
the @scheme[_body]s for side effects.
|
||||
|
||||
@examples[
|
||||
(for ([i '(1 2 3)])
|
||||
|
@ -34,8 +34,8 @@ the @scheme[_body-expr] for side effects.
|
|||
]
|
||||
|
||||
The @scheme[for/list] variant of @scheme[for] is more Scheme-like. It
|
||||
accumulates @scheme[_body-expr] results into a list, instead of
|
||||
evaluating @scheme[_body-expr] only for side effects. In more
|
||||
accumulates @scheme[_body] results into a list, instead of
|
||||
evaluating @scheme[_body] only for side effects. In more
|
||||
technical terms, @scheme[for/list] implements a @defterm{list
|
||||
comprehension}.
|
||||
|
||||
|
@ -49,14 +49,14 @@ comprehension}.
|
|||
The full syntax of @scheme[for] accomodates multiple sequences to
|
||||
iterate in parallel, and the @scheme[for*] variant nests the
|
||||
iterations instead of running them in parallel. More variants of
|
||||
@scheme[for] and @scheme[for*] accumulate @scheme[_body-expr] results
|
||||
@scheme[for] and @scheme[for*] accumulate @scheme[_body] results
|
||||
in different ways. In all of these variants, predicates that prune
|
||||
iterations can be included along with bindings.
|
||||
|
||||
Before details on the variations of @scheme[for], though, it's best to
|
||||
see the kinds of sequence generators that make interesting examples.
|
||||
|
||||
@section{Sequence Constructors}
|
||||
@section[#:tag "guide:sequences"]{Sequence Constructors}
|
||||
|
||||
The @scheme[in-range] procedure generates a sequence of numbers, given
|
||||
an optional starting number (which defaults to @scheme[0]), a number
|
||||
|
@ -80,7 +80,8 @@ The @scheme[in-naturals] procedure is similar, except that the
|
|||
starting number must be an exact non-negative integer (which defaults
|
||||
to @scheme[0]), the step is always @scheme[1], and there is no upper
|
||||
limit. A @scheme[for] loop using just @scheme[in-naturals] will never
|
||||
terminate.
|
||||
terminate unless a body expression raises an exception or otherwise
|
||||
escapes.
|
||||
|
||||
@examples[
|
||||
(for ([i (in-naturals)])
|
||||
|
@ -104,9 +105,9 @@ true.
|
|||
Sequence constructors like @scheme[in-list], @scheme[in-vector] and
|
||||
@scheme[in-string] simply make explicit the use of a list, vector, or
|
||||
string as a sequence. Since they raise an exception when given the
|
||||
wrong kind of value and otherwise avoid a run-time dispatch to
|
||||
determine the sequence type, they enable more efficient code
|
||||
generation; see @secref["for-performance"] for more information.
|
||||
wrong kind of value, and since they otherwise avoid a run-time
|
||||
dispatch to determine the sequence type, they enable more efficient
|
||||
code generation; see @secref["for-performance"] for more information.
|
||||
|
||||
@examples[
|
||||
(for ([i (in-string "abc")])
|
||||
|
@ -115,19 +116,18 @@ generation; see @secref["for-performance"] for more information.
|
|||
(display i))
|
||||
]
|
||||
|
||||
@refdetails["mz:sequences"]{sequences}
|
||||
|
||||
@section{@scheme[for] and @scheme[for*]}
|
||||
|
||||
The full syntax of @scheme[for] is
|
||||
A more complete syntax of @scheme[for] is
|
||||
|
||||
@schemeblock[
|
||||
(for (_clause ...)
|
||||
_body-expr ...+)
|
||||
code:blank
|
||||
#, @where-is-one-of[@scheme[_clause]]
|
||||
[_id _sequence-expr]
|
||||
#:when _boolean-expr
|
||||
]
|
||||
@specform/subs[
|
||||
(for (clause ...)
|
||||
body ...+)
|
||||
([clause [id sequence-expr]
|
||||
(code:line #:when boolean-expr)])
|
||||
]{}
|
||||
|
||||
When multiple @scheme[[_id _sequence-expr]] clauses are provided
|
||||
in a @scheme[for] form, the corresponding sequences are traversed in
|
||||
|
@ -163,7 +163,7 @@ Thus, @scheme[for*] is a shorthand for nested @scheme[for]s in the
|
|||
same way that @scheme[let*] is a shorthand for nested @scheme[let]s.
|
||||
|
||||
The @scheme[#:when _boolean-expr] form of a @scheme[_clause] is
|
||||
another shorthand. It allows the @scheme[_body-expr]s to evaluate only
|
||||
another shorthand. It allows the @scheme[_body]s to evaluate only
|
||||
when the @scheme[_boolean-expr] produces a true value:
|
||||
|
||||
@interaction[
|
||||
|
@ -191,7 +191,7 @@ mutually nested, instead of in parallel, even with @scheme[for].
|
|||
@section{@scheme[for/list] and @scheme[for*/list]}
|
||||
|
||||
The @scheme[for/list] form, which has the same syntax as @scheme[for],
|
||||
evaluates the @scheme[_body-expr]s to obtain values that go into a
|
||||
evaluates the @scheme[_body]s to obtain values that go into a
|
||||
newly constructed list:
|
||||
|
||||
@interaction[
|
||||
|
@ -201,7 +201,7 @@ newly constructed list:
|
|||
]
|
||||
|
||||
A @scheme[#:when] clause in a @scheme[for-list] form prunes the result
|
||||
list along with evaluations of the @scheme[_body-expr]s:
|
||||
list along with evaluations of the @scheme[_body]s:
|
||||
|
||||
@interaction[
|
||||
(for/list ([i (in-naturals 1)]
|
||||
|
@ -255,7 +255,7 @@ same facility with nested iterations.
|
|||
@section{@scheme[for/first] and @scheme[for/last]}
|
||||
|
||||
The @scheme[for/first] form returns the result of the first time that
|
||||
the @scheme[_body-expr]s are evaluated, skipping further iterations.
|
||||
the @scheme[_body]s are evaluated, skipping further iterations.
|
||||
This form is most useful with a @scheme[#:when] clause.
|
||||
|
||||
@interaction[
|
||||
|
@ -264,7 +264,7 @@ This form is most useful with a @scheme[#:when] clause.
|
|||
chapter)
|
||||
]
|
||||
|
||||
If the @scheme[_body-expr]s are evaluated zero time, then the result
|
||||
If the @scheme[_body]s are evaluated zero time, then the result
|
||||
is @scheme[#f].
|
||||
|
||||
The @scheme[for/last] form runs all iterations, returning the value of
|
||||
|
@ -301,15 +301,15 @@ beginning:
|
|||
@schemeblock[
|
||||
(for/fold ([_accum-id _init-expr] ...)
|
||||
(_clause ...)
|
||||
_body-expr ...+)
|
||||
_body ...+)
|
||||
]
|
||||
|
||||
In the simple case, only one @scheme[[_accum-id _init-expr]] is
|
||||
provided, and the result of the @scheme[for/fold] is the final value
|
||||
for @scheme[_accum-id], which starts out with the value of
|
||||
@scheme[_init-expr]. In the @scheme[_clause]s and
|
||||
@scheme[_body-expr]s, @scheme[_accum-id] can be referenced to gets its
|
||||
current value, and the last @scheme[_body-expr] provides the value of
|
||||
@scheme[_body]s, @scheme[_accum-id] can be referenced to gets its
|
||||
current value, and the last @scheme[_body] provides the value of
|
||||
@scheme[_accum-id] for the netx iteration.
|
||||
|
||||
@examples[
|
||||
|
@ -325,7 +325,7 @@ current value, and the last @scheme[_body-expr] provides the value of
|
|||
]
|
||||
|
||||
When multiple @scheme[_accum-id]s are specified, then the last
|
||||
@scheme[_body-expr] must produce multiple values, one for each
|
||||
@scheme[_body] must produce multiple values, one for each
|
||||
@scheme[_accum-id]. The @scheme[for/fold] expression itself produces
|
||||
multiple values for the results.
|
||||
|
||||
|
@ -350,6 +350,11 @@ In the same way that @scheme[let-values] binds multiple results to
|
|||
multiple identifiers, @scheme[for] can bind multiple sequence elements
|
||||
to multiple iteration identifiers:
|
||||
|
||||
@margin-note{While @scheme[let] must be changed to @scheme[let-values]
|
||||
to bind multiple identifier, @scheme[for] simply allows a
|
||||
parenthesized list of identifiers instead of a single
|
||||
identifier in any clause.}
|
||||
|
||||
@interaction[
|
||||
(for ([(k v) #hash(("apple" . 1) ("banana" . 3))])
|
||||
(printf "~a count: ~a\n" k v))
|
||||
|
@ -431,7 +436,7 @@ fast-parallel-seq (in-parallel fast-seq ...)
|
|||
The grammars above are not complete, because the set of syntactic
|
||||
patterns that provide good performance is extensible, just like the
|
||||
set of sequence values. The documentation for a sequence constructor
|
||||
should indicate the performance impliciations of using it directly in
|
||||
should indicate the performance benefits of using it directly in
|
||||
a @scheme[for] @scheme[_clause].
|
||||
|
||||
@refdetails["mz:for"]{iterations and comprehensions}
|
||||
|
|
|
@ -19,6 +19,10 @@ Two byte strings are @scheme[eq?] when mutating one would mutate the
|
|||
other. Two byte strings are @scheme[eqv?] and @scheme[equal?] when
|
||||
they have the same length and contain the same sequence of bytes.
|
||||
|
||||
A byte string can be used as a single-valued sequence (see
|
||||
@secref["mz:sequences"]). The bytes of the string serve as elements
|
||||
of the sequence. See also @scheme[in-bytes].
|
||||
|
||||
See also: @scheme[immutable].
|
||||
|
||||
@; ----------------------------------------
|
||||
|
|
|
@ -96,6 +96,13 @@ ephemeron key (see @secref["mz:ephemerons"]).
|
|||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "mz:pairs"]{Pairs and Lists}
|
||||
|
||||
A list can be used as a single-valued sequence (see
|
||||
@secref["mz:sequences"]). The elements of the list serve as elements
|
||||
of the sequence. See also @scheme[in-list].
|
||||
|
||||
@; ----------------------------------------
|
||||
@subsection{Pair Constructors, Selectors, and Mutators}
|
||||
|
||||
@defproc[(cons [a any/c] [d any/c]) pair?]{Returns a pair whose first
|
||||
element is @scheme[a] and second element is @scheme[d].}
|
||||
|
||||
|
@ -193,12 +200,28 @@ If the @scheme[lst]s are empty, then @scheme[#f] is returned.}
|
|||
@; ------------------------------------------------------------
|
||||
@section[#:tag "mz:vectors"]{Vectors}
|
||||
|
||||
A vector can be used as a single-valued sequence (see
|
||||
@secref["mz:sequences"]). The elements of the vector serve as elements
|
||||
of the sequence. See also @scheme[in-vector].
|
||||
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section[#:tag "mz:boxes"]{Boxes}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "mz:hashtables"]{Hash Tables}
|
||||
|
||||
A hash table can be used as a two-valued sequence (see
|
||||
@secref["mz:sequences"]). The keys and values of the hash table serve
|
||||
as elements of the sequence (i.e., each element is a key and its
|
||||
associated value). If a mapping is added to or removed from the hash
|
||||
table during iteration, then an iteration step may fail with
|
||||
@scheme[exn:fail:contract], or the iteration may skip or duplicate
|
||||
keys and values. See also @scheme[in-hash-table],
|
||||
@scheme[in-hash-table-keys], @scheme[in-hash-table-values], and
|
||||
@scheme[in-hash-table-pairs].
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@include-section["sequences.scrbl"]
|
||||
|
||||
|
|
|
@ -1,29 +1,39 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
@require-for-syntax[mzscheme]
|
||||
|
||||
@define-syntax[speed
|
||||
(syntax-rules ()
|
||||
[(_ id what)
|
||||
@t{A @scheme[id] application can provide better performance for
|
||||
@elem[what]
|
||||
iteration when it appears directly in a @scheme[for] clause.}])]
|
||||
|
||||
@title[#:tag "mz:sequences"]{Sequences}
|
||||
|
||||
@guideintro["guide:sequences"]{sequences}
|
||||
|
||||
A @pidefterm{sequence} encapsulates an ordered stream of values. The
|
||||
elements of a sequence can be extracted with one of the @scheme[for]
|
||||
syntactic forms or with the procedures returned by
|
||||
@scheme[generate-sequence].
|
||||
|
||||
The datatype overlaps with many other datatypes, because it includes
|
||||
the following:
|
||||
The sequence datatype overlaps with many other datatypes. Among
|
||||
built-in datatypes, the sequence datatype includes the following:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{lists; see @secref["mz:pairs"]}
|
||||
@item{lists (see @secref["mz:pairs"])}
|
||||
|
||||
@item{vectors; see @secref["mz:vectors"]}
|
||||
@item{vectors (see @secref["mz:vectors"])}
|
||||
|
||||
@item{hash tables; see @secref["mz:hashtables"]}
|
||||
@item{hash tables (see @secref["mz:hashtables"])}
|
||||
|
||||
@item{strings; see @secref["mz:strings"]}
|
||||
@item{strings (see @secref["mz:strings"])}
|
||||
|
||||
@item{byte strings; see @secref["mz:bytestrings"]}
|
||||
@item{byte strings (see @secref["mz:bytestrings"])}
|
||||
|
||||
@item{input ports; see @secref["mz:input-ports"]}
|
||||
@item{input ports (see @secref["mz:input-ports"])}
|
||||
|
||||
}
|
||||
|
||||
|
@ -55,24 +65,29 @@ case @scheme[(in-range end)] is equivalent to @scheme[(in-range 0 end
|
|||
successive element is generated by adding @scheme[step] to the
|
||||
previous element. The sequence starts before an element that would be
|
||||
greater or equal to @scheme[end] if @scheme[step] is non-negative, or
|
||||
less or equal to @scheme[end] if @scheme[step] is negative.}
|
||||
less or equal to @scheme[end] if @scheme[step] is negative.
|
||||
@speed[in-range "number"]}
|
||||
|
||||
@defproc[(in-naturals [start exact-nonnegative-integer? 0]) sequence?]{
|
||||
Returns an infinite sequence of exact integers starting with
|
||||
@scheme[start], where each element is one more than the preceeding
|
||||
element.}
|
||||
element. @speed[in-naturals "integer"]}
|
||||
|
||||
@defproc[(in-list [lst list?]) sequence?]{
|
||||
Returns a sequence equivalent to @scheme[lst].}
|
||||
Returns a sequence equivalent to @scheme[lst].
|
||||
@speed[in-list "list"]}
|
||||
|
||||
@defproc[(in-vector [vec vector?]) sequence?]{
|
||||
Returns a sequence equivalent to @scheme[vec].}
|
||||
Returns a sequence equivalent to @scheme[vec].
|
||||
@speed[in-vector "vector"]}
|
||||
|
||||
@defproc[(in-string [str string?]) sequence?]{
|
||||
Returns a sequence equivalent to @scheme[str].}
|
||||
Returns a sequence equivalent to @scheme[str].
|
||||
@speed[in-string "string"]}
|
||||
|
||||
@defproc[(in-bytes [bstr bytes?]) sequence?]{
|
||||
Returns a sequence equivalent to @scheme[bstr].}
|
||||
Returns a sequence equivalent to @scheme[bstr].
|
||||
@speed[in-bytes "byte string"]}
|
||||
|
||||
@defproc[(in-input-port-bytes [inp input-port?]) sequence?]{
|
||||
Returns a sequence equivalent to @scheme[inp].}
|
||||
|
|
|
@ -19,6 +19,10 @@ Two strings are @scheme[eq?] when mutating one would mutate the other.
|
|||
Two strings are @scheme[eqv?] and @scheme[equal?] when they have the
|
||||
same length and contain the same sequence of characters.
|
||||
|
||||
A string can be used as a single-valued sequence (see
|
||||
@secref["mz:sequences"]). The characters of the string serve as elements
|
||||
of the sequence. See also @scheme[in-string].
|
||||
|
||||
See also: @scheme[immutable], @scheme[symbol->string],
|
||||
@scheme[bytes->string/utf-8].
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user