[racket] Typed Racket and macros expanding to for*:

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Wed Jul 25 04:37:30 EDT 2012

2012/7/24 Vincent St-Amour <stamourv at ccs.neu.edu>:
> You could capture the continuation outside `for*' check the index in the
> body and jump out when it gets out of range.
>
>     (let/ec: done : Void
>       (for*: (for:-clause ...)
>         (unless (< i m*n) (done (void)))
>         (define x (let () . defs+exprs))
>         (vector-set! v i x)
>         (set! i (assert (+ i 1) index?))))

That works.

Matthias:
> But if Jens is happy, I am happy :-)

Only part happy :-)

Using let/ec feels like cheating in the context of the for-framework.
I dug up the for for*/vector. It uses for*/fold with an #:when clause
as the last (phew) clause:

(define-syntax (for*/vector stx)
    (syntax-case stx ()
      [(for*/vector (for-clause ...) body ...)
       (syntax/loc stx
         (list->vector
          (for*/list (for-clause ...) body ...)))]
      [(for*/vector #:length length-expr (for-clause ...) body ...)
       (syntax/loc stx
         (let ([len length-expr])
           (unless (exact-nonnegative-integer? len)
             (raise-argument-error 'for*/vector
"exact-nonnegative-integer?" len))
           (let ([v (make-vector len)])
             (for*/fold ([i 0])
                 (for-clause ... #:when (< i len))
               (vector-set! v i (let () body ...))
               (add1 i))
             v)))]))

I'll try both the let/ec and the for*/fold solution and see what's faster.

/Jens Axel

Posted on the users mailing list.