foreach (var object &rest keys) &body forms-and-clauses => result
Arguments and Values:
var---a non evaluated symbol
object---an object instance
keys---a list of key-value pairs
forms-and-clauses---a list of forms and LOOP clauses
The FOREACH macro is a simplified iteration construct over an enumerable object. FOREACH is a thin macro over LOOP and it mixes, in a hybrid -- and maybe not so beautiful -- style the DOTIMES/DOLIST shape with LOOP clauses.
forms-and-clauses are executed in an environment where var is bound to the elements of the result of
(apply #'enum:enumerate object keys)
If keys contains a non-NIL
then the enumeration must be bi-directional and PREVIOUS and
HAS-PREVIOUS-P will be used to traverse it.
:reverse and its value
will be still passed to the embedded call to ENUMERATE. This is
obviously only useful only for enumerations that can start "in the
forms-and-clauses can start with some declarations and then continue with either regular forms or LOOP clauses. After the first LOOP clause appears in FORMS-AND-CLAUSES, standard LOOP rules should be followed.
The result returned by FOREACH is whatever is returned by forms-and-clauses according to standard LOOP semantics.
Here are some examples of FORACH.
cl-prompt> (setf le (enumerate '(1 2 3))) #<CONS enumeration ...> cl-prompt> (foreach (i le) (print i)) 1 2 3 NILOf course, FOREACH is smarter than that:
cl-prompt> (foreach (i (vector 'a 's 'd)) (declare (type symbol i)) (print i)) A S D NILApart from declarations, FOREACH is just a macro built on top of LOOP, therefore you can leverage all the LOOP functionality.
cl-prompt> (foreach (i (vector 1 2 3 4)) (declare (type fixnum i)) when (evenp i) collect i) (2 4)While this creates an admittedly strange hybrid between the standard DO... operators and LOOP, it does serve the purpose. The right thing would be to have a standardized way of extending LOOP. Alas, there is no such luxury.
Finally an example of a reverse enumeration:
cl-prompt> (foreach (i (vector 1 2 3 4 5 6 7 8) :reverse t :start 4) when (evenp i) collect i) (4 2)
ENUMERATION class, BOUNDED-ENUMERATION, NUMBER-ENUMERATION, BI-DIRECTIONAL-ENUMERATION, SEQUENCE-ENUMERATION, LIST-ENUMERATION, ARRAY-ENUMERATION, VECTOR-ENUMERATION, STRING-ENUMERATION, HASH-TABLE-ENUMERATION, NEXT, HAS-NEXT-P, CURRENT, PREVIOUS, HAS-PREVIOUS-P.