Opened 9 months ago

Last modified 9 months ago

#1422 new defect

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

Reported by: sjamaan Owned by:
Priority: major Milestone: 5.1
Component: core libraries Version: 5.0
Keywords: compiler syntax, for-each, inconsistency Cc:
Estimated difficulty: medium

Description (last modified by sjamaan)

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.


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


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.

Change History (2)

comment:1 Changed 9 months ago by sjamaan

  • Description modified (diff)

comment:2 Changed 9 months ago by felix

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.

Note: See TracTickets for help on using tickets.