Often, mutation provides “obvious” ways to do things that may be more difficult 
to do without it. Here’s one that I came across today: for/vector with an 
accumulator.

In this case, I want to create an array of length ’n’ where each cell contains 
a list of n copies of the symbol ‘zzz. That is, 

(check-equal? (init-vec 3)
  ‘#(() (zzz) (zzz zzz) (zzz zzz zzz)))

… and yes, the vector is of length n+1. No worries.

The ‘natural’ way to do this is with a helper function that just recomputes a 
list of ’n’ copies of ‘zzz’. This does actually turn a linear algorithm into an 
n^2 one, though.

There’s also a super-easy solution using for/vector with mutation:

#lang racket

(require rackunit)

;; construct a vector of lists of 'zzzs
(define (init-vec n)
  (define t '())
  (for/vector ([i (in-range (add1 n))])
    (begin0 t
            (set! t (cons 'zzz t)))))

(check-equal? (init-vec 3)
              '#(() (zzz) (zzz zzz) (zzz zzz zzz)))


… but the “right” solution sounds like a for/vector with an accumulator, so 
that I could write:

;; construct a vector of lists of 'zzzs
(define (init-vec n)
  (for/vector/accum ([t '()]) ([i (in-range (add1 n))])
    (values t (cons 'zzz t))))

Honestly, this feels a lot like one of Will Clinger’s “piling feature upon 
feature” situations, where the problem is that list comprehensions aren’t as 
flexible as they could be.

Aaand, naturally, apologies in advance if this feature already exists; about 
half the time when I ask for a feature in Racket, someone added it last year 
and I just didn’t notice :).

Back to your regularly scheduled program,

John Clements

P.S.: using for/fold to produce a list and then using list->vector is obviously 
still linear; I just like the idea of using something like for/vector that 
doesn’t produce the intermediate list. Seems like it should be possible.



-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to