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

Re: LOOP



    Date: 17 November 1980 1938-EST (Monday)
    From: Guy.Steele at CMU-10A

    (a) There is a "dangling AND" problem, similar to the "dangling ELSE"
        problem with IF-THEN-ELSE.  Suppose I write:
    	(LOOP FOR I IN LIST-OF-INTEGERS
                  WHEN (ODDP I)
                    DO (FORMAT T "~%~D is odd" I)
                    AND WHEN (ZEROP (REMAINDER I 3))
    		      DO (FORMAT T " and divisible by 3")
                    AND (FORMAT T "."))

There are certain features I like about LOOP, but the ability to write code
which looks like the above is not one of them.  That is, I don't care for
this attempt to create an algebraic-syntax language within Lisp.  We can
just as easily (and more clearly, in my Aunt Agathoid opinion) write

    (LOOP FOR I IN LIST-OF-INTEGERS
	  DO (WHEN (ODDP I)
		   (FORMAT T "~%~D is odd" I)
		   (WHEN (ZEROP (REMAINDER I 3))
			 (FORMAT T " and divisible by 3"))
		   (FORMAT T ".")))

where (WHEN X . Y) is an abbreviation for (COND (X . Y)).
I classify LOOP's features into three catagories:

(1) The ease with which one can construct "data sources", as in

    (LOOP FOR X IN LIST-1
	  FOR Y IN LIST-2
	  FOR I FROM 1 TO N
	  DO ...)

where we don't have to worry about cdr'ing, car'ing, incrementing, and
end-testing by hand.

(2) The ease with which one can construct "data sinks", like COLLECT,
APPEND, MAXIMIZE, SUM, COUNT, and THEREIS.

(3) Various "control" features, like ALWAYS, NEVER, and FINALLY.

It is not the LOOP keywords I object to.  They seem essential for anything
of this complexity, and we seem to be moving in that direction anyway.  It
is their infix nature.  I would prefer to see a syntax of the form

    (LOOP (IN-LIST X LIST-1)
	  (IN-LIST Y LIST-2)
	  (INCREMENT I 1 N)
	  (ALWAYS (> Y 3))
	  (DO ...)
	  (FINALLY ...))

Other keywords might be IN-VECTOR, ON-LIST, etc. [along the lines of what
LOOP provides], and a keyword like AND for parallel assignment, e.g.

    (LOOP (AND (REPEAT CHAR (TYI))
	       (REPEAT OLD-CHAR NIL CHAR))
	  (DO ...))

Where the REPEAT keyword is meant to describe something like
LOOP's FOR X = ... THEN ...

The problem arises when we try to implement the class of features mentioned
under (2).  Correct me if I'm wrong, but it appears that the only reason the
LOOP keyword WHEN is needed [as opposed to writing DO (COND ...)]  is in
conjunction with the "data source" facilities [COLLECT, COLLECT-INTO,
MAXIMIZE, SUM, THEREIS].  We want forms like (COLLECT X) to appear
arbitrarily deep in nested CONDS, which may contain vanilla Lisp forms as
well.  Unfortunately, COLLECT is not an isolated special form, but a part of
LOOP's syntax.  I don't see a simple solution to this, other than doing a
hairy analysis/macro-expansion of code at macro-expand time, as is done by
MC:ALAN;COMLET.