From: Sungwoo Lim
Subject: [Q] ELSE in LOOP
Date: 
Message-ID: <sungwoo-0504011541150001@gorecki.cad.strath.ac.uk>
Hello,

I confused to use ELSE in LOOP.
Anyone explain me why following code is wrong?
Also, is it right to use RETURN NIL when the ELSE doesn't 
has any clause?

;----------------
(loop for i from 0 to 10
      when (evenp i)
           do (print i)
           when (= i 6)
                do (print 'BINGO!!)
           else
                return nil
      else
           do (print 'odd))
> Error: Secondary clause misplaced at top level in LOOP macro: ELSE DO
(PRINT 'ODD) ...
>        Current LOOP context: ELSE DO.


Thanks for your help.

Sungwoo

-- 
<^)++<

From: Barry Margolin
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <TF%y6.291$U4.10880@burlma1-snr2>
In article <························@gorecki.cad.strath.ac.uk>,
Sungwoo Lim <·······@cad.strath.ac.uk> wrote:
>Hello,
>
>I confused to use ELSE in LOOP.
>Anyone explain me why following code is wrong?
>Also, is it right to use RETURN NIL when the ELSE doesn't 
>has any clause?
>
>;----------------
>(loop for i from 0 to 10
>      when (evenp i)
>           do (print i)
>           when (= i 6)
>                do (print 'BINGO!!)
>           else
>                return nil
>      else
>           do (print 'odd))
>> Error: Secondary clause misplaced at top level in LOOP macro: ELSE DO
>(PRINT 'ODD) ...
>>        Current LOOP context: ELSE DO.

I think indenting it correctly might clarify the problem:

(loop for i from 0 to 10
      when (evenp i)
           do (print i)
      when (= i 6)
	   do (print 'BINGO!!)
      else
	   return nil
  else
       do (print 'odd))

The second WHEN ends the first WHEN, so the second ELSE is dangling.

The body of a DO clause is just regular Lisp expressions, and it ends when
the first symbol is encountered.  You can't have a WHEN inside a DO; if you
want conditionals inside the DO clause, you have to use a regular (if ...)
invocation:

(loop for i from 0 to 10
      when (evenp i)
           do (print i)
              (if (= i 6)
		  (print 'BINGO!!)
                  (return nil))
      else
	   do (print 'odd))

I like LOOP, but I have a general rule of thumb about it: the more complex
a LOOP gets, the less appropriate it is to use.  It's great for some simple
constructs that it automates, such as collecting results, but if you try to
do too many things with it at once you're likely to run into problems, and
you should go back to "normal" Lisp code.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Sungwoo Lim
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <sungwoo-0504011630530001@gorecki.cad.strath.ac.uk>
In article <··················@burlma1-snr2>, Barry Margolin
<······@genuity.net> wrote:

> I think indenting it correctly might clarify the problem:
> 
> (loop for i from 0 to 10
>       when (evenp i)
>            do (print i)
>       when (= i 6)
>            do (print 'BINGO!!)
>       else
>            return nil
>   else
>        do (print 'odd))
> 
> The second WHEN ends the first WHEN, so the second ELSE is dangling.
> 
> The body of a DO clause is just regular Lisp expressions, and it ends when
> the first symbol is encountered.  You can't have a WHEN inside a DO; if you
> want conditionals inside the DO clause, you have to use a regular (if ...)
> invocation:
> 
> (loop for i from 0 to 10
>       when (evenp i)
>            do (print i)
>               (if (= i 6)
>                   (print 'BINGO!!)
>                   (return nil))
>       else
>            do (print 'odd))
> 
> I like LOOP, but I have a general rule of thumb about it: the more complex
> a LOOP gets, the less appropriate it is to use.  It's great for some simple
> constructs that it automates, such as collecting results, but if you try to
> do too many things with it at once you're likely to run into problems, and
> you should go back to "normal" Lisp code.

I see...

My codes mixed two hierarchical LOOP and four hierarchical WHEN, so I was
struggling to solve it. I should change it as a easy way then...
Thanks alot. =)

Sungwoo

-- 
<^)++<
From: Sungwoo Lim
Subject: Eh? where are last posts?
Date: 
Message-ID: <sungwoo-0604010900260001@gorecki.cad.strath.ac.uk>
Where are they?
There were couple of answers more for my question but thety disappeared?
Strange..

Sungwoo

-- 
<^)++<
From: Michael Kappert
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <3ACC9274.5327004A@iitb.fhg.de>
Sungwoo Lim schrieb:
> 
> Hello,
> 
> I confused to use ELSE in LOOP.
> Anyone explain me why following code is wrong?
> Also, is it right to use RETURN NIL when the ELSE doesn't
> has any clause?
> 
> ;----------------
> (loop for i from 0 to 10
>       when (evenp i)
>            do (print i)
>            when (= i 6)
>                 do (print 'BINGO!!)
>            else
>                 return nil
>       else
>            do (print 'odd))
> > Error: Secondary clause misplaced at top level in LOOP macro: ELSE DO
> (PRINT 'ODD) ...
> >        Current LOOP context: ELSE DO.

You can't use DO to group statements containing LOOP keywords,
because a LOOP keyword implicitly terminates the DO body.
Use AND to join the statements in a WHEN branch.

RETURN terminates the loop. If you didn't mean to terminate on the
first even number, use a dummy else branch.

As a matter of style, i suggest using IF instead of WHEN
if (err, when :-)) the ELSE branch is present.
 
So, your code would appear as

(loop for i from 0 to 10
    if (evenp i)
      do (print i)
      and if (= i 6)
            do (print 'BINGO!!)
          else do ()
    else
      do (print 'odd)) 

which gives

0 
odd 
2 
odd 
4 
odd 
6 
bingo!! 
odd 
8 
odd 
10 
odd 
nil

However, I'd advise you to use the conditional keywords only in very
simple cases. When things get more complicated, use normal Lisp forms
instead:

(loop for i from 0 to 10 do
      (cond ((evenp i)
	     (print i)
	     (when (= i 6) (print 'bingo!!)))
	    (T
	     (print 'odd))))

Michael

--
From: Frode Vatvedt Fjeld
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <2hsnjn2vrz.fsf@dslab7.cs.uit.no>
[I first replied privately in email by mistake. Sorry about that.]

·······@cad.strath.ac.uk (Sungwoo Lim) writes:

> I confused to use ELSE in LOOP.  Anyone explain me why following
> code is wrong?

I think you are confused not about the use of ELSE, but of the purpose
of LOOP's conditional constructs.

Their purpose is primarily to control the execution of LOOP's value
accumulation clauses. At least it helps to think of them this
way. That is, LOOP's conditional execution clauses are _not_ to be
used as general control structures, substituting the regular lisp
control structures.

So my rule of thumb would be: Use LOOP's conditional execution clauses
only where you can't use the regular lisp control operators.

(My second rule of thumb concerning LOOP would be the negative of
Barry Margolin's: The more complex the looping, the more you need/want
to use LOOP.)

> ;----------------
> (loop for i from 0 to 10
>       when (evenp i)
>            do (print i)
>            when (= i 6)
>                 do (print 'BINGO!!)
>            else
>                 return nil
>       else
>            do (print 'odd))

This is not a good example because it's not very realistic. And you
can't nest clauses like that. If you have a more realistic example,
it'd be easier to suggest improvements.

In general however, you need to factor out the loop termination
condition(s), you don't want them embedded deep in other
code. Applying this to your contrieved example you'd get something
like this (it still doesn't make sense):

  (loop for i from 0 to 10
     as terminate = (and (evenp i) (not (= i 6)))
     do (cond
          ((evenp i)
           (print i)
           (when (= i 6) (print 'bingo)))
          (t (print 'odd)))
     until terminate)

If you _really_ need to terminate your loop from deep within other
functional code, consider using RETURN-FROM or throwing a
condition. I'd expect this to be _very_ infrequently required, though.

-- 
Frode Vatvedt Fjeld
From: Sungwoo Lim
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <sungwoo-0504011717270001@gorecki.cad.strath.ac.uk>
In article <··············@dslab7.cs.uit.no>, Frode Vatvedt Fjeld
<······@acm.org> wrote:


> This is not a good example because it's not very realistic. And you
> can't nest clauses like that. If you have a more realistic example,
> it'd be easier to suggest improvements.

OK, here is the part of my code. Still confused, 
so I am trying to change the WHEN and ELSE in LOOP to IF clauses (or may
be COND is better?).
Thanks for your help.

Sungwoo

;-----------
(loop for i from 0 to stroke-index
      when (= (aref stroke-array-y i) (dialine-y1 (aref stroke-array-x i))) 
          when (and (> (aref stroke-array-x i) max-inter-x) 
                    (> (aref stroke-array-y i) max-inter-y))
              do (setf max-inter-x (aref stroke-array-x i) 
                       max-inter-y (aref stroke-array-y i))
          else 
              when (and (< (aref stroke-array-x i) min-inter-x) 
                        (< (aref stroke-array-y i) min-inter-y))
                  do (setf min-inter-x (aref stroke-array-x i) 
                           min-inter-y (aref stroke-array-y i))
              else
                  return nil
      else
          when (/= deno 0)
              do (setf Ua (/ numer1 deno) Ub (/ numer2 deno))
              when (and (<= 0 Ua 1) (<= 0 Ub 1) (/= x1 x3) (/= y1 y3))
                  do (setf temp-x (float (+ x1 (* Ua (- x2 x1)))) 
                           temp-y (float (+ y1 (* Ua (- y2 y1)))))
                  when (and (> temp-x max-inter-x) (> temp-y max-inter-y))
                      do (setf max-inter-x temp-x max-inter-y temp-y)
                  else
                      when (and (< temp-x min-inter-x) (< temp-y min-inter-y))
                          do (setf min-inter-x temp-x min-inter-y temp-y))

-- 
<^)++<
From: Michael Kappert
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <3ACC9E70.451CDE5D@iitb.fhg.de>
Sungwoo Lim schrieb:
> 
> In article <··············@dslab7.cs.uit.no>, Frode Vatvedt Fjeld
> <······@acm.org> wrote:
> 
> > This is not a good example because it's not very realistic. And you
> > can't nest clauses like that. If you have a more realistic example,
> > it'd be easier to suggest improvements.
> 
> OK, here is the part of my code. Still confused,
> so I am trying to change the WHEN and ELSE in LOOP to IF clauses (or may
> be COND is better?).
> Thanks for your help.
> 
> Sungwoo
> 
> ;-----------
> (loop for i from 0 to stroke-index
>       when (= (aref stroke-array-y i) (dialine-y1 (aref stroke-array-x i)))
>           when (and (> (aref stroke-array-x i) max-inter-x)
>                     (> (aref stroke-array-y i) max-inter-y))
>               do (setf max-inter-x (aref stroke-array-x i)
>                        max-inter-y (aref stroke-array-y i))
>           else
>               when (and (< (aref stroke-array-x i) min-inter-x)
>                         (< (aref stroke-array-y i) min-inter-y))
>                   do (setf min-inter-x (aref stroke-array-x i)
>                            min-inter-y (aref stroke-array-y i))
>               else
>                   return nil
                    ^^^^^^
This terminates the loop alltogether. Do you want that?
The first part of the loop seems to search some kind of convex
hull, so i think you must loop over all points (if the sequence
of points is monotonic, this makes no sense).
You might want to look into scanline algorithms & such.

>       else
>           when (/= deno 0)
>               do (setf Ua (/ numer1 deno) Ub (/ numer2 deno))
>               when (and (<= 0 Ua 1) (<= 0 Ub 1) (/= x1 x3) (/= y1 y3))
>                   do (setf temp-x (float (+ x1 (* Ua (- x2 x1))))
>                            temp-y (float (+ y1 (* Ua (- y2 y1)))))
>                   when (and (> temp-x max-inter-x) (> temp-y max-inter-y))
>                       do (setf max-inter-x temp-x max-inter-y temp-y)
>                   else
>                       when (and (< temp-x min-inter-x) (< temp-y min-inter-y))
>                           do (setf min-inter-x temp-x min-inter-y temp-y))
> 
> --
> <^)++<

--
From: Sungwoo Lim
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <sungwoo-0504011747200001@gorecki.cad.strath.ac.uk>
In article <·················@iitb.fhg.de>, Michael Kappert
<···@iitb.fhg.de> wrote:

> This terminates the loop alltogether. Do you want that?

No, I don't want it. Yeap, that was what I didn't know.
The case of ELSE, I want to by pass, 
so what should I fill in that ELSE clause for doing nothing?

> The first part of the loop seems to search some kind of convex
> hull, so i think you must loop over all points (if the sequence
> of points is monotonic, this makes no sense).
> You might want to look into scanline algorithms & such.

Hmm, where can I find the scanline algorithms, etc?
Any good pointer for that please?
Thanks alot.

Sungwoo

-- 
<^)++<
From: Barry Margolin
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <sM2z6.306$U4.10921@burlma1-snr2>
In article <························@gorecki.cad.strath.ac.uk>,
Sungwoo Lim <·······@cad.strath.ac.uk> wrote:
>In article <·················@iitb.fhg.de>, Michael Kappert
><···@iitb.fhg.de> wrote:
>
>> This terminates the loop alltogether. Do you want that?
>
>No, I don't want it. Yeap, that was what I didn't know.
>The case of ELSE, I want to by pass, 
>so what should I fill in that ELSE clause for doing nothing?

  else
      do (progn)

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <sfwwv8z5eju.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> In article <························@gorecki.cad.strath.ac.uk>,
> Sungwoo Lim <·······@cad.strath.ac.uk> wrote:
> >In article <·················@iitb.fhg.de>, Michael Kappert
> ><···@iitb.fhg.de> wrote:
> >
> >> This terminates the loop alltogether. Do you want that?
> >
> >No, I don't want it. Yeap, that was what I didn't know.
> >The case of ELSE, I want to by pass, 
> >so what should I fill in that ELSE clause for doing nothing?
> 
>   else
>       do (progn)
 
Or, if you're wanting to be more abstract

(defmacro nothing () 'nil)

Then later:
  ...
  else
    do (nothing)
From: Erik Naggum
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <3195489225318916@naggum.net>
* Sungwoo Lim
> The case of ELSE, I want to by pass, 
> so what should I fill in that ELSE clause for doing nothing?

  Use end to terminate a conditional clause.

  if ... do ... end

  From 6.1.6 Conditional Execution Clauses

The optional loop keyword end marks the end of the clause.  If this keyword
is not supplied, the next loop keyword marks the end.  The construct end
can be used to distinguish the scoping of compound clauses.

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Christopher J. Vogt
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <3ACCD498.F4BF81B2@computer.org>
Sungwoo Lim wrote:
> 
 
> Hmm, where can I find the scanline algorithms, etc?
> Any good pointer for that please?
> Thanks alot.

You can most likely find what you are looking for in one of the Graphics Gems books, probably the first one.
From: Michael Kappert
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <3ACCC35D.D52416F5@iitb.fhg.de>
Sungwoo Lim wrote:

> > The first part of the loop seems to search some kind of convex
> > hull, so i think you must loop over all points (if the sequence
> > of points is monotonic, this makes no sense).
> > You might want to look into scanline algorithms & such.
> 
> Hmm, where can I find the scanline algorithms, etc?

Scanline algorithms are used in computer graphics,
for computing inner regions of polytopes, or computing
2D views of 3D scenes, for example.

> Any good pointer for that please?

Sorry, I don't have any particular references.
Try Google (www.google.com) with the search keywords
scanline algorithm or geometric algorithm.

 
Michael

--
From: Barry Margolin
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <mK2z6.305$U4.10910@burlma1-snr2>
In article <··············@dslab7.cs.uit.no>,
Frode Vatvedt Fjeld  <······@acm.org> wrote:
>(My second rule of thumb concerning LOOP would be the negative of
>Barry Margolin's: The more complex the looping, the more you need/want
>to use LOOP.)

My recommendation is based on seeing many question in the past of the form
"What happens if you use both XXX and YYY in the same LOOP?"  The
unfortunate fact is that when we were writing the standard we didn't have
time to nail down all the possible interactions between different LOOP
features, so many of these are not well specified.  And even if we did get
it right in the standard, it's likely to be difficult to find them and I
wouldn't trust that all implementors got it right (many of those questions
were probably from implementors, trying to figure out what they were
supposed to do).  And even if they all got it right, someone reading your
code may not be able to figure it out.

So, with all those potential problems, my feeling is that if you have to
ask, it's probably better to use something other than LOOP.  Most other
parts of Lisp have relatively straightforward semantics, they nest in
obvious ways, and interactions are pretty clear (perhaps the only notable
exception is the interaction between all the different exiting mechanisms
like RETURN, UNWIND-PROTECT, and condition handlers -- it was very
difficult to get that right in the standard).

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Lieven Marchand
Subject: Re: [Q] ELSE in LOOP
Date: 
Message-ID: <m3vgoj14ij.fsf@localhost.localdomain>
Barry Margolin <······@genuity.net> writes:

> My recommendation is based on seeing many question in the past of the form
> "What happens if you use both XXX and YYY in the same LOOP?"  The
> unfortunate fact is that when we were writing the standard we didn't have
> time to nail down all the possible interactions between different LOOP
> features, so many of these are not well specified.  And even if we did get
> it right in the standard, it's likely to be difficult to find them and I
> wouldn't trust that all implementors got it right (many of those questions
> were probably from implementors, trying to figure out what they were
> supposed to do).  And even if they all got it right, someone reading your
> code may not be able to figure it out.

In a way it is a pity that the MIT LOOP user defined iteration paths
didn't make the standard, since the ADD-LOOP-PATH arguments give a
conceptual model of loop clauses, splitting the effects of each clause
into bindings, prologue, pre-step, step, post-step and pseudo-step. 

-- 
Lieven Marchand <···@wyrd.be>
Gla�r ok reifr skyli gumna hverr, unz sinn b��r bana.