Commit a1753b81 authored by Joerg-Cyril Hoehle's avatar Joerg-Cyril Hoehle
Browse files

Use @:, @. and two spaces between sentences

Move section on predicate (first-time-p) outside of gathering clauses
Various typos and some clarifications

darcs-hash:5b5854a2ee03c6d4bb12991029e4eb351be51ad8
parent 0a95bcee
\input texinfo @c -*- Mode: Texinfo; Mode: auto-fill -*- \input texinfo @c -*- Mode: Texinfo; Mode: auto-fill -*-
@c %**start of header @c %**start of header
@setfilename iterate.info @setfilename iterate.info
@settitle The Iterate Manual @settitle The Iterate Manual and Paper
@exampleindent 2 @exampleindent 2
@c @documentencoding utf-8 @c @documentencoding utf-8
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
@end macro @end macro
@macro impnote {text} @macro impnote {text}
@quotation @quotation Implementor's note
@strong{Implementor's note:} @emph{\text\} @emph{\text\}
@end quotation @end quotation
@end macro @end macro
...@@ -75,8 +75,8 @@ Copyright @copyright{} 1989 Jonathan Amsterdam <jba at ai.mit.edu> @* ...@@ -75,8 +75,8 @@ Copyright @copyright{} 1989 Jonathan Amsterdam <jba at ai.mit.edu> @*
@c <loliveira at common-lisp.net> @* @c <loliveira at common-lisp.net> @*
@quotation @quotation
The present manual is an adaptation of Jonathan Amsterdam's ``The The present manual is a conversion of Jonathan Amsterdam's ``The
Iterate Manual'', @acronym{MIT} @acronym{AI} Memo No. 1236. Said memo Iterate Manual'', @acronym{MIT} @acronym{AI} Memo No.@: 1236. Said memo
mentioned the following contract information: mentioned the following contract information:
@emph{This report describes research done at the Artificial @emph{This report describes research done at the Artificial
...@@ -85,12 +85,15 @@ Support for the laboratory's artificial intelligence research is ...@@ -85,12 +85,15 @@ Support for the laboratory's artificial intelligence research is
provided in part by the Advanced Research Projects Agency of the provided in part by the Advanced Research Projects Agency of the
Department of Defense under Office of Naval Research contract Department of Defense under Office of Naval Research contract
N00014-85-K-0124.} N00014-85-K-0124.}
The appendix includes Jonathan Amsterdam's Working Paper 324,
MIT AI Lab entitled ``Don't Loop, Iterate.''
@end quotation @end quotation
@end copying @end copying
@c %**end of header @c %**end of header
@titlepage @titlepage
@title The Iterate Manual @title The Iterate Manual and Paper
@c @subtitle Version X.X @c @subtitle Version X.X
@c @author Jonathan Amsterdam @c @author Jonathan Amsterdam
...@@ -131,10 +134,10 @@ Common Lisp. @iter{} provides abstractions for many common iteration ...@@ -131,10 +134,10 @@ Common Lisp. @iter{} provides abstractions for many common iteration
patterns and allows for the definition of additional patterns. patterns and allows for the definition of additional patterns.
@iter{} is a macro that expands into ordinary Lisp at compile-time, so @iter{} is a macro that expands into ordinary Lisp at compile-time, so
it is more efficient than higher-order functions like @code{map} and it is more efficient than higher-order functions like @code{map} and
@code{reduce}. While it is similar to @code{loop}, @iter{} offers a @code{reduce}. While it is similar to @code{loop}, @iter{} offers a
more Lisp-like syntax and enhanced extensibility. (For a more more Lisp-like syntax and enhanced extensibility. (For a more
complete comparison of @iter{} with other iteration constructs, see complete comparison of @iter{} with other iteration constructs, see
@acronym{MIT} @acronym{AI} Lab Working Paper No. 324, @emph{Don't @acronym{MIT} @acronym{AI} Lab Working Paper No.@: 324, @emph{Don't
Loop, Iterate.} also included in this manual in @ref{Don't Loop Loop, Iterate.} also included in this manual in @ref{Don't Loop
Iterate}.) Iterate}.)
...@@ -189,7 +192,7 @@ illustrates some of these features: ...@@ -189,7 +192,7 @@ illustrates some of these features:
@end lisp @end lisp
This loop takes the keys of an alist and returns a new alist This loop takes the keys of an alist and returns a new alist
associating the keys with their positions in the original list. The associating the keys with their positions in the original list. The
compiler declaration for @code{i} will appear in the generated code in compiler declaration for @code{i} will appear in the generated code in
the appropriate place. the appropriate place.
...@@ -216,6 +219,7 @@ keyword @code{&optional}. ...@@ -216,6 +219,7 @@ keyword @code{&optional}.
* Variable Binding and Setting:: * Variable Binding and Setting::
* Gathering Clauses:: * Gathering Clauses::
* Control Flow:: * Control Flow::
* Predicates::
* Code Placement:: * Code Placement::
@end menu @end menu
...@@ -287,7 +291,7 @@ not an integer, the actual number of executions will be @mathx{\lceil n ...@@ -287,7 +291,7 @@ not an integer, the actual number of executions will be @mathx{\lceil n
The general form for iterating over a sequence of numbers requires a The general form for iterating over a sequence of numbers requires a
variable and, optionally, one or more keywords that provide the bounds variable and, optionally, one or more keywords that provide the bounds
and step size of the iteration. The @code{&sequence} lambda-list and step size of the iteration. The @code{&sequence} lambda-list
keyword is a shorthand for these sequence keywords. They are: keyword is a shorthand for these sequence keywords. They are:
@code{from}, @code{upfrom}, @code{downfrom}, @code{to}, @code{downto}, @code{from}, @code{upfrom}, @code{downfrom}, @code{to}, @code{downto},
@code{above}, @code{below} and @code{by}. @code{from} provides the @code{above}, @code{below} and @code{by}. @code{from} provides the
...@@ -295,7 +299,7 @@ starting value for @var{var} and defaults to zero. @code{to} provides ...@@ -295,7 +299,7 @@ starting value for @var{var} and defaults to zero. @code{to} provides
a final value and implies that the successive values of @var{var} will a final value and implies that the successive values of @var{var} will
be increasing; @code{downto} implies that they will be decreasing. be increasing; @code{downto} implies that they will be decreasing.
The loop terminates when @var{var} passes the final value The loop terminates when @var{var} passes the final value
(i.e. becomes smaller or larger than it, depending on the direction of (i.e.@: becomes smaller or larger than it, depending on the direction of
iteration); in other words, the loop body will never be executed for iteration); in other words, the loop body will never be executed for
values of @var{var} past the final value. @code{below} and values of @var{var} past the final value. @code{below} and
@code{above} are similar to @code{to} and @code{downto}, except that @code{above} are similar to @code{to} and @code{downto}, except that
...@@ -330,7 +334,7 @@ next to the clause. ...@@ -330,7 +334,7 @@ next to the clause.
There are a number of clauses for iterating over sequences. In all of There are a number of clauses for iterating over sequences. In all of
them, the argument following @code{for} may be a list instead of a them, the argument following @code{for} may be a list instead of a
symbol, in which case destructuring is performed. See symbol, in which case destructuring is performed. See
@ref{Destructuring}. @ref{Destructuring}.
@claused{for, in} @claused{for, in}
...@@ -359,7 +363,7 @@ ancient @code{for @v{var} in} is equivalent to ...@@ -359,7 +363,7 @@ ancient @code{for @v{var} in} is equivalent to
@claused{for, on} @claused{for, on}
@deffn Clause for @v{var} @cl{on} @v{list} @k{&optional} @k{by} @v{step-function} @deffn Clause for @v{var} @cl{on} @v{list} @k{&optional} @k{by} @v{step-function}
@var{var} is set to successive sublists of list. @var{step-function} @var{var} is set to successive sublists of list. @var{step-function}
(default @code{cdr}) is used as in @code{for@dots{} in}. (default @code{cdr}) is used as in @code{for@dots{} in}.
This clause uses @code{atom} to test for the end of a list, so it can This clause uses @code{atom} to test for the end of a list, so it can
...@@ -377,13 +381,13 @@ be used with dotted lists---like @code{loop}. ...@@ -377,13 +381,13 @@ be used with dotted lists---like @code{loop}.
@claused{for, in-vector} @claused{for, in-vector}
@deffn Clause for @v{var} @cl{in-vector} @v{vector} @k{&sequence} @deffn Clause for @v{var} @cl{in-vector} @v{vector} @k{&sequence}
@var{var} takes on successive elements from @var{vector}. The vector's @var{var} takes on successive elements from @var{vector}. The vector's
fill-pointer is observed. Here and in subsequent clauses, the fill-pointer is observed. Here and in subsequent clauses, the
@code{&sequence} keywords include @code{with-index}, which takes a @code{&sequence} keywords include @code{with-index}, which takes a
symbol as argument and uses it for the index variable instead of an symbol as argument and uses it for the index variable instead of an
internally generated symbol. The other @code{&sequence} keywords internally generated symbol. The other @code{&sequence} keywords
behave as in numerical iteration, except that the default iteration behave as in numerical iteration, except that the default iteration
bounds are the bounds of the vector. E.g. in @code{(for i in-vector v bounds are the bounds of the vector. E.g.@: in @code{(for i in-vector v
downto 3)}, @code{i} will start off being bound to the last element in downto 3)}, @code{i} will start off being bound to the last element in
@code{v}, and will be set to preceding elements down to and including @code{v}, and will be set to preceding elements down to and including
the element with index 3. the element with index 3.
...@@ -457,7 +461,7 @@ more than once. ...@@ -457,7 +461,7 @@ more than once.
@k{&optional} @k{using} @v{reader} @k{&optional} @k{using} @v{reader}
Opens the file @var{name} (which may be a string or pathname) for Opens the file @var{name} (which may be a string or pathname) for
input, and iterates over its contents. @var{reader} defaults to input, and iterates over its contents. @var{reader} defaults to
@code{read}, so by default @emph{var} will be bound to the successive @code{read}, so by default @emph{var} will be bound to the successive
forms in the file. The @iter{} body is wrapped in an forms in the file. The @iter{} body is wrapped in an
@code{unwind-protect} to ensure that the file is closed no matter how @code{unwind-protect} to ensure that the file is closed no matter how
...@@ -506,7 +510,7 @@ from 1 to 10)}: ...@@ -506,7 +510,7 @@ from 1 to 10)}:
@deffn Clause for @v{var} @k{do-next} @v{form} @deffn Clause for @v{var} @k{do-next} @v{form}
@var{form} is evaluated each time through the loop. Its value is @var{form} is evaluated each time through the loop. Its value is
@var{not} set to @var{var}; that is @var{form}'s job. @var{var} is @var{not} set to @var{var}; that is @var{form}'s job. @var{var} is
only present so that @iter{} knows it is a driver variable. @* only present so that @iter{} knows it is a driver variable. @*
@code{(for @var{var} next @var{expr})} is equivalent to @code{(for @code{(for @var{var} next @var{expr})} is equivalent to @code{(for
@var{var} do-next (dsetq @var{var} @var{expr}))}. (See @var{var} do-next (dsetq @var{var} @var{expr}))}. (See
...@@ -652,7 +656,7 @@ then @var{pvar} will be assigned @var{var}'s first value when ...@@ -652,7 +656,7 @@ then @var{pvar} will be assigned @var{var}'s first value when
@var{var} is set to its third value. @var{var} is set to its third value.
A @code{for@dots{} previous} clause may occur after or before its A @code{for@dots{} previous} clause may occur after or before its
associated driver clause. @code{for@dots{} previous} works with associated driver clause. @code{for@dots{} previous} works with
generators as well as ordinary drivers. generators as well as ordinary drivers.
Example: Example:
...@@ -698,7 +702,7 @@ beginning. ...@@ -698,7 +702,7 @@ beginning.
Successive occurrences of @code{with} result in sequential bindings Successive occurrences of @code{with} result in sequential bindings
(as with @code{let*}). There is no way to obtain parallel bindings; (as with @code{let*}). There is no way to obtain parallel bindings;
see @ref{Parallel Binding and Stepping} for a rationale. see @ref{Parallel Binding and Stepping} for a rationale.
@end deffn @end deffn
@claused{for, =} @claused{for, =}
...@@ -749,7 +753,7 @@ extending @iter{} with new drivers (see @ref{Rolling Your Own}). ...@@ -749,7 +753,7 @@ extending @iter{} with new drivers (see @ref{Rolling Your Own}).
@deffn Clause for @v{var} @cl{first} @v{first-expr} @cl{then} @v{then-expr} @deffn Clause for @v{var} @cl{first} @v{first-expr} @cl{then} @v{then-expr}
The first time through the loop, @var{var} is set to @var{first-expr}; The first time through the loop, @var{var} is set to @var{first-expr};
on subsequent iterations, it is set to @var{then-expr}. This differs on subsequent iterations, it is set to @var{then-expr}. This differs
from @code{for@dots{} initially} in that @var{var} is set to from @code{for@dots{} initially} in that @var{var} is set to
@var{first-expr} inside the loop body, so @var{first-expr} may depend @var{first-expr} inside the loop body, so @var{first-expr} may depend
on the results of other clauses. For instance, on the results of other clauses. For instance,
...@@ -780,7 +784,7 @@ binding (usually @code{nil}) for the first iteration. ...@@ -780,7 +784,7 @@ binding (usually @code{nil}) for the first iteration.
operations were sufficiently different to warrant different keywords. operations were sufficiently different to warrant different keywords.
Also, the @code{for} in the above three clauses is misleading, since Also, the @code{for} in the above three clauses is misleading, since
none is true driver (e.g. none has a corresponding @code{generate} none is true driver (e.g.@: none has a corresponding @code{generate}
form). @code{setting} would have been a better choice, but @code{for} form). @code{setting} would have been a better choice, but @code{for}
was used to retain some compatibility with @code{loop}. was used to retain some compatibility with @code{loop}.
@end quotation @end quotation
...@@ -803,23 +807,22 @@ during the loop, but it should not be modified. ...@@ -803,23 +807,22 @@ during the loop, but it should not be modified.
These clauses all begin with a verb. When the verb does not conflict 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 with an existing Common Lisp function, then it may be used in either
its infinitival or present-participle form (e.g. @code{sum}, its infinitival or present-participle form (e.g.@: @code{sum},
@code{summing}). However, when there is a conflict with Common Lisp, @code{summing}). However, when there is a conflict with Common Lisp,
only the present-participle form may be used (e.g. @code{unioning}). only the present-participle form may be used (e.g.@: @code{unioning}).
This is to prevent @iter{} clauses from clashing with Common Lisp This is to prevent @iter{} clauses from clashing with Common Lisp
functions. functions.
@c although these clauses are described as ``producing a value,'' it @c although these clauses are described as ``producing a value,'' it
@c is a mistake to think of the lisp list representing the clause as a @c is a mistake to think of the lisp list representing the clause as a
@c value-producing form in the usual way. clauses may legally be @c value-producing form in the usual way. clauses may legally be
@c written where a value is expected, e.g. @code{(setq x (sum i))}, @c written where a value is expected, e.g.@: @code{(setq x (sum i))},
@c but the lisp value of a clause in such a context is undefined. @c but the lisp value of a clause in such a context is undefined.
@menu @menu
* Reductions:: * Reductions::
* Accumulations:: * Accumulations::
* Finders:: * Finders::
* Boolean Tests::
* Aggregated Boolean Tests:: * Aggregated Boolean Tests::
@end menu @end menu
...@@ -886,7 +889,7 @@ variable is untyped) or @math{0} (if it has a numeric type). ...@@ -886,7 +889,7 @@ variable is untyped) or @math{0} (if it has a numeric type).
@deffn Clause reducing @v{expr} @k{by} @v{func} @k{&optional} @deffn Clause reducing @v{expr} @k{by} @v{func} @k{&optional}
@k{initial-value} @v{init-val} @k{into} @v{var} @k{initial-value} @v{init-val} @k{into} @v{var}
This is a general way to perform reductions. @var{func} should be a This is a general way to perform reductions. @var{func} should be a
function of two arguments, the first of which will be the value function of two arguments, the first of which will be the value
computed so far and the second of which will be the value of computed so far and the second of which will be the value of
@var{expr}. It should return the new value. @code{reducing} is @var{expr}. It should return the new value. @code{reducing} is
...@@ -917,7 +920,7 @@ entered, so it should not depend on any value computed inside the ...@@ -917,7 +920,7 @@ entered, so it should not depend on any value computed inside the
@c ~expr~ or ~var~ can be determined to be a fixnum or a float, @c ~expr~ or ~var~ can be determined to be a fixnum or a float,
@c @iter{} will implement the clause as a true reduction, using one of @c @iter{} will implement the clause as a true reduction, using one of
@c the constants |most-negative-fixnum|, |@c most-positive-fixnum|, @c the constants |most-negative-fixnum|, |@c most-positive-fixnum|,
@c |most-negative-short-float|, etc. as appropriate.} @c |most-negative-short-float|, etc.@: as appropriate.}
@c =================================================================== @c ===================================================================
@node Accumulations @node Accumulations
...@@ -933,7 +936,7 @@ point in the loop. ...@@ -933,7 +936,7 @@ point in the loop.
@k{into} @v{var} @k{at} @v{place} @k{result-type} @v{type} @k{into} @v{var} @k{at} @v{place} @k{result-type} @v{type}
Produces a sequence of the values of @var{exptr} on each Produces a sequence of the values of @var{exptr} on each
iteration. @var{place} indicates where the next value of @var{exptr} iteration. @var{place} indicates where the next value of @var{exptr}
is added to the list and may be one of the symbols @code{start}, is added to the list and may be one of the symbols @code{start},
@code{beginning} (a synonym for @code{start}) or @code{end}. The @code{beginning} (a synonym for @code{start}) or @code{end}. The
symbol may be quoted, but need not be. The default is @code{end}. symbol may be quoted, but need not be. The default is @code{end}.
...@@ -994,7 +997,7 @@ As in Common Lisp, they work only on lists. Also as in Common Lisp, ...@@ -994,7 +997,7 @@ As in Common Lisp, they work only on lists. Also as in Common Lisp,
@deffn Clause accumulate @v{expr} @k{by} @v{func} @k{&optional} @ @deffn Clause accumulate @v{expr} @k{by} @v{func} @k{&optional} @
@k{initial-value} @v{init-val} @k{into} @v{var} @k{initial-value} @v{init-val} @k{into} @v{var}
This is a general-purpose accumulation clause. @var{func} should be a This is a general-purpose accumulation clause. @var{func} should be a
function of two arguments, the value of @var{expr} and the value function of two arguments, the value of @var{expr} and the value
accumulated so far in the iteration, and it should return the updated accumulated so far in the iteration, and it should return the updated
value. If no initial value is supplied, @code{nil} is used. value. If no initial value is supplied, @code{nil} is used.
...@@ -1033,7 +1036,7 @@ or @var{failure-value} when the epilogue code is run. ...@@ -1033,7 +1036,7 @@ or @var{failure-value} when the epilogue code is run.
As a special case, if the @var{test} expression is a sharp-quoted As a special case, if the @var{test} expression is a sharp-quoted
function, then it is applied to @var{expr} instead of being simply function, then it is applied to @var{expr} instead of being simply
evaluated. E.g. @code{(finding x such-that #'evenp)} is equivalent to evaluated. E.g.@: @code{(finding x such-that #'evenp)} is equivalent to
@code{(finding x such-that (evenp x))}. @code{(finding x such-that (evenp x))}.
@c \cpar although @var{test} need have nothing to do with ~@c expr~ as in @c \cpar although @var{test} need have nothing to do with ~@c expr~ as in
...@@ -1046,10 +1049,10 @@ evaluated. E.g. @code{(finding x such-that #'evenp)} is equivalent to ...@@ -1046,10 +1049,10 @@ evaluated. E.g. @code{(finding x such-that #'evenp)} is equivalent to
@c is slightly different from that for {\lisp 'oddp}; see the discussion @c is slightly different from that for {\lisp 'oddp}; see the discussion
@c under {\lisp for\dots in} and {\lisp for\dots on}. @c under {\lisp for\dots in} and {\lisp for\dots on}.
@code{On-failure} is a misnomer. Because it is always evaluated, it @code{On-failure} is a misnomer. Because it is always evaluated, it
behaves more like the default third argument to the @code{gethash} behaves more like the default third argument to the @code{gethash}
function. As a result, @code{on-failure (error "Not found")} makes no function. As a result, @code{on-failure (error "Not found")} makes no
sense. Instead, the clauses @code{leave} or @code{thereis} can be used sense. Instead, the clauses @code{leave} or @code{thereis} can be used
in conjunction with @code{finally} as follows: in conjunction with @code{finally} as follows:
@lisp @lisp
...@@ -1059,17 +1062,17 @@ in conjunction with @code{finally} as follows: ...@@ -1059,17 +1062,17 @@ in conjunction with @code{finally} as follows:
@end lisp @end lisp
This clause may appear multiple times when all defaults are This clause may appear multiple times when all defaults are
identical. It can also be used together with either identical. It can also be used together with either
@code{always}/@code{never} or @code{thereis} if their defaults @code{always}/@code{never} or @code{thereis} if their defaults
match. More specifically, @code{on-failure nil} is compatible with match. More specifically, @code{on-failure nil} is compatible with
@code{thereis}, while @code{on-failure t} is compatible with @code{thereis}, while @code{on-failure t} is compatible with
@code{always} and @code{never} clauses. @code{always} and @code{never} clauses.
@lisp @lisp
(iter (for i in '(7 -4 2 -3)) (iter (for i in '(7 -4 2 -3))
(if (plusp i) (if (plusp i)
(finding i such-that (evenp i)) (finding i such-that (evenp i))
(finding (- i) such-that (oddp i)))) (finding (- i) such-that (oddp i))))
@end lisp @end lisp
@end deffn @end deffn
...@@ -1087,8 +1090,8 @@ new extremum is established. If @var{m-expr} is never evaluated (due ...@@ -1087,8 +1090,8 @@ new extremum is established. If @var{m-expr} is never evaluated (due
to, for example, being embedded in a conditional clause), then the to, for example, being embedded in a conditional clause), then the
returned value depends on the type, if any, of @var{expr} (or returned value depends on the type, if any, of @var{expr} (or
@var{var}, if one is supplied). If there is no type, the returned @var{var}, if one is supplied). If there is no type, the returned
value will be \nil; if the type is numeric, the returned value will be value will be @code{nil}; if the type is numeric, the returned value
zero. will be zero.
For these two clauses, @var{var} may be a list of two symbols; in that For these two clauses, @var{var} may be a list of two symbols; in that
case, the first is used to record @var{expr} and the second, case, the first is used to record @var{expr} and the second,
...@@ -1099,33 +1102,6 @@ sharp-quoted function, then it is called on @var{expr} instead of ...@@ -1099,33 +1102,6 @@ sharp-quoted function, then it is called on @var{expr} instead of
being evaluated. being evaluated.
@end deffn @end deffn
@c ===================================================================
@node Boolean Tests
@subsection Boolean Tests
@clauseu{first-iteration-p}
@deffn Clause first-iteration-p
Returns @code{t} in the first cycle of the loop, otherwise @code{nil}.
@end deffn
@clauseu{first-time-p}
@deffn Clause first-time-p
Returns @code{t} the first time the expression is evaluated, and then
@code{nil} forever. This clause comes handy when printing (optional)
elements separated by a comma:
@lisp
(iter (for el in '(nil 1 2 nil 3))
(when el
(unless (first-time-p)
(princ ", "))
(princ el)))
@end lisp
produces @code{"1, 2, 3"}.
@end deffn
@c =================================================================== @c ===================================================================
@node Aggregated Boolean Tests @node Aggregated Boolean Tests
@subsection Aggregated Boolean Tests @subsection Aggregated Boolean Tests
...@@ -1147,7 +1123,7 @@ return @code{t}). ...@@ -1147,7 +1123,7 @@ return @code{t}).
@deffn Clause never @v{expr} @deffn Clause never @v{expr}
Like @code{(always (not @var{expr}))}, except it does not influence Like @code{(always (not @var{expr}))}, except it does not influence
the last value returned by a possible other @code{always} clause. That the last value returned by a possible other @code{always} clause. That
is, is,
@lisp @lisp
...@@ -1177,11 +1153,13 @@ implementations of @code{loop}). ...@@ -1177,11 +1153,13 @@ implementations of @code{loop}).
Several clauses can be used to alter the usual flow of control in a Several clauses can be used to alter the usual flow of control in a
loop. loop.
Note: the clauses of this and subsequent sections don't adhere to @quotation Note
The clauses of this and subsequent sections don't adhere to
@iter{}'s usual syntax, but instead use standard Common Lisp syntax. @iter{}'s usual syntax, but instead use standard Common Lisp syntax.
Hence the format for describing syntax subsequently is like the Hence the format for describing syntax subsequently is like the
standard format used in the Common Lisp manual, not like the standard format used in the Common Lisp manual, not like the
descriptions of clauses above. descriptions of clauses above.
@end quotation
@clauseu{finish} @clauseu{finish}
@deffn Clause finish @deffn Clause finish
...@@ -1202,7 +1180,7 @@ Stops the loop and runs the epilogue code. ...@@ -1202,7 +1180,7 @@ Stops the loop and runs the epilogue code.
@c @end lisp @c @end lisp
@c @c
@c this code will execute |cleanup| whether or not the test |(correct? @c this code will execute |cleanup| whether or not the test |(correct?
@c i)| ever succeeds. @c i)| ever succeeds.
@c the (more elegant) formulation, @c the (more elegant) formulation,
@c @lisp @c @lisp
@c (iter (initially (make-a-mess)) @c (iter (initially (make-a-mess))
...@@ -1237,7 +1215,7 @@ the epilogue code executed. Equivalent to @code{(if (not @var{expr}) ...@@ -1237,7 +1215,7 @@ the epilogue code executed. Equivalent to @code{(if (not @var{expr})
@end deffn @end deffn
@clauseu{until} @clauseu{until}
@deffn Clause until @v{~expr~} @deffn Clause until @v{expr}
Equivalent to @code{(if @var{expr} (finish))}. Equivalent to @code{(if @var{expr} (finish))}.
@end deffn @end deffn
...@@ -1261,6 +1239,38 @@ The only difference is that the @code{for} version makes @var{var} ...@@ -1261,6 +1239,38 @@ The only difference is that the @code{for} version makes @var{var}
available for use with @code{for@dots{} previous}. available for use with @code{for@dots{} previous}.
@end deffn @end deffn
@c ===================================================================
@node Predicates
@section Predicates
@quotation Compatibility Note
The clauses in this section were added in the twenty-first century and
not part of Jonathan Amsterdam's original design.
@end quotation
@clauseu{first-iteration-p}
@deffn Clause first-iteration-p
Returns @code{t} in the first cycle of the loop, otherwise @code{nil}.
@end deffn
@clauseu{first-time-p}
@deffn Clause first-time-p
Returns @code{t} the first time the expression is evaluated, and then
@code{nil} forever. This clause comes handy when printing (optional)
elements separated by a comma:
@lisp
(iter (for el in '(nil 1 2 nil 3))
(when el
(unless (first-time-p)
(princ ", "))
(princ el)))
@print{} 1, 2, 3
@end lisp
@end deffn
@c =================================================================== @c ===================================================================
@node Code Placement @node Code Placement
@section Code Placement @section Code Placement
...@@ -1417,14 +1427,14 @@ binding is generated for that piece of the structure). ...@@ -1417,14 +1427,14 @@ binding is generated for that piece of the structure).
Sometimes, you might like to do the equivalent of a Sometimes, you might like to do the equivalent of a
@code{multiple-value-setq} in a clause. This ``multiple-value @code{multiple-value-setq} in a clause. This ``multiple-value
destructuring'' can be expressed by writing @code{(values @var{pat1} destructuring'' can be expressed by writing @code{(values @var{pat_1}
@var{pat2} @dots{})} for a destructuring pattern, as in @var{pat_2} @dots{})} for a destructuring pattern, as in
@lisp @lisp
(for (values (a . b) c d) = (three-valued-function ...)) (for (values (a . b) c d) = (three-valued-function ...))
@end lisp @end lisp
Note that the @var{pati} can themselves be destructuring patterns Note that the @var{pat_i} can themselves be destructuring patterns
(though not multiple-value destructuring patterns). You can't do (though not multiple-value destructuring patterns). You can't do
multiple-value destructuring in a @code{with} clause; instead wrap the multiple-value destructuring in a @code{with} clause; instead wrap the
whole @iter{} form in a @code{multiple-value-bind}. whole @iter{} form in a @code{multiple-value-bind}.
...@@ -1442,7 +1452,7 @@ mechanism, using the @code{dsetq} macro: ...@@ -1442,7 +1452,7 @@ mechanism, using the @code{dsetq} macro:
@defmac dsetq @v{template} @v{expr} @defmac dsetq @v{template} @v{expr}
Performs destructuring of @var{expr} using @var{template}. May be Performs destructuring of @var{expr} using @var{template}. May be
used outside of an @iter{} form. Yields the primary value of used outside of an @iter{} form. Yields the primary value of
@var{expr}. @var{expr}.
@end defmac @end defmac
...@@ -1530,7 +1540,7 @@ code by avoiding error-checks; the resulting problems would be doubly ...@@ -1530,7 +1540,7 @@ code by avoiding error-checks; the resulting problems would be doubly
hard to track down because the declarations would be hidden from the hard to track down because the declarations would be hidden from the
programmer. Of course, a compiler might omit error-checks even in the programmer. Of course, a compiler might omit error-checks even in the
absence of declarations, though this behavior can usually be avoided, absence of declarations, though this behavior can usually be avoided,
e.g. by saying @code{(declaim (optimize (safety 3)))}. e.g.@: by saying @code{(declaim (optimize (safety 3)))}.
So, the above @iter{} form will generate code with no declarations. So, the above @iter{} form will generate code with no declarations.
But say we wish to declare the types of @code{el} and the internal But say we wish to declare the types of @code{el} and the internal
...@@ -1778,13 +1788,13 @@ mentioned in this list. ...@@ -1778,13 +1788,13 @@ mentioned in this list.
density of parens. density of parens.
@item @item
The current implementation of @iter{}, unlike the current version of The current implementation of @iter{}, unlike the standardised version
@code{loop} (as documented in @emph{Common Lisp, 2nd Ed.}), is of @code{loop}, is extensible (see @ref{Rolling Your Own}).
extensible (see @ref{Rolling Your Own}).
@item @item
@code{loop} puts the updates of all driver variables at the top of the @code{loop} puts the updates of all driver variables at the top of the
loop; @iter{} leaves them where the driver clauses appear. loop; @iter{} leaves them where the driver clauses appear. In