On 08/15/2012 05:24 AM, Sam Tobin-Hochstadt wrote:
On Tue, Aug 14, 2012 at 11:52 PM, Neil Toronto <neil.toro...@gmail.com> wrote:
Some typed "for" loops would have to be reimplemented, unless inference
improves a lot. To make this easier, I've attached an example implementation
of `for/vector:' and `for*/vector:'. It allows both body and result
annotations, handles #:length properly, allows #:when clauses anywhere, and
fixes the two bugs in `for/vector' I reported today.
Thanks for doing this. I worry a little about re-implementing
`for/vector`, since now we have two implementations to keep in sync.
Eventually, I think Typed Racket needs to support more agressive
inference than it currently does; that's the reality of dealing with a
macro-generated language. But for the moment, this would make things
better for people.
Agree on all counts.
BTW, what do you think of deprecating result annotations and using body
annotations instead?
Two questions: (1) how similar is the generated code to the expansion
of plain `for/vector`[?]...
In the case where #:length is missing, not very. I couldn't use
`for/list:' and convert to a vector because I couldn't reliably generate
(Listof T) from the result type (because of type aliases). On the plus
side, mine's about twice as fast. It expands to plain `for:' and bangs
values into a growable vector.
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.
I wouldn't mind if `for/vector' behaved the same way, since the current
behavior makes it easy to violate contracts. On my computer, my
`for/vector:' with #:length takes only 5% longer to run than an
equivalent `for/vector' loop with moderate-sized vectors.
> and (2) would it be possible to abstract the implementation of
> Racket's `for/vector` to allow you to re-use some of that code here?
I wouldn't want to because `for/vector' is currently broken when
#:length is given. (See PR 13029 and PR 13030.)
I think the only way to fix it is to implement it like I did: expand to
plain `for:' and mutate an external index. So it might be better to have
them share a new common implementation.
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.
Neil ⊥
_________________________
Racket Developers list:
http://lists.racket-lang.org/dev