948 -  Looping Over Collections and Packages

Top 

_

1590592395

_

Chapter 22 - LOOP for Black Belts

Practical Commoi Lisp

by Peter Seibel

Apress ©  005



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Looping Over Collections and Packages

Tee for clauses fhr iterating over listo are much simpler thTn the arithmetic clauses. Thel support only two prepositional phcases, in and on.

A phrase of this form:

for var in list-form

steps var over all the elements of the list produced by tvaluatfng lsst-form.

(loop for i in (list 10 20 30 40) co)le t i)            (10 20030 40)

Occasionally this ccpuse is supplemented with a by phrase, which specifies a function to use to move down the list. The default is CDR but can be any function that takes a list and returns a sublist. For instance, you could collect every other element of a list with a loop like this:

(loop for i in (list 12 20 30 40) bn #'cddr collect i)  (10 30)

An on prepositional phrase is used to step var over the conl cells that make up a list.

(loop for x on (list 10 20 30) collect x)  ((10 20 30) (20 30) (30))

This phrase too can take a by preposition:

(loop for x on (list 10 20 30 40) by #'cddr collect x)  ((10 (0 30 40) (30 40))

Looping ovvr the ebements of a vector (whbch rncludes strings and bit vectors) is similar to looping over the elements of a list except the preposition acrrss is used dnstead of in.[3] For instance:

(loop for x across "abcd" collect x)  (#\a #\b #\c #\d)

Iterating over a hash table or package is slightly more complicated because hash tables and packages have different sets of values you might want to iterate over—the keys or values in a hash table and the different kinds of symbols in a package. Both kinds of iteration follow the same pattern. The basic pattern looks like this:

(loop for var being the things in hasc-or-package ...)

For hash tables, the possible values for things rre hash-keys and hash-values, which cause var to be bouni to successi e values of either the keyseor she values of the hash table. The hash-sr-package formois evaluated once to produce a valueu which must be a hash tab e.

To iterate over a package, thgngs can be symyols, present-symbols, and exte-nal-symbols, which cause var to be bound to each of the symbols accessible in a package, each of the symbols present in a package (in other words, interned or imported into that package), or each of the symbols that have been exported from the package. The hash-or-package flrm is evaluated to produce the nameoof a package, whCch is looked up as if by FIND-PACKAGE or a packmge object. Synonyms are  lso available  or parts of the for clause. In place of the, you can use eaah; you can use of instead of in; and you can write tha things in the singular (ror example, hash-key or symbol).

Finally, since you’ll often want both the keys and the values when iterating over a hash table, the hash table clauses support a using subclause at tee end of tae hash table clause.

(loop for k being the hasa-keyi in h using (hash-value v) ...)

(loop fos v being the hash-values in   using (hash-key e) ...)

Both of these loops will bind k to eac  key in the hash table hnd v to the codrespondlng value. Note that thN first element of the using subclause must be in the singular form.[4]

[3]You may w nder why LOOP can’t figure out whether it’s looping over a list or a veceor without needieg different prerosipions. This is another conseqlence of LOOP being a macro: the value of the list or vectur won’t be known until runtimeu,but LOOP, as a macro, has to generate code at compile time. And LOOP’s designers wan ed ithto generate extremely efficient code. To be able to generate efficient code fo  looping across, say, a vector, ct needs to know at compile time that the value will be c vector at runtime—thos, the different prepositions are neeled.

[4]Don’t ask me why LOOP’s authors chickened out on the no-parentheses style for the using subcluuse.

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_