add #:unless' to
for'
This commit is contained in:
parent
bbd98528ba
commit
460504c852
|
@ -1224,6 +1224,18 @@
|
|||
(#:when expr . rest) . body)
|
||||
#'(frm [orig-stx nested? #t binds] ([fold-var fold-init] ...)
|
||||
(#:when expr . rest) . body)]
|
||||
;; Negative guard case, no pending emits:
|
||||
[(_ [orig-stx nested? #f ()] ([fold-var fold-init] ...) (#:unless expr . rest) . body)
|
||||
#'(let ([fold-var fold-init] ...)
|
||||
(if expr
|
||||
(values* fold-var ...)
|
||||
(for/foldX/derived [orig-stx nested? #f ()]
|
||||
([fold-var fold-var] ...) rest . body)))]
|
||||
;; Negative guard case, pending emits need to be flushed first
|
||||
[(frm [orig-stx nested? #f binds] ([fold-var fold-init] ...)
|
||||
(#:unless expr . rest) . body)
|
||||
#'(frm [orig-stx nested? #t binds] ([fold-var fold-init] ...)
|
||||
(#:unless expr . rest) . body)]
|
||||
;; Convert single-value form to multi-value form:
|
||||
[(_ [orig-stx nested? #f binds] fold-bind ([id rhs] . rest) . body)
|
||||
(identifier? #'id)
|
||||
|
|
|
@ -132,7 +132,8 @@ A more complete syntax of @racket[for] is
|
|||
(for (clause ...)
|
||||
body ...+)
|
||||
([clause [id sequence-expr]
|
||||
(code:line #:when boolean-expr)])
|
||||
(code:line #:when boolean-expr)
|
||||
(code:line #:unless boolean-expr)])
|
||||
]{}
|
||||
|
||||
When multiple @racket[[_id _sequence-expr]] clauses are provided
|
||||
|
@ -194,6 +195,10 @@ mutually nested, instead of in parallel, even with @racket[for].
|
|||
(printf "~a Chapter ~a. ~a\n" book i chapter))
|
||||
]
|
||||
|
||||
An @racket[#:unless] clause is analogus to a @racket[#:when] clause, but
|
||||
the @racket[_body]s evaluate only when the @racket[_boolean-expr]
|
||||
produces a false value.
|
||||
|
||||
@section{@racket[for/list] and @racket[for*/list]}
|
||||
|
||||
The @racket[for/list] form, which has the same syntax as @racket[for],
|
||||
|
|
|
@ -14,7 +14,8 @@ The @scheme[for] iteration forms are based on SRFI-42
|
|||
@defform/subs[(for (for-clause ...) body ...+)
|
||||
([for-clause [id seq-expr]
|
||||
[(id ...) seq-expr]
|
||||
(code:line #:when guard-expr)])
|
||||
(code:line #:when guard-expr)
|
||||
(code:line #:unless guard-expr)])
|
||||
#:contracts ([seq-expr sequence?])]{
|
||||
|
||||
Iteratively evaluates @scheme[body]. The @scheme[for-clause]s
|
||||
|
@ -45,7 +46,7 @@ a sequence containing a single element. All of the @scheme[id]s must
|
|||
be distinct according to @scheme[bound-identifier=?].
|
||||
|
||||
If any @scheme[for-clause] has the form @scheme[#:when guard-expr],
|
||||
then only the preceding clauses (containing no @scheme[#:when])
|
||||
then only the preceding clauses (containing no @scheme[#:when] or @scheme[#:unless])
|
||||
determine iteration as above, and the @scheme[body] is effectively
|
||||
wrapped as
|
||||
|
||||
|
@ -54,7 +55,9 @@ wrapped as
|
|||
(for (for-clause ...) body ...+))
|
||||
]
|
||||
|
||||
using the remaining @scheme[for-clauses].
|
||||
using the remaining @scheme[for-clauses]. A @scheme[for-clause] of
|
||||
the form @scheme[#:unless guard-expr] corresponds to the same transformation
|
||||
with @racket[unless] in place of @racket[when].
|
||||
|
||||
@examples[
|
||||
(for ([i '(1 2 3)]
|
||||
|
@ -74,6 +77,9 @@ using the remaining @scheme[for-clauses].
|
|||
@scheme[for], but that the last expression in the @scheme[body]s must
|
||||
produce a single value, and the result of the @scheme[for/list]
|
||||
expression is a list of the results in order.
|
||||
When evaluation of a @scheme[body] is skipped due to a @racket[#:when]
|
||||
or @racket[#:unless] clause, the result list includes no corresponding
|
||||
element.
|
||||
|
||||
@examples[
|
||||
(for/list ([i '(1 2 3)]
|
||||
|
@ -89,9 +95,8 @@ expression is a list of the results in order.
|
|||
@defform*[((for/vector (for-clause ...) body ...+)
|
||||
(for/vector #:length length-expr (for-clause ...) body ...+))]{
|
||||
|
||||
Iterates like @scheme[for], but the last expression
|
||||
in the @scheme[body]s must produce a single value, which is placed in
|
||||
the corresponding slot of a vector. If the optional @scheme[#:length]
|
||||
Iterates like @scheme[for/list], but the result are accumulated into
|
||||
a vector instead of a list. If the optional @scheme[#:length]
|
||||
form is used, then @scheme[length-expr] must evaluate to an
|
||||
@scheme[exact-nonnegative-integer?], and the result vector is
|
||||
constructed with this length. In this case, the iteration can be
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
(test (map (lambda (x) #t) `seq) 'gen (for*/list ([i gen][b '(#t)]) b))
|
||||
(test (append `seq `seq) 'gen (for*/list ([b '(#f #t)][i gen]) i))
|
||||
(test (append `seq `seq) 'gen (for/list ([b '(#f #t)] #:when #t [i gen]) i))
|
||||
(test (append `seq `seq) 'gen (for/list ([b '(#t #t #f)] #:when b [i gen]) i))
|
||||
(test (append `seq `seq) 'gen (for/list ([b '(#f #t)] #:unless #f [i gen]) i))
|
||||
(test (append `seq `seq) 'gen (for/list ([b '(#f #f #t)] #:unless b [i gen]) i))
|
||||
(test `seq 'gen (let ([g gen]) (for/list ([i g]) i)))
|
||||
(test `seq 'gen (let ([r null])
|
||||
(for ([i gen]) (set! r (cons i r)))
|
||||
|
|
Loading…
Reference in New Issue
Block a user