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 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, bar...@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.
<bar...@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. =)
> 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))))
[I first replied privately in email by mistake. Sorry about that.]
sung...@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.
In article <2hsnjn2vrz....@dslab7.cs.uit.no>, Frode Vatvedt Fjeld
<fro...@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))
> In article <2hsnjn2vrz....@dslab7.cs.uit.no>, Frode Vatvedt Fjeld > <fro...@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))
In article <3ACC9E70.451CD...@iitb.fhg.de>, Michael Kappert
<k...@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.
In article <2hsnjn2vrz....@dslab7.cs.uit.no>, Frode Vatvedt Fjeld <fro...@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, bar...@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.
>> 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, bar...@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.
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.
Barry Margolin <bar...@genuity.net> writes: > In article <sungwoo-0504011747200...@gorecki.cad.strath.ac.uk>, > Sungwoo Lim <sung...@cad.strath.ac.uk> wrote: > >In article <3ACC9E70.451CD...@iitb.fhg.de>, Michael Kappert > ><k...@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 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:
Barry Margolin <bar...@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 <m...@wyrd.be> Glaðr ok reifr skyli gumna hverr, unz sinn bíðr bana.