[racket-dev] [plt] Push #20898: master branch updated

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Aug 21 08:14:35 EDT 2010

At Fri, 20 Aug 2010 13:05:12 -0500, "Will M. Farr" wrote:
> Thanks very much for the comments.  I'll get to work preparing an updated 
> version using #:size soon, and send it to Sam for pushing. 

I should have suggested `#:length', since it corresponds to

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

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.

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'.

Posted on the dev mailing list.