[racket] Typed Racket - (Sequenceof Index) As Looping Index

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Wed Feb 27 17:22:08 EST 2013

At Wed, 27 Feb 2013 16:34:46 -0500,
Ray Racine wrote:
> The below is just an observation.
> Historically in TR I've always struggled with Index vs Fixnum vs Natural
> for the vector indexing type when iterating over a vector (or large
> sub-ranges or even larger vectors).  Either the Optimizer complains that an
> index? check was not elided in a vector-ref OR you end up doing something
> along the lines of  (assert (add1 idx) index?) while looping your index
> variable passing over the Vector.
> But I've just noticed that one can construct TR recognized (Sequenceof
> Index).
> So in theory, TR + Compiler should be able to elide a number of checks,
> such as (assert idx index?), use `unsafe-vector-ref', even elide in loop
> bounds checks if the vector is supplied to the 'for'.  This assumes the
> (Sequenceof Index) is an efficient generator.  i.e., (in-range 3 10000000)
> is not allocating 10000000 somethings. ( I don't know what it "really" is
> happening overall, just what I think is possible.  Sufficiently smart
> compiler yada yada.)

The TR optimizer is not smart enough to completely elide bounds
checking[1]. If a vector index is guaranteed to be an `Index', the
optimizer avoids checking whether the index is >= 0, uses unsafe fixnum
operations for that check, and then calls `unsafe-vector-ref'. Not as
fast as calling `unsafe-vector-ref' directly, but still an improvement
over plain `vector-ref'.

At Wed, 27 Feb 2013 16:51:42 -0500,
Ray Racine wrote:
> Just to be clear.  The below does work in TR and idx is of type Index.
> However when one embeds the (in-range 3 5)  directly in the for/vector idx
> is not of type Index.  No reason why it shouldn't however.

The `for' macros recognize the `in-*' forms and, instead of actually
calling the corresponding functions, generate optimized code in-line.
This means that TR, instead of seeing the call to `in-range', sees the
optimized expansion and typechecks that. Since that code uses `+' in
unrestricted ways, TR can't assign precise types.


[1] Except in very limited cases, where a vector with a bounded-length
vector type is accessed with an index of a singleton type that's within
the bound. Basically, when vectors are used as poor man's structs.

Posted on the users mailing list.