[racket] idiomatic and fast

From: J. Ian Johnson (ianj at ccs.neu.edu)
Date: Sat Apr 28 16:26:04 EDT 2012

(whoops, should reply all)
I have a macro that does for/fold behavior on some arguments and for/lists on the other. It's fairly handy.

Here's my solution with that macro:
(let-values ([(_ result)
              (for/fold/lists ([s 0]) (result) ([i (in-range 1 21)])
                              (values (+ s i) (+ s i)))])
  result)

And here's the macro for your libraries (uses syntax/parse):
(define-syntax (for/fold/lists stx)
  (syntax-parse stx
    ;; lists go last
    [(_ ([fold-target:id fold-start:expr] ...) (lst:id ...) (clauses ...) body1:expr body:expr ...)
     (with-syntax ([(lsttmps ...) (generate-temporaries #'(lst ...))])
       #`(let-values ([(fold-target ... lst ... )
                       (for/fold/derived #,stx ([fold-target fold-start] ... [lst '()] ...) (clauses ...)
                         (let-values ([(fold-target ... lsttmps ...) (let () body1 body ...)])
                           (values fold-target ... (cons lsttmps lst) ...)))])
           (values fold-target ... (reverse lst) ... )))]
    ;; lists go first.
    [(_ (lst:id ...) ([fold-target:id fold-start:expr] ...) (clauses ...) body1:expr body:expr ...)
     (with-syntax ([(lsttmps ...) (generate-temporaries #'(lst ...))])
       #`(let-values ([(lst ... fold-target ...)
                       (for/fold/derived #,stx ([lst '()] ... [fold-target fold-start] ...) (clauses ...)
                         (let-values ([(lsttmps ... fold-target ...) (let () body1 body ...)])
                           (values (cons lsttmps lst) ... fold-target ...)))])
           (values (reverse lst) ... fold-target ...)))]))

Haven't gotten around to making a for*/fold/lists form yet.
-Ian
----- Original Message -----
From: "Joe Gilray" <jgilray at gmail.com>
To: "Racket mailing list" <users at racket-lang.org>
Sent: Saturday, April 28, 2012 3:54:31 PM GMT -05:00 US/Canada Eastern
Subject: [racket] idiomatic and fast


Hi, 


I'm trying to come up with the most idiomatic way to generate triangle numbers that is also fast: 


(for/list ([i (in-range 2 22)]) (for/sum ([j (in-range i)]) j)) 


works but is slow because it regenerates the sums each time 


(define s 0) (for/list ([i (in-range 1 21)]) (set! s (+ s i)) s) 


is fast, but ugly. 


How do I keep the sum in an idiomatic fashion? 


Thanks, 
-Joe 
____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Posted on the users mailing list.