[LISPWORKS][Common Lisp HyperSpec (TM)] [Previous][Up][Next]



Forum: X3J13 Letter Ballot

References: LOOP syntax (X3J13/92-102 pp6-2..6-5)


Edit history: 16-Jun-93, Version 1 by Pitman

Status: Proposal REPAIR passed (7+3)-1 on letter ballot 93-304.

Problem Description:

The LOOP syntax in the first dpANS all screwed up.


Affirm that the following changes to the source relating to LOOP syntax

are in fact editorial and that nothing has been broken. Note that several

recently passed cleanups are implicitly included in this writeup.

A typeset version of this code should have been attached for the reader's

convenience, but the TeX source code is what is being voted upon and kept

as a record. This requires a new TeX macro library, not included.

Note that two new notations are used to make this work:

[[ { x }1 | { y }* ]]

means that x can occur anywhere, but exactly once (it is not optional).


[[ x | y | ... ]]+

means that at least one of the enclosed options must be selected.

(Appropriate text has been added to Section 1.4 to explain this new

notational extension.)

\input setup % -*- Mode: TeX -*-


%%% ========== LOOP


\label Syntax::

The ``simple'' \macref{loop} \term{form}:

\DefmacWithValues loop {\starparam{compound-form}} {\starparam{result}}

The ``extended'' \macref{loop} \term{form}:

\DefmacWithValues loop {\brac{\down{name-clause}}


\stardown{main-clause}} {\starparam{result}}

\auxbnf{name-clause}{\loopref{named} \param{name}}

\auxbnf{variable-clause}{\down{with-clause} | \down{initial-final} | \down{for-as-clause}}


{\loopref{with} \param{var1} \brac{\param{type-spec}} \brac{$=$ \param{form1}}

\star{\curly{\loopref{and} \param{var2} \brac{\param{type-spec}}

\brac{$=$ \param{form2}}}}}


{\down{unconditional} |

\down{accumulation} |

\down{conditional} |

\down{end-test} |



{\loopref{initially} \plusparam{form} | \loopref{finally} \plusparam{form}}


{\curly{\loopref{do} | \loopref{doing}} \plusparam{form} |

\loopref{return} \param{form}}

\auxbnf{accumulation}{\down{list-accumulation} | \down{numeric-accumulation}}


{\curly{\loopref{collect} | \loopref{collecting} |

\loopref{append} | \loopref{appending} |

\loopref{nconc} | \loopref{nconcing}} \param{form} \CR

\brac{\loopref{into} \param{var}}}


{\curly{\loopref{count} | \loopref{counting} |

\loopref{sum} | \loopref{summing} | \CR

\xcurly\loopref{maximize} | \loopref{maximizing} |

\loopref{minimize} | \loopref{minimizing}} \param{form} \CR

\brac{\loopref{into} \param{var}} \brac{\param{type-spec}}}


{\curly{\loopref{if} | \loopref{when} | \loopref{unless}} \param{form}

\param{selectable-clause} \star{\curly{\loopref{and} \param{selectable-clause}}} \CR


\param{selectable-clause} \star{\curly{\loopref{and} \param{selectable-clause}}}} \CR


%% I flushed the clause/clause1/clause2 distinction in the next thing, since it's not used

%% anywhere for reference, and it's not appropriate to the bnf style.

%% However, I'm concerned about the loss of IT here due to LOOP-MISCELLANEOUS-REPAIRS.

%% -kmp 4-May-93

\auxbnf{selectable-clause}{\down{unconditional} | \down{accumulation} | \down{conditional}}


{\loopref{while} \param{form} |

\loopref{until} \param{form} |

\loopref{repeat} \param{form} |

\loopref{always} \param{form} |

\loopref{never} \param{form} |

\loopref{thereis} \param{form}}


{\curly{\loopref{for} | \loopref{as}} \down{for-as-subclause}

\star{\curly{\loopref{and} \down{for-as-subclause}}}}


{\down{for-as-arithmetic} |

\down{for-as-in-list} |

\down{for-as-on-list} |

\down{for-as-equals-then} |\CR

\down{for-as-across} |

\down{for-as-hash} |


\auxbnf{for-as-arithmetic}{\param{var} \brac{\param{type-spec}}



{\down{arithmetic-up} | \down{arithmetic-downto} | \down{arithmetic-downfrom}}


{\begininterleave\curly{\loopref{from} | \loopref{upfrom}} \param{form1} |

\extrainterleave\curly{\loopref{to} | \loopref{upto} | \loopref{below}} \param{form2} |

\extrainterleave\loopref{by} \param{form3}\endinterleave\prevplus}


{\begininterleave\one{\curly{\loopref{from} \param{form1}}} |

\extrainterleave\one{\curly{\curly{\loopref{downto} | \loopref{above}} \param{form2}}} |

\extrainterleave\loopref{by} \param{form3}\endinterleave}


{\begininterleave\one{\curly{\loopref{downfrom} \param{form1}}} |

\extrainterleave\curly{\loopref{to} | \loopref{downto} | \loopref{above}} \param{form2} |

\extrainterleave\loopref{by} \param{form3}\endinterleave}


{\param{var} \brac{\param{type-spec}}

\loopref{in} \param{form1} \brac{\loopref{by} \param{step-fun}}}


{\param{var} \brac{\param{type-spec}}

\loopref{on} \param{form1} \brac{\loopref{by} \param{step-fun}}}


{\param{var} \brac{\param{type-spec}}

$=$ \param{form1} \brac{\loopref{then} \param{form2}}}


{\param{var} \brac{\param{type-spec}}

\loopref{across} \param{vector}}


{\param{var} \brac{\param{type-spec}}

\loopref{being} \curly{\loopref{each} | \loopref{the}} \CR

\lcurly\curly{\loopref{hash-key} | \loopref{hash-keys}}

\curly{\loopref{in} | \loopref{of}} \param{hash-table} \CR

\xcurly\brac{\loopref{using} \paren{\loopref{hash-value} \param{other-var}}} | \CR

\xcurly\curly{\loopref{hash-value} | \loopref{hash-values}}

\curly{\loopref{in} | \loopref{of}} \param{hash-table} \CR

\xcurly\brac{\loopref{using} \paren{\loopref{hash-key} \param{other-var}}}\rcurly}


{\param{var} \brac{\param{type-spec}}

\loopref{being} \curly{\loopref{each} | \loopref{the}} \CR

\lcurly\loopref{symbol} | \loopref{symbols} |\CR

\xcurly\loopref{present-symbol} | \loopref{present-symbols} |\CR

\xcurly\loopref{external-symbol} | \loopref{external-symbols}\rcurly \CR

\brac{\curly{\loopref{in} | \loopref{of}} \param{package}}}

\auxbnf{type-spec}{\down{simple-type-spec} | \down{destructured-type-spec}}


{\declref{fixnum} | \declref{float} | \declref{t} | \declref{nil}}

\auxbnf{destructured-type-spec}{\loopref{of-type} \param{d-type-spec}}


{\param{type-specifier} | \f{(\param{d-type-spec} . \param{d-type-spec})}}

\label Arguments and Values::

\param{compound-form}---a \term{compound form}.

\param{name}---a \term{symbol}.

\param{var}, \param{var1}, \param{var2}, \param{other-var}---a \term{symbol}

(a \term{variable} \term{name}).

\param{form}, \param{form1}, \param{form2}, \param{form3}---a \term{form}.


\param{step-fun}---a \term{form} that evaluates to a \term{function} of one \term{argument}.


\param{vector}---a \term{form} that evaluates to a \term{vector}.

\param{hash-table}---a \term{form} that evaluates to a \term{hash table}.

\param{package}---a \term{form} that evaluates to a \term{package designator}.

\param{type-specifier}---a \term{type specifier}.

\param{result}---an \term{object}.

\label Description::

%!!! This should be elaborated slightly here.

For details, \seesection\LoopFacility.

\label Examples::


;; An example of the simple form of LOOP.

(defun sqrt-advisor ()

(loop (format t "~&Number: ")

(let ((n (parse-integer (read-line) :junk-allowed t)))

(when (not n) (return))

(format t "~&The square root of ~D is ~D.~%" n (sqrt n)))))



\OUT Number: \IN{5\CRLF}

\OUT The square root of 5 is 2.236068.

\OUT Number: \IN{4\CRLF}

\OUT The square root of 4 is 2.

\OUT Number: \IN{done\CRLF}


;; An example of the extended form of LOOP.

(defun square-advisor ()

(loop as n = (progn (format t "~&Number: ")

(parse-integer (read-line) :junk-allowed t))

while n

do (format t "~&The square of ~D is ~D.~%" n (* n n))))



\OUT Number: \IN{4\CRLF}

\OUT The square of 4 is 16.

\OUT Number: \IN{23\CRLF}

\OUT The square of 23 is 529.

\OUT Number: \IN{done\CRLF}


;; Another example of the extended form of LOOP.

(loop for n from 1 to 10

when (oddp n)

collect n)

\EV (1 3 5 7 9)


\label Affected By:\None.

\label Exceptional Situations:\None.

%!!! Barmar: The description mentions several places where PROGRAM-ERROR is signaled.

\label See Also::

\macref{do}, \macref{dolist}, \macref{dotimes},

\macref{return}, \specref{go}, \specref{throw}

\label Notes::

The simple form of \macref{loop} is related to the extended form

in the following way:


(loop \starparam{compound-form}) \EQ (loop do \starparam{compound-form})





Test Case:



What was there was utterly broken, so how could we do worse?

Current Practice:


Cost to Implementors:

Hopefully very small. This is not really supposed to be a change,

just a clarification for readability.

Cost to Users:

Hopefully very small. This is not really supposed to be a change,

just a clarification for readability.

Cost of Non-Adoption:

A hopelessly messed up description of LOOP's syntax.


Using LOOP just from the documentation will be possible.

Editorial Impact:

This affirms work already done.


What was there was so broken that this is unquestionably an improvement.


Pitman thinks this is just a rubber stamp, and that only editorial changes

have been made here. He just wanted the committee to have a chance to

double-check this work specially.

[Starting Points][Contents][Index][Symbols][Glossary][Issues]
Copyright 1996-2005, LispWorks Ltd. All rights reserved.