[racket] idiomatic way to loop over 1-255 in TR?

From: Neil Toronto (neil.toronto at gmail.com)
Date: Wed Feb 18 14:59:52 EST 2015

TR isn't really good about finding precise types for range sequence 
elements. The macro-expanded code is too complicated.

When I write a loop with an index that needs to have a specific, narrow 
type, I either use an assertion, as in

   (for/list : (Listof Byte) ([b  (in-range 256)])
     (assert b byte?))

or loop using the next wider type and always compare the loop index with 
a value that has the narrow type:

    (let loop : (Listof Byte) ([b : Index  0]
                               [bs : (Listof Byte)  empty])
      (cond [(<= b 255)  (loop (+ b 1) (cons b bs))]
            [else  bs])))

The second method is about 10% faster.

Neil ⊥

On 02/18/2015 02:38 PM, John Clements wrote:
> I want to write this:
> (for/list ([b (in-range 256)])
>    b)
> ... and get back a list of bytes.
> That is, I want TR to see that the number 256 is one greater than the
> largest byte, and therefore that b must be of type byte.  I see that
> this dips way too close to undecidability in the general case, so I
> would instead perhaps expect to see something like an 'in-bytes-range'
> form that is known to produce only bytes.
> I looked for such a thing, but didn't find it.  Naturally, I could
> simply jam a run-time check in at the top of the body, something like
> 'ensure-bytes', but it seems unnecessary.
> Am I missing something obvious?
> Thanks!
> John
> ____________________
>    Racket Users list:
>    http://lists.racket-lang.org/users

Posted on the users mailing list.