From: Kjeld Larsen
Subject: Loop macro - why?
Date: 
Message-ID: <C4EACt.29E@stl.dk>
Loop macro considered harmful??!!

In a recent thread this code didn't work:

(defun addlist (list num)
  (mapcar #'(lambda (x) (+ x num)) list) )

Of course it should work, but one helpful person suggested to  try this instead:

(defun f1 (list num)
  (loop for n in list
	collect (+ n num)))

-- which reminded us:

Some years ago we both did extensive Common Lisp programming, and we never did
use the loop macro at all. For a number of reasons:

- it's not Lisp, neither syntactically nor semantically
- it's ugly
- and you never need it - it's all there in Lisp as is...

At that time the macro was not part of Common Lisp, and we realize that it
is now. But why?

Are there any good reasons to use the loop macro? And those of you who do
use it - what are you using it for?

-- Kjeld and Flemming

From: Hans Tallis
Subject: Re: Loop macro - why?
Date: 
Message-ID: <tallis.732988528@starbase>
In <··········@stl.dk> ···@stl.dk (Kjeld Larsen) writes:

>Some years ago we both did extensive Common Lisp programming, and we never did
>use the loop macro at all. For a number of reasons:

>- it's not Lisp, neither syntactically nor semantically
>- it's ugly
>- and you never need it - it's all there in Lisp as is...

>At that time the macro was not part of Common Lisp, and we realize that it
>is now. But why?

>Are there any good reasons to use the loop macro? And those of you who do
>use it - what are you using it for?


This came up a year ago.  Loop-fanatics like me use loop to replace all
iteration (do, do*, etc.) and mapping (mapcan, mapcon, etc.) constructs.  One
form replaces a good dozen or so.  

	1. Whether this is ugly is in the eye of the beholder. 
	2. I can't remember the difference between mapcons and maplist (or
	whatever their names are), so for me it's a simple matter of saving
	CLtL reference time by going with the loop macro.  I can also debug a
	buggy loop form more quickly than a mapXXX typo.
	3. The loop macro is undeniably more readable than the forms it
	replaces, and if you're serious about software engineering (meaning:
	making it easy for others to read your code) then loop is the only way
	to go.  I know that my code is regularly read by lisp-neophytes, and
	loop's syntax is much easier for them to decipher.

--Hans
From: Barry Margolin
Subject: Re: Loop macro - why?
Date: 
Message-ID: <1oq4m9INNse4@early-bird.think.com>
In article <··········@stl.dk> ···@stl.dk (Kjeld Larsen) writes:
>Some years ago we both did extensive Common Lisp programming, and we never did
>use the loop macro at all. For a number of reasons:
>
>- it's not Lisp, neither syntactically nor semantically
>- it's ugly
>- and you never need it - it's all there in Lisp as is...

The first two reasons are obvious and I think many Lispers agree with them,
but the third is harder to swallow.  Sure, you don't "need" LOOP, but you
don't "need" REMOVE either; they can both be replaced with uses of more
primitive constructs.  But Common Lisp attempts to provide a large built-in
library of common programming constructs so that programmers aren't forced
to recode these basic facilities (I always laugh whenever I see a Prolog
program, since they all seem to start with the same definition of
"member").  Furthermore, by building it into the language we enable
implementors to optimize it better (the Symbolics implementation of LOOP's
COLLECT verb makes use of a locative (a low-level pointer) to point to the
loop tail).

>At that time the macro was not part of Common Lisp, and we realize that it
>is now. But why?

It was a tough decision, but basically it was added because it is in
widespread use (most commercial CLs include it, and postings here looking
for the portable version were common), it fills a hole in the language
(X3J13's charter included addition of a powerful iteration and collection
facility to the language), and it was better to standardize it than to
continue the current proliferation of incompatible variants.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Don Geddis
Subject: Re: Loop macro - why?
Date: 
Message-ID: <1993Mar25.015305.27865@CSD-NewsHost.Stanford.EDU>
In article <··········@stl.dk>, ···@stl.dk (Kjeld Larsen) writes:
> - it's not Lisp, neither syntactically nor semantically
> - it's ugly
> - and you never need it - it's all there in Lisp as is...
> Are there any good reasons to use the loop macro? And those of you who do
> use it - what are you using it for?

When you need iteration with lots of options, you degenerate to the "do" form.
This gets really opaque.  Consider translating a simple "dolist" form into
the "do" version (which might be necessary if lots of other iteration
dependecies were needed):
	(let ((answer-list nil))
	  (dolist (x *big-list*)
	    (push (1+ x) answer-list) )
	  (reverse answer-list) )
becomes
	(do ((answer-list nil)
	     (remainder *big-list* (cdr remainder))   ; These three lines
	     (x (car remainder) (car remainder)) )    ; mimic DOLIST, but it's
	   ((null remainder)                          ; not that clear...
	    (reverse answer-list) )
	  (push (1+ x) answer-list) )

I don't know about you, but it's _much_ easier for me to understand this
oh-so-common idiom with the extended loop:

	(loop for x in *big-list*
	      collect (1+ x) )

Of course, for this example you can use a "mapcar" as well, but that
shouldn't obscure the point:  You can concisely get the effect of "dolist"
or the other iteration constructs, while still being tremendously flexible
if you need to do more complicated things.  "do" is flexible, but not
readable.

	-- Don
-- 
Don Geddis (······@CS.Stanford.Edu)
You possess a mind not merely twisted, but actually sprained.
From: Raul Valdes-Perez
Subject: Re: Loop macro - why?
Date: 
Message-ID: <C4G8qI.3Ky.1@cs.cmu.edu>
In article <··········@stl.dk>, ···@stl.dk (Kjeld Larsen) writes:
|> 
|> Loop macro considered harmful??!!
|> ...
|> Are there any good reasons to use the loop macro? And those of you who do
|> use it - what are you using it for?
|> 

If you even think of getting rid of the Loop macro, I will be demonstrating
in the streets of Copenhagen.

Seriously, though, here's one reason to add to the others.  I was giving
some advice to colleagues in our psychology department who intend to
freely distribute a lisp implementation of a psychological model.  The
code was written (adapted, actually) by non-CS types and was horribly 
unreadable, partly because it looked fairly BASIC-like.  After introducing
the programmer to the Loop macro, he fell in love with it, and his code
is much more intelligible, and probably less buggy also.

In my own work, I find Loop wonderful for the immediate or rapid transformation
of an algorithmic idea into testable code.  Maybe I'm just too impatient,
but it's gratifying to know that some language designers are indulging my
peccadillos.

-- 
Raul E. Valdes-Perez		    ······@cs.cmu.edu
Carnegie Mellon University	    (412) 268-7127
From: Rainer Joswig
Subject: Re: Loop macro - why?
Date: 
Message-ID: <joswig-260393114525@kimac1.informatik.uni-hamburg.de>
In article <············@cs.cmu.edu>, ·······@CS.CMU.EDU (Raul
Valdes-Perez) wrote:
> In my own work, I find Loop wonderful for the immediate or rapid transformation
> of an algorithmic idea into testable code.  Maybe I'm just too impatient,
> but it's gratifying to know that some language designers are indulging my
> peccadillos.

I personally prefer the ITERATE macro, because it looks more like Lisp.
But, I have to confess, I'm using the LOOP-macro quite often. And sometimes
I'm using more functional constructs. So it is all a matter of taste.

I wish Common Lisp would have ITERATE and not LOOP. ITERATE can
do most of the things LOOP can do and is extensible (well,
there are extensible versions of the LOOP-macro).

Rainer Joswig
······@informatik.uni-hamburg.de
From: Richard Fateman
Subject: Re: Loop macro - why?
Date: 
Message-ID: <1ov5j3$fd7@agate.berkeley.edu>
I think there is a philosophical justification for the inclusion or
exclusion of features in common lisp that explains the inclusion of the
Loop macro.

1. If, in the normal (sophisticated, professional ...) usage  of lisp,
one might reasonably expect many users to come up with a feature that
provides a certain capability  X,
2. If capability X might be implemented in a variety of similar but
not exactly identical ways, and with different minor variations,
3. and the up-holders of the standard for CL can come up with a single
version that satisfies them all (in terms of semantics, efficiency, etc.)
as a way of providing capability X

then CL should standardly provide the feature.

This will make programs in the language more easily readable for others.


This does not necessarily produce truth, beauty, simplicity, or universal
satisfaction.  

-- 
Richard J. Fateman
·······@cs.berkeley.edu   510 642-1879
From: Jeff Dalton
Subject: Re: Loop macro - why?
Date: 
Message-ID: <8558@skye.ed.ac.uk>
I don't often use LOOP.  However, I don't use DO very much either.
In a number of cases, I prefer LOOP to DO or even to DOTIMES.

My most common use of LOOP is for numeric iteration.  I can
read LOOP directly, while for a DO or tail-recursion I would
have to do more work to figure out what sequence of values was
involved.  I've written code in which I tried to avoid LOOP
but eventually had to give up and resort to LOOP after all.

I hardly ever use LOOP for lists, though.  I almost always use
sequence functions or recursion.


In article <···················@kimac1.informatik.uni-hamburg.de> ······@informatik.uni-hamburg.de (Rainer Joswig) writes:

>I personally prefer the ITERATE macro, because it looks more like Lisp.
>But, I have to confess, I'm using the LOOP-macro quite often. And sometimes
>I'm using more functional constructs. So it is all a matter of taste.

Is this the ITERATE macro that's a named-LET?  Eg, to sum a list of
numbers you'd write:

  (iterate sum ((numbers list-of-numbers)
                (result 0))
    (if (null numbers)
        result
      (sum (cdr numbers) (+ (car numbers) result))))

If so, it's trivial to write it as a macro.  Most CLs optimize
self-tail-recursion, so you can even write it in the obvious way.

-- jd