Next: , Previous: Reductions, Up: Gathering Clauses

2.3.2 Accumulations

All the predefined accumulation clauses add values to a sequence. If the sequence is a list, they all have the property that the partial list is kept in the correct order and available for inspection at any point in the loop.

— Clause: collect exptr &optional

into var at place result-type type

Produces a sequence of the values of exptr on each iteration. place indicates where the next value of exptr is added to the list and may be one of the symbols start, beginning (a synonym for start) or end. The symbol may be quoted, but need not be. The default is end. For example,

       (iter (for i from 1 to 5)
             (collect i))

produces (1 2 3 4 5), whereas

       (iter (for i from 1 to 5)
             (collect i at beginning))

produces (5 4 3 2 1) (and is likely to be faster in most Common Lisp implementations).

If type is provided, it should be a subtype of sequence. The default is list. Specifying a type other than list will result in collect returning a sequence of that type. However, the type of the sequence being constructed when inside the loop body is undefined when a non-list type is specified. (As with place, quoting type is optional.)

— Clause: adjoining exptr &optional into var test test at place result-type type

Like collect, but only adds the value of exptr if it is not already present. test, which defaults to #'eql, is the test to be used with member.

— Clause: appending expr &optional into var at place
— Clause: nconcing expr &optional into var at place
— Clause: unioning expr &optional into var test test at place
— Clause: nunioning expr &optional into var test test at place

These are like collect, but behave like the Common Lisp functions append, nconc, union or nunion. As in Common Lisp, they work only on lists. Also as in Common Lisp, unioning and nunioning assume that the value of expr contains no duplicates.

— Clause: accumulate expr by func &optional initial-value init-val into var

This is a general-purpose accumulation clause. func should be a function of two arguments, the value of expr and the value accumulated so far in the iteration, and it should return the updated value. If no initial value is supplied, nil is used.

The differences between accumulate and reducing are slight. One difference is that the functions take their arguments in a different order. Another is that in the absence of init-val, accumulate will use nil, whereas reducing will generate different code that avoids any dependence on the initial value. The reason for having both clauses is that one usually thinks of reductions (like sum) and accumulations (like collect) as different beasts.