[racket-dev] [plt] Push #20898: master branch updated

From: Noel Welsh (noelwelsh at gmail.com)
Date: Sun Aug 22 17:11:48 EDT 2010

On Sun, Aug 22, 2010 at 9:36 PM, Will M. Farr <wmfarr at gmail.com> wrote:
> Matthew & co,
...
> I'll make sure to throw a syntax error if I see a #:when in the for-clauses, and I think I should give up on the for*/vector #:length variant.  I was hoping that you would have some sort of neat trick to keep a running counter during the nested iteration....

I'm pretty sure this will exclude a lot of my code. I'll have to check tomorrow.

My for/vector allows one to construct multiple vectors in one
iteration. This is fairly useful to efficient code. I also bind the
length to a name. I thought I checked that this counter was exactly
the length after the comprehension terminated, but it appears I don't.
 Code is below.

You won't be surprised to hear I prefer my variant ;-).  I have uses
for every feature that I can dreg up if anyone is interested. I'm keen
to see a for/vector comprehension in Racket.

N.

  (define-syntax (for/fold/vector stx)
    (syntax-case stx ()
      [(for/fold/vector
        ([accum-id init-expr] ...)
        ([idx length] for-clause ...)
        body ...)
       (syntax
        (for/fold/vector
         ([accum-id init-expr] ...)
         ([idx length 1] for-clause ...)
         body ...))]

      [(for/fold/vector
        ([accum-id init-expr] ...)
        ([idx length n-vectors])
        body ...)
       (syntax
        (let ([l length])
          (for/fold/vector
           ([accum-id init-expr] ...)
           ([idx l n-vectors] [_ (in-range l)])
           body ...)))]

      [(for/fold/vector
        ()
        ([idx length n-vectors] for-clause0 for-clause ...)
        body ...)
       (with-syntax ([(v-id ...)
                      (datum->syntax
                       stx
                       (for/list ([i (in-range (syntax->datum (syntax
n-vectors)))])
                                 (gensym 'for-vector))
                       (syntax n-vectors))]
                     [(temp-id ...)
                      (datum->syntax
                       stx
                       (for/list ([i (in-range (syntax->datum (syntax
n-vectors)))])
                                 (gensym 'for-vector))
                       (syntax n-vectors))])
         (syntax
          (let* ([l length]
                 [idx 0]
                 [v-id (make-vector l)] ...)
            (begin
              (for (for-clause0 for-clause ...)
                   (let-values (([temp-id ...] (let () body ...)))
                     (vector-set! v-id idx temp-id) ...
                     (set! idx (add1 idx))))
              (values v-id ...)))))]

      [(for/fold/vector
        ([accum-id0 init-expr0] [accum-id init-expr] ...)
        ([idx length n-vectors] for-clause0 for-clause ...)
        body ...)
       (with-syntax ([(v-id ...)
                      (datum->syntax
                       stx
                       (for/list ([i (in-range (syntax->datum (syntax
n-vectors)))])
                                 (gensym 'for-vector))
                       (syntax n-vectors))]
                     [(temp-id ...)
                      (datum->syntax
                       stx
                       (for/list ([i (in-range (syntax->datum (syntax
n-vectors)))])
                                 (gensym 'for-vector))
                       (syntax n-vectors))])
         (syntax
          (let* ([l length]
                 [idx 0]
                 [v-id (make-vector l)] ...)
            (let-values (([accum-id0 accum-id ...]
                          (for/fold ([accum-id0 init-expr0]
                                     [accum-id  init-expr] ...)
                              (for-clause0 for-clause ...)
                            (let-values (([accum-id0 accum-id ... temp-id ...]
                                          (let () body ...)))
                              (vector-set! v-id idx temp-id) ...
                              (set! idx (add1 idx))
                              (values accum-id0 accum-id ...)))))
              (values accum-id0 accum-id ... v-id ...)))))]))

  (define-syntax (for/vector stx)
    (syntax-case stx ()
      [(for/vector (for-clause ...)
                   body ...)
       (syntax (for/fold/vector () (for-clause ...) body ...))]))


Posted on the dev mailing list.