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

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Tue Jul 24 11:07:40 EDT 2012

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?))))


Vincent


At Tue, 24 Jul 2012 13:33:55 +0200,
Jens Axel Søgaard wrote:
> 
> Hi All,
> 
> I am writing a comprehension for*/matrix: that collects
> numbers and puts them in an mxn matrix.
> 
> A simple example:
> 
> (for*/matrix: : Number 2 3 ([i (in-range 6)]) i)
> ; => '#(0 1 2
> ;          3 4 5)
> 
> In this post the representation is simplified to a vector.
> 
> An example more:
> 
> (for*/matrix: : Number 2 3
>   ([i (in-range 2)]
>    [j (in-range 3)])
>   (+ (* 10 i) j))
> ; => '# (   0  1   2
> ;           10 11 12)
> 
> The two examples above work fine with the code below.
> 
> However I'd like the comprehension to automatically when m*n
> numbers have been generated. That is, I'd like
> 
>     (for*/matrix: : Number 2 3 ([i (in-naturals)]) i)
> 
> to produce #(0 1 2 3 4 5).
> 
> The current expansion generates an index out of range error in vector-set!.
> In for/matrix I solved the problem by adding a dummy sequence
> before the for:-clauses provided by the macro user.
> 
>          (for: ([dummy (in-range (* m n))] for:-clause ...)
>            (define x (let () . defs+exprs))
> 
> This works because for: evaluates the sequences in parallel.
> This also implies I can't use the same trick for for*: which
> evaluates the sequences in a nested fashion.
> 
> The question is how to modify the expansion below
> to  automatically stop after m*n elements have been
> generated?
> 
> /Jens Axel
> 
> 
> #lang typed/racket
> 
> (define-syntax (for*/matrix: stx)
>   (syntax-case stx ()
>     [(_ : type m-expr n-expr (for:-clause ...) . defs+exprs)
>      (syntax/loc stx
>        (let ()
>          (define: m   : Index           m-expr)
>          (define: n   : Index           n-expr)
>          (define: m*n : Index           (assert (* m n) index?))
>          (define: v   : (Vectorof type) (make-vector m*n 0))
>          (define: i   : Index           0)
>          (for*: (for:-clause ...)
>            (define x (let () . defs+exprs))
>            (vector-set! v i x)
>            (set! i (assert (+ i 1) index?)))
>          v))]))
> 
> (for*/matrix: : Number 2 3
>   ([i (in-range 2)]
>    [j (in-range 3)])
>   (+ (* 10 i) j))
> ; => '#(  0  1  2
> ;        10 11 12)
> 
> (for*/matrix: : Number 2 3 ([i (in-range 6)]) i)
> ; => '#(0 1 2
> ;       3 4 5)
> 
> (for*/matrix: : Number 2 3 ([i (in-naturals)]) i)
> ; vector-set!: index out of range
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users


Posted on the users mailing list.