diff --git a/pkgs/racket-doc/scribblings/reference/for.scrbl b/pkgs/racket-doc/scribblings/reference/for.scrbl index 73412c50d4..1a838c1618 100644 --- a/pkgs/racket-doc/scribblings/reference/for.scrbl +++ b/pkgs/racket-doc/scribblings/reference/for.scrbl @@ -374,19 +374,19 @@ terminates, if a @racket[result-expr] is provided then the result of the ] The binding and evaluation order of @racket[accum-id]s and -@racket[init-expr]s does not follow the textual, left-to-right order -relative to the @racket[for-clause]s . Instead, the sequence -expressions in @racket[for-clause]s that determine the outermost -iteration are evaluated first, the associated identifiers are bound, -and then the @racket[init-expr]s are evaluated and the -@racket[accum-id]s are bound. One consequence is that the -@racket[accum-id]s are not bound in @racket[for-clause]s for the -outermost initialization. Another consequence is that when a -@racket[accum-id] is used as a @racket[for-clause] binding for the -outermost iteration, the @racket[for-clause] binding is shadowed in -the loop body (even though, syntactically, a @racket[for-clause] is -closer to the body). A fresh variable for each @racket[accum-id] (at a -fresh location) is bound to in each nested iteration created by a +@racket[init-expr]s do not completely follow the textual, +left-to-right order relative to the @racket[for-clause]s. Instead, the +sequence expressions in @racket[for-clause]s that determine the +outermost iteration are evaluated first, then the @racket[init-expr]s +are evaluated and the @racket[accum-id]s are bound, and finally the +outermost iteration's identifiers are bound. One consequence is that +the @racket[accum-id]s are not bound in @racket[for-clause]s for the +outermost initialization. At the same time, when a @racket[accum-id] +is used as a @racket[for-clause] binding for the outermost iteration, +the @racket[for-clause] binding shadows the @racket[accum-id] binding +in the loop body (which is what you would expect syntactically). +A fresh variable for each @racket[accum-id] (at a +fresh location) is bound in each nested iteration that is created by a later group for @racket[for-clause]s (after a @racket[#:when] or @racket[#:unless], for example). diff --git a/pkgs/racket-test-core/tests/racket/for.rktl b/pkgs/racket-test-core/tests/racket/for.rktl index abe47bffb4..b8bafa69fa 100644 --- a/pkgs/racket-test-core/tests/racket/for.rktl +++ b/pkgs/racket-test-core/tests/racket/for.rktl @@ -461,6 +461,25 @@ (test 13 next) (test #f more?)) +(test 1 'in-value-bind-correctly (for/fold ([x #f]) + ([x (in-value 1)]) + x)) +(test 2 'in-value-bind-correctly (for/fold ([x #f]) + ([x (values (in-value 2))]) + x)) + +(let ([x 'out] + [prints '()]) + (for/fold ([x (begin + (set! prints (cons (list 'top x) prints)) + 'top)]) + ([x (in-list (begin + (set! prints (cons (list 'rhs x) prints)) + (list 1 2 3)))]) + (set! prints (cons x prints)) + x) + (test '(3 2 1 (top out) (rhs out)) values prints)) + ;; check ranges on `in-vector', especially as a value (test '() 'in-empty-vector (let ([v (in-vector '#())]) (for/list ([e v]) e))) (test '() 'in-empty-vector (let ([v (in-vector '#() 0)]) (for/list ([e v]) e))) diff --git a/racket/collects/racket/private/for.rkt b/racket/collects/racket/private/for.rkt index 4808da0f20..216fefec34 100644 --- a/racket/collects/racket/private/for.rkt +++ b/racket/collects/racket/private/for.rkt @@ -2309,8 +2309,8 @@ (lambda () #'in-value) (lambda (stx) (syntax-case stx () - [[(id) (_ expr)] - #'[(id) (:do-in ([(id) expr]) #t () #t () #t #f ())]] + [[<(id) (_ expr)] + #'[(id) (:do-in ([(id*) expr]) #t () #t ([(id) id*]) #t #f ())]] [_ #f]))) (define-sequence-syntax *in-producer