Summary

for-each behaves inconsistently when compiled versus interpreted on lists of unequal length

Metadata

Description

There's a compiler syntax registered for for-each (and for map, too) which rewrite/expands most for-each calls to a loop for performance reasons.

While working on the "scheme" module at some point I forgot to patch this to apply to scheme#for-each so it didn't get applied, and I got an error in both the scrutinizer and a test. In both cases, for-each was being used on two lists of unequal length, causing for-each to bail out with an error.

Example:

 (for-each (lambda (x y) (print (+ x y))) '(1 2 3) '(1 2))

When compiled, this prints 2\n4, when interpreted this gives the following (quite useless) error:

 2
 4
 
 Error: (for-each) lists are not of same length: (())

I think this error message really needs to be improved (which will be a bit more costly in terms of garbage collection because the head is held onto regardless of how far we got in the loop). I believe map has the same issue.

Also, giving the error after executing the procedure is questionable; maybe it should first check the lengths of the lists and then start traversing them?

Finally, we need to decide how we want for-each to behave: like the compiler syntax or like the procedure. Either is fine by me, and judging what the standard says, I think both are fine too. It doesn't explicitly say "it is an error" when the lists aren't the same length, but it just says "the lists must be the same length". R7RS explicitly allows the lists to be of unequal length (presumably taken from SRFI-1's extended definition), so maybe we should just allow this as an allowed extension to R5RS and get rid of the check.

Changes and comments

[2017-10-19 12:29:35 UTC] sjamaan changed description

[2017-10-19 15:54:41 UTC] felix wrote:

Any extra check would make the compiler syntax slower (and thus pointless). I'd rather go for the lax interpretation of the standard. This may also be handy when coding, even though it may break in stricter implementations.

[2019-04-07 12:23:24 UTC] sjamaan changed milestone from 5.1 to 5.2

[2019-04-07 12:23:24 UTC] sjamaan wrote:

Getting ready for 5.1, moving tickets which won't make it in to 5.2.

[2019-07-24 10:33:52 UTC] evhan changed status from new to closed

[2019-07-24 10:33:52 UTC] evhan set resolution to fixed

[2019-07-24 10:33:52 UTC] evhan wrote:

Fixed by c968d65ce.