Opened 7 years ago
Closed 5 years ago
#1422 closed defect (fixed)
for-each behaves inconsistently when compiled versus interpreted on lists of unequal length
Reported by: | sjamaan | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | 5.2 |
Component: | core libraries | Version: | 5.0.0 |
Keywords: | compiler syntax, for-each, inconsistency | Cc: | |
Estimated difficulty: | medium |
Description (last modified by )
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.
Change History (4)
comment:1 Changed 7 years ago by
Description: | modified (diff) |
---|
comment:2 Changed 7 years ago by
comment:3 Changed 6 years ago by
Milestone: | 5.1 → 5.2 |
---|
Getting ready for 5.1, moving tickets which won't make it in to 5.2.
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.