Matthew & co, On Aug 21, 2010, at 7:14 AM, Matthew Flatt wrote:
> I didn't think of this before, but probably you should add a check that > the length expression proceduces a nonnegative exact integer: > > (syntax/loc stx > (let ((len length-expr)) > (unless (exact-nonnegative-integer? len) > (raise-type-error 'for/vector "exact nonnegative integer" len)) > (let ((v (make-vector len))) > (for ((i (in-naturals)) > for-clause ...) > (vector-set! v i body)) > v))) Absolutely. I'll take care of it. > More things that I didn't think of below... > >> As for the issue >> of a #:size that doesn't match the length of the iteration, I have been >> thinking about adding a check inside the loop (for sizes that are too >> small), >> and a check outside the loop (for sizes that are too large). If the size >> does >> not match the number of loop iterations would it be better to (error >> 'for/vector "loop iterations (~a) and vector size (~a) do not match" iter >> size), raise one of the exn:fail:contract type exceptions, or manually >> construct a blame object and (raise-blame-error ...), or ...? If it were >> simply my code, I would just call (error ...), but that's maybe not the best >> in a general purpose library. > > A `exn:fail:contract' exception would be the right one. It's probably > easiest to use `raise-mismatch-error'. > > It might also be ok to use > > (i (in-range 0 len)) > > and say that the loop stops when either the sequence runs out or the > number of iterations matches the length. I'd be happy with that but i > can imagine that others might prefer an error. I think I prefer this second approach; maybe there is sometimes a use for creating a vector that is longer than its initially set length. For example, I could imagine having an extendable vector implementation where you want to leave some space at the end for future expansion. > Either choice --- error or stopping --- interacts awkwardly with > `for*/vector'. If you've going to raise an exception, the natural thing > to do with `for/vector' would be to stop as soon as the sequence goes > too far. But `for*/vector' with a length currently just uses > `for*/vector' without the length; you could check afterward, but that > would be different than the natural choice for `for/vector'. > > Along similar lines, every `for/vector' is a `for*/vector' in a way, > because a `#:when' clause can introduce a nesting. The `for/vector' > macro with an without a length behaves very differently than the one > with a length when a `#:when' clause is used. > > Maybe `for/vector' with a length clause should be syntactically > restricted to have no `#:when' clauses, and maybe there just shouldn't > be a variant of `for*/vector' that supports `#:length'. 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'll send Sam the latest when I'm done with the modifications. Will _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev