[racket-dev] Wrapping loops for TR isn't working, and the type annotations are for the wrong value

From: Neil Toronto (neil.toronto at gmail.com)
Date: Wed Aug 15 10:36:36 EDT 2012

On 08/15/2012 08:05 AM, Sam Tobin-Hochstadt wrote:
> On Wed, Aug 15, 2012 at 9:54 AM, Neil Toronto <neil.toronto at gmail.com> wrote:
>> When #:length is given, it's similar in that it creates a vector outside the
>> loop and bangs values into it. But I have to start with (define vs (vector))
>> and then (set! vs (make-vector n v)) when the first value `v' is computed.
>> The docs for `for/vector' say any values not computed in the loop are
>> supposed to be 0, but that doesn't work well in TR: it'd have to create a
>> (Vectorof (U T 0)). Ick.
>
> So then the first value computed is replicated everywhere?  That seems
> unappealing as well.

It costs nothing, and if the #:length argument matches the number of 
iterations, the user never sees it.

Other options:

  1. Raise an error when the vector isn't filled.
  2. Return a (Vectorof (U T #f)) (better than (Vectorof (U T 0))?).
  3. Always return a vector whose length is the number of iterations.

For #3, the #:length argument would mean one of two things:

  A. An upper bound on the number of iterations.
  B. A "best guess" at the number of iterations.

For B, I could make it just as efficient as my current implementation 
when the guess is correct. Not giving #:length would be equivalent to 
giving #:length 1 (or some other small number).

But if implemented in Racket, #3 would break any code that depends on 
#:length limiting the number of iterations.

> Also, is there any way you could generate code that uses a binding,
> instead of `set!`?  That will probably improve the performance.

Good idea. I'll try using `for/fold:' instead of `for:'.

>> I think I could work one up that expands to code with annotations when used
>> from TR and to code without annotations otherwise. I'd use the
>> "maybe-annotate" macro (`ann:') for every annotation, not just for
>> annotating with the optional result and body types.
>
> I don't think that's a good idea -- then `racket/base` would have to
> expand to Typed Racket-specific code.  Is there a way that you can
> come up with an abstraction that is oblivious to Typed Racket?

I think something that accepts macros that expand to (vector) and 
(make-vector n v) would work. Only those expressions really need 
annotations.

Neil ⊥


Posted on the dev mailing list.