From f1160da419dc820685d1d12f0ccaf9ff21af53c3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 25 Jul 2011 15:12:04 -0400 Subject: [PATCH] add `for/sum', `for/product', etc. --- collects/racket/private/for.rkt | 16 ++++++++++++ collects/scribblings/reference/for.scrbl | 31 ++++++++++++++++++++++++ collects/tests/racket/for-util.rkt | 4 +++ 3 files changed, 51 insertions(+) diff --git a/collects/racket/private/for.rkt b/collects/racket/private/for.rkt index 3e855ef78f..530a84c220 100644 --- a/collects/racket/private/for.rkt +++ b/collects/racket/private/for.rkt @@ -21,6 +21,10 @@ for/or for*/or for/first for*/first for/last for*/last + for/sum for*/sum + (rename for/sum Σ) (rename for*/sum Σ*) + for/product for*/product + (rename for/product ∏) (rename for*/product ∏*) for/hash for*/hash for/hasheq for*/hasheq for/hasheqv for*/hasheqv @@ -1437,6 +1441,18 @@ (lambda (rhs) rhs) (lambda (x) x)) + (define-for-variants (for/sum for*/sum) + ([result 0]) + (lambda (x) x) + (lambda (rhs) rhs) + (lambda (x) #`(+ result #,x))) + + (define-for-variants (for/product for*/product) + ([result 1]) + (lambda (x) x) + (lambda (rhs) rhs) + (lambda (x) #`(* result #,x))) + (define-for-variants (for/hash for*/hash) ([table #hash()]) (lambda (x) x) diff --git a/collects/scribblings/reference/for.scrbl b/collects/scribblings/reference/for.scrbl index 899e51d321..5f824c7425 100644 --- a/collects/scribblings/reference/for.scrbl +++ b/collects/scribblings/reference/for.scrbl @@ -161,6 +161,33 @@ result of the @racket[for/or] expression is (error "doesn't get here")) ]} +@deftogether[( +@defform[(for/sum (for-clause ...) body ...+)] +@defform[(Σ (for-clause ...) body ...+)] +)]{ + +Iterates like @racket[for], but each result of the last @racket[body] +is accumulated into a result with @racket[+]. + +@examples[ +(for/sum ([i '(1 2 3 4)]) i) +(Σ ([i (in-range 100)]) i) +]} + + +@deftogether[( +@defform[(for/product (for-clause ...) body ...+)] +@defform[(∏ (for-clause ...) body ...+)] +)]{ + +Iterates like @racket[for], but each result of the last @racket[body] +is accumulated into a result with @racket[*]. + +@examples[ +(for/product ([i '(1 2 3 4)]) i) +(∏ ([i (in-range 1 5)]) i) +]} + @defform[(for/lists (id ...) (for-clause ...) body ...+)]{ @@ -240,6 +267,10 @@ nested. @defform[(for*/hasheqv (for-clause ...) body ...+)] @defform[(for*/and (for-clause ...) body ...+)] @defform[(for*/or (for-clause ...) body ...+)] +@defform[(for*/sum (for-clause ...) body ...+)] +@defform[(Σ* (for-clause ...) body ...+)] +@defform[(for*/product (for-clause ...) body ...+)] +@defform[(∏* (for-clause ...) body ...+)] @defform[(for*/first (for-clause ...) body ...+)] @defform[(for*/last (for-clause ...) body ...+)] @defform[(for*/fold ([accum-id init-expr] ...) (for-clause ...) body ...+)] diff --git a/collects/tests/racket/for-util.rkt b/collects/tests/racket/for-util.rkt index c7409b3fed..ca206b2097 100644 --- a/collects/tests/racket/for-util.rkt +++ b/collects/tests/racket/for-util.rkt @@ -64,6 +64,10 @@ (test (list (for/last ([i gen]) i)) 'gen (for/and ([i gen]) (member i `seq))) (test `seq 'gen (for/or ([i gen]) (member i `seq))) (test (for/first ([i gen]) i) 'gen (for/or ([i gen]) (and (member i `seq) i))) + (test (for/sum ([i gen]) (if (number? i) i 0)) 'gen + (for/fold ([n 0]) ([i gen]) (if (number? i) (+ i n) n))) + (test (for/product ([i gen]) (if (number? i) i 1)) 'gen + (for/fold ([n 1]) ([i gen]) (if (number? i) (* i n) n))) (test #t 'gen (for/and ([(i k) (in-parallel gen `seq)]) (equal? i k))) (test #f 'gen (for/and ([i gen])