How can I use the function `count` inside an `iterate` form?

I just realized that using the count function in iterate is awkward. Something like:

(iterate (for x below 5) 
         (collect (count x '(1 4 2 3 4 2 1 2))))

causes an error (because iterate has a count clause) and needs to be rewritten as:

(iterate (for x below 5) 
         (collect (funcall #'count x '(1 4 2 3 4 2 1 2))))

This made me wish iterate stuck to counting, finding, etc., and left count, find, etc., alone. But maybe I'm just not seeing the right way of doing this. Is there a better way to use count from inside an iterate form?

Upvotes: 4

Views: 296

Answers (2)

Rainer Joswig
Rainer Joswig

Reputation: 139251

For some reason someone long ago added a synonym for count. This clashes with cl:count.

We can remove the synonym:

CL-USER 14 > (remprop 'iterate::count 'iterate::synonym)
(ITERATE::SYNONYM COUNTING)

CL-USER 15 > (iterate (for x below 5) 
               (collect (cl:count x '(1 4 2 3 4 2 1 2))))
(0 2 3 1 2)

The ITERATE manual is in conflict with the current iterate implementation:

2.3 Gathering Clauses

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.

Could be useful to report a bug: either remove the synonym(s) in question or fix the documentation. When fixing the documentation it might be useful to document how to use cl:count inside an iterate clause.

Upvotes: 3

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 9865

Why not use loop?

(loop for x below 5
      collect (count x '(1 4 2 3 4 2 1 2)))

Somehow even to use common-lisp:count inside iterate doesn't help.

I would do then:

(defun count-it (x list) (count x list))

(iter (for x below 5)
      (collect (count-it x '(1 4 2 3 4 2 1 2))))

But then, your funcall solution is more elegant even ...

Upvotes: 2

Related Questions