[racket] Typed Racket and macros expanding to for*:
(I had just considered writing a matrix library in TR too.)
I don't see any other way than use a #:when clause that checks i. -- Matthias
On Jul 24, 2012, at 7:33 AM, 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