[racket] idiomatic way to loop over 1-255 in TR?
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
>