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:

  (reverse
   (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


____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to