Minor bug: conflict with Common Lisp function count
Section 2.3 of the Iterate Manual, “Gathering Clauses,” states
These clauses all begin with a verb. When the verb does not conflict with an existing Common Lisp function, then it may be used in either its infinitival or present-participle form (e.g. sum, summing). However, when there is a conflict with Common Lisp, only the present-participle form may be used (e.g. unioning). This is to prevent iterate clauses from clashing with Common Lisp functions.
Unfortunately it appears that iterate currently uses the infinitive form of count, which is a Common Lisp function. For example, I believe that
(iter (for string in '("foo!" "bar!!" "baz?" "ba!zoo!"))
(when (> (count #\! string) 1)
(collect string)))
should return ("bar!!" "ba!zoo!")
, but instead signals an error
Iterate, in (COUNT ! STRING):
Missing value for STRING keyword
[Condition of type SIMPLE-ERROR]
(An ugly workaround to demonstrate the correct result is to replace (count …
by (funcall #'count …
.)
That is, according to its documentation, and to be consistent with other cases such as nconc
or union
, Iterate should use only counting
, not count
.
This is easily fixed by deleting line 2,835 of iterate.lisp: (defsynonym count counting)
. I’ve confirmed that removing this line seems to work and cause no other obvious problems, though I’ve not yet been able to try adjusting and running the unit tests, as described below.
In fact, looking at this part of iterate.lisp it seems evident that as originally written count correctly was not a synonym for counting, and only at some subsequent point was the buggy behavior introduced: in all the other cognate cases the defsynonym
comes after the corresponding defclause
, while it comes before for counting/count
; and in all the other cognate cases the defclause
defines the infinitive form, with the present-participle being the target of the defsynonym
, yet it is the other way around for counting/count
.
I don’t know when this change was made. It is not mentioned in the changes listed at the top of the file, and was already present in the earliest version I can find on gitlab.common-lisp.net, from 2006.
After correcting this I believe that eight, or perhaps nine, of the unit tests would also have to be updated. The eight definite ones simply need to have count
replaced by counting
, and are on lines 107, 358, 782, 1,279, 1,358, 1,851, 1,862 and 1,870 of iterate-test.lisp.
The questionable ninth one is nearly at the end of that file, at or around line 1,913. Amusingly, from the comment, it appears to be acknowledging the presence of this bug and working around it. It seems plausible that that work around should be removed.
I would suggest also adding a further, short, clear unit test that uses the Common Lisp count
function to guard against recidivism of this issue.
I’m afraid I’ve not yet figured out how to obtain RT so that I can run the unit tests myself. If I can figure that out, perhaps with your help, I’d be happy to to make the simple change to iterate.lisp and the changes to the unit tests and confirm that all is well and submit a pull request (or, it looks like GitLab may call it a “merge request”?). Though, even in addition to not knowing RT I’d also have to learn a bit about GitLab, which I’ve never used before. And I’d only be able to test it in SBCL and CCL on Linux and macOS, not having access to a Windows machine nor to proprietary Lisp implmentations.
Anyway, please let me know what I can do to help.
Thanks!