[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


DO& is an interation macro with many of the features of LOOP and a
LISPy syntax similar to DO*.  User-definable keywords allow common
iterative constructs -- like CDRing down a list, CONSing a new list,
or counting -- to be implemented more simply and readably.  Automatic
generation of end tests makes the DO/DO* end-test form unnecessary.  

The programs below, equivalent to common LISP functions, give a feel for
DO& style:

(defun length (list)
  (do& ((i &count0)
	(l &pop list &return i))))

(defun reverse (list)
  (do& ((elt &pop list &return accum)
	(accum &push elt))))

(defun listarray (array)
  (do& ((elt &aref array
	     &return (nreverse list))
	(list &push elt))))

(defun remq (item list)
  (do& ((a &pop list &return (nreverse out))
	(out &push a
	     &only-if (neq a item)))))

DO& allows most relevant information to appear within the
variable specifications, improving program clarity, and doing
away with the need for formulaic and complex bodies.

DO& has evolved over more than two years and reimplemented many times.
The rough corners have been worn off, and we now believe the current
implementation is clean enough for general release.

DO& is documented in detail in LMLIB;DO&DOC.  Bugs to BUG-DO&@AI;
users may wish to add themselves to INFO-DO&.

Here is a partial comparison of features of DO& and LOOP.  It is
perhaps not perfectly impartial.  Also, many of the features of LOOP
which DO& lacks could be added if there were demand for them.

DO& syntax is a natural extension of DO*.  LOOP is a non-LISPy
sublanguage.  Partly as a consequence, it is easier to determine
the scope of DO& keywords than that of LOOP keywords.  Since
keywords all begin with ``&'' it is easy to separate them from
non-keywords.  The simplicity of DO& syntax makes it trivial to
learn and often immediately understandably by non-users.  Also it
indents better than LOOP in Zmacs.

LOOP and DO& have roughly comparable numbers predefined iteration
keywords.  The sets are not identical; LOOP has a package mapping
keyword, and DO& has one for mapping over plists.  In any case, both
make it relatively easy to define your own keywords, so exactly which
keywords are defined by default is not very important.

LOOP supports parallel binding; DO& does not.  Of course you can
always use an extra variable to get the same effect.

DO& guarantees that variables have sensible values at all times; LOOP
does not.  In particular, in a LOOP epilogue, the values of iteration
variables may be undefined, whereas in a DO& &RETURN form, they are
always defined and take on the obvious value.

Both LOOP and DO& achieve package independence by using pname equality
in looking for keywords.

LOOP supports destructuring; DO& does not.  DO& generates automatic
dummy variables when none is supplied in a variable specification;
LOOP does not.

LOOP does more code optimization than DO& does.

DO& has many other features that are described in detail in DO&DOC.