As title. The "continue" statement is very useful when writing loop
structure. But I cannot find the counterpart in CL. Do it mean I can
only use tagbody/go to do the same thing in CL, or re-organize the
codes?
On Dec 4, 7:36 pm, Brian Jiang <········@gmail.com> wrote:
> As title. The "continue" statement is very useful when writing loop
> structure. But I cannot find the counterpart in CL. Do it mean I can
> only use tagbody/go to do the same thing in CL, or re-organize the
> codes?
Use iterate or write a macro per your appeal, it won't be difficult.
Slobodan
In article
<····································@a39g2000pre.googlegroups.com>,
Brian Jiang <········@gmail.com> wrote:
> As title. The "continue" statement is very useful when writing loop
> structure. But I cannot find the counterpart in CL. Do it mean I can
> only use tagbody/go to do the same thing in CL, or re-organize the
> codes?
LOOP has no 'continue'. You need to restructure your code.
The ITERATE macro has such a facility (NEXT-ITERATION):
http://common-lisp.net/project/iterate/doc/Control-Flow.html#Control-Flow
--
http://lispm.dyndns.org/
On Dec 5, 4:01 am, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@a39g2000pre.googlegroups.com>,
> Brian Jiang <········@gmail.com> wrote:
>
> > As title. The "continue" statement is very useful when writing loop
> > structure. But I cannot find the counterpart in CL. Do it mean I can
> > only use tagbody/go to do the same thing in CL, or re-organize the
> > codes?
>
> LOOP has no 'continue'. You need to restructure your code.
>
> The ITERATE macro has such a facility (NEXT-ITERATION):
>
> http://common-lisp.net/project/iterate/doc/Control-Flow.html#Control-...
>
> --http://lispm.dyndns.org/
Thanks a lot for the information. The ITERATE macro looks very nice :)
Rainer Joswig wrote:
> In article
> <····································@a39g2000pre.googlegroups.com>,
> Brian Jiang <········@gmail.com> wrote:
>
> > As title. The "continue" statement is very useful when writing loop
> > structure. But I cannot find the counterpart in CL. Do it mean I can
> > only use tagbody/go to do the same thing in CL, or re-organize the
> > codes?
>
>
> LOOP has no 'continue'. You need to restructure your code.
>
I'm not sure (loop ... do (block continue ... (return-from
continue) ...)) qualifies as `restructuring'.
Paul Khuong
On Dec 5, 8:46 am, Paul Khuong <·······@gmail.com> wrote:
>
> I'm not sure (loop ... do (block continue ... (return-from
> continue) ...)) qualifies as `restructuring'.
>
Just use DO
(do ((x 0 (+ x 1)))
((> x 10))
(when (= x 5) (go continue))
(print x)
continue)
Theoritically LOOP could do this as well, they both
enclose the processing in a TAGBODY but I can't think
of a way to keep it from trying to treat the tags as
keywords.
---
Geoff
On Dec 5, 11:08 pm, Geoffrey Summerhayes <·······@gmail.com> wrote:
> On Dec 5, 8:46 am, Paul Khuong <·······@gmail.com> wrote:
>
>
>
> > I'm not sure (loop ... do (block continue ... (return-from
> > continue) ...)) qualifies as `restructuring'.
>
> Just use DO
>
> (do ((x 0 (+ x 1)))
> ((> x 10))
> (when (= x 5) (go continue))
> (print x)
> continue)
>
> Theoritically LOOP could do this as well, they both
> enclose the processing in a TAGBODY but I can't think
> of a way to keep it from trying to treat the tags as
> keywords.
>
AFAIK you cannot. This seems obviously an oversight. The machinery
is all there to support this. It should be straighforward to add a
macrolet ((CONTINUE () ..)) as we already have LOOP-FINISH and RETURN.
Cheers
--
Marco
On Dec 6, 3:55 am, Marco Antoniotti <·······@gmail.com> wrote:
> On Dec 5, 11:08 pm, Geoffrey Summerhayes <·······@gmail.com> wrote:
>
> > Just use DO
>
> > (do ((x 0 (+ x 1)))
> > ((> x 10))
> > (when (= x 5) (go continue))
> > (print x)
> > continue)
>
> > Theoritically LOOP could do this as well, they both
> > enclose the processing in a TAGBODY but I can't think
> > of a way to keep it from trying to treat the tags as
> > keywords.
>
> AFAIK you cannot. This seems obviously an oversight. The machinery
> is all there to support this. It should be straighforward to add a
> macrolet ((CONTINUE () ..)) as we already have LOOP-FINISH and RETURN.
I don't know if I'd call it an oversight. Even in C/C++
I've rarely used continue. Or break for that matter,
other than inside a switch block.
Personally, I find that most of the times I've seen continue
and break used in C/C++ code, their use didn't do much more
than make the flow harder to follow and show the coders were
either a misguided attempt to show off their command of the
language, or too rushed and/or too lazy to take the time to
do it clearly.
I can see the use of continue in LOOP's simple form but it
can be easily done with a TAGBODY. What I can't do is think
of an extended LOOP form where its use would be justifiable,
other than make it easier to translate code from another
programming language(but then, why use an extended form of
LOOP in the first place?).
---
Geoff
From: Rupert Swarbrick
Subject: Re: Does CL have sth for interaction/loop control struction like "continue" for for/while in C or Python
Date:
Message-ID: <NWW5j.2729$1j1.2244@newsfe7-gui.ntli.net>
On Thu, 06 Dec 2007 09:40:46 -0800, Geoffrey Summerhayes wrote:
> I don't know if I'd call it an oversight. Even in C/C++ I've rarely used
> continue. Or break for that matter, other than inside a switch block.
>
> Personally, I find that most of the times I've seen continue and break
> used in C/C++ code, their use didn't do much more than make the flow
> harder to follow and show the coders were either a misguided attempt to
> show off their command of the language, or too rushed and/or too lazy to
> take the time to do it clearly.
>
I'm not so sure about that. I'm really a C/C++ guy and am still seeking
enlightenment with lisp :P, but something like this seems natural to me:
for( int i=1; i<N; i++ ) {
if( !isPrime(i) ) continue;
// i must be prime
std::cout << "Wow! " << i << " is prime!\n";
}
Clearly, isPrime() is left as an exercise...
But seriously, this makes life nicer, otherwise you have to wrap the cout
call in an if() { ... } statement. Doing this more than a couple of times
leads to seriously crazy indentation.
I don't know whether similar situations happen in lisp - I realise
indentation isn't such a problem.
Rupert
On Dec 6, 1:10 pm, Rupert Swarbrick <··········@gmail.com> wrote:
>
> I'm not so sure about that. I'm really a C/C++ guy and am still seeking
> enlightenment with lisp :P, but something like this seems natural to me:
>
> for( int i=1; i<N; i++ ) {
> if( !isPrime(i) ) continue;
>
> // i must be prime
> std::cout << "Wow! " << i << " is prime!\n";
>
> }
But why?
Very trivial, but is this:
for( int i=1; i<N; i++ )
{
if( isPrime(i) )
std::cout << "Wow! " << i << " is prime!\n";
}
in any way harder to understand? Cuts the statement
count in half! Oooooh!
Break, continue, and goto interrupt the normal
flow, usually making code harder to follow. Their
overuse is the reason<deep_bass tone="godlike" echo="on">
Structured Programming</deep_bass> was taken as
the thing-to-do back in the 70's.
Also, C/C++'s flow breakers are non-partisan, you
have to check the code to see what the controlling
statement is, like HTML's position="absolute" you
know it's a surrounding statement but you don't
know how many levels you have to go up to find it,
and until you do, you're not too sure what kind of
statement you're looking for. At least good ol'
BASIC had NEXT i for its FOR loops.
Now a better example of where continue makes sense
would be something along the lines of:
for(...)
{
...
if(..)
{
...
if(...)continue;
...
}
else
{
...
if(...)
{
...
if(...)continue;
...
}
...
}
...
}
where the quick alternative would be
for(...)
{
bool process=true;
...
if(..)
{
...
if(...)
process=false;
else
{
...
}
}
else
{
...
if(...)
{
...
if(...)
process=false;
else
{
...
}
}
}
if(process)
{
...
}
}
But that's no guarantee that a little extra thought
and some rearranging couldn't eliminate the need for
the flag altogether and make things clearer at the
same time.
> But seriously, this makes life nicer, otherwise you have to wrap the cout
> call in an if() { ... } statement. Doing this more than a couple of times
> leads to seriously crazy indentation.
As long as the code is a one-off, no problem. You get any halfway
complicated program requiring maintenance and it can become a bit
of a nightmare. A rewrite may eliminate or replace the controlling
statement with one that isn't one that isn't a continuable block.
For a quick example, consider:
for(int i=...)
{
...
for(int j=...)
{
if(some_fiddly_bit)
{
...
// and..buried somewhere
if(a[j])continue; // exception!
...
}
}
...
}
gets altered to:
for(int i=...)
{
int index;
// added preprocessing to get
// data ready
// see BUG #22 ;-)
for(int k=...)
{
if(some_fiddly_bit)index=k;
}
...
// eliminated redundant loop-if
// already searched
// just use the found index
int j=index;
{
...
// we'll call this BUG #42 :-P
// and..buried somewhere
if(a[j])continue; // exception!
...
}
...
}
> I don't know whether similar situations happen in lisp - I realise
> indentation isn't such a problem.
Well, I rarely go over eight levels of indents in C/C++.
Hell, I rarely go that deep. When I get above eight it
usually means I'm repeating code and need to refactor
anyway.
---
Geoff
On Dec 6, 6:40 pm, Geoffrey Summerhayes <·······@gmail.com> wrote:
> On Dec 6, 3:55 am, Marco Antoniotti <·······@gmail.com> wrote:
>
>
>
> > On Dec 5, 11:08 pm, Geoffrey Summerhayes <·······@gmail.com> wrote:
>
> > > Just use DO
>
> > > (do ((x 0 (+ x 1)))
> > > ((> x 10))
> > > (when (= x 5) (go continue))
> > > (print x)
> > > continue)
>
> > > Theoritically LOOP could do this as well, they both
> > > enclose the processing in a TAGBODY but I can't think
> > > of a way to keep it from trying to treat the tags as
> > > keywords.
>
> > AFAIK you cannot. This seems obviously an oversight. The machinery
> > is all there to support this. It should be straighforward to add a
> > macrolet ((CONTINUE () ..)) as we already have LOOP-FINISH and RETURN.
>
> I don't know if I'd call it an oversight. Even in C/C++
> I've rarely used continue. Or break for that matter,
> other than inside a switch block.
Well, same here. :) Basically LOOP gives you the LOOP-1/2 construct
which is a a very general loop facility. Having CONTINUE would be
easy, but I guess you are right. Maybe it was not an oversight after
all.
>
> Personally, I find that most of the times I've seen continue
> and break used in C/C++ code, their use didn't do much more
> than make the flow harder to follow and show the coders were
> either a misguided attempt to show off their command of the
> language,
Yeah! Right :) As if we, LOOP coders, are not showing off when we
NCONC something while iterating a destructured sublist ON a parameter
while DOING other stuff. :)
Cheers
--
Marco
From: Stefan Nobis
Subject: Re: Does CL have sth for interaction/loop control struction like "continue" for for/while in C or Python
Date:
Message-ID: <m18x46hlvi.fsf@snobis.de>
Geoffrey Summerhayes <·······@gmail.com> writes:
> I've rarely used continue. Or break for that matter
Hmmm... I like to write something like this:
while (line = read_from_file()) {
if (complete_bullshit(line)) break;
if (comment(line)) continue;
if (uninteresting_in_context(line, context)) continue;
process(line);
}
Yes, there are other ways to express this und if overused above style
may become quite hard to read/understand. But for me it comes very
natural. That's so great about people: They are different. :)
--
Stefan.
On Dec 7, 4:53 am, Stefan Nobis <······@gmx.de> wrote:
> Geoffrey Summerhayes <·······@gmail.com> writes:
> > I've rarely used continue. Or break for that matter
>
> Hmmm... I like to write something like this:
>
> while (line = read_from_file()) {
> if (complete_bullshit(line)) break;
> if (comment(line)) continue;
> if (uninteresting_in_context(line, context)) continue;
>
> process(line);
>
> }
>
> Yes, there are other ways to express this und if overused above style
> may become quite hard to read/understand. But for me it comes very
> natural. That's so great about people: They are different. :)
Me: Yep...(rolls up sleeves, cross DR)
Let see.
while (!complete_bullshit(line = read_from_file())) {
if (!comment(line)&&
!uninteresting_in_context(line, context))
process(line);
}
(straightens up, not completely happy)
Being from the days when memory and time
were expensive, I'm always curious about
what comes out of the compiler...I'd guess
this would generate marginally a smaller
amount of code say, 10%, for this little
thing, a larger loop would naturally make
less of a difference. Depends a lot on
how smart the optimizer is.
Of course, I might just keep the break
line for readability, and avoid the while-
not-assign, it is a bit cumbersome.
(looks around)
Sorry, wrong group for this. Let's get
back to Lisp.
(Exeunt SR)
---
Geoff
In article <··············@snobis.de>, Stefan Nobis <······@gmx.de>
wrote:
> Geoffrey Summerhayes <·······@gmail.com> writes:
>
> > I've rarely used continue. Or break for that matter
>
> Hmmm... I like to write something like this:
>
> while (line = read_from_file()) {
> if (complete_bullshit(line)) break;
> if (comment(line)) continue;
> if (uninteresting_in_context(line, context)) continue;
>
> process(line);
> }
>
> Yes, there are other ways to express this und if overused above style
> may become quite hard to read/understand. But for me it comes very
> natural. That's so great about people: They are different. :)
The LOOP version would be something like this:
(loop for line = (read-line stream nil nil)
while line
until (complete-bullshit-p line)
unless (or (comment-p line)
(uninteresting-in-context-p line context))
do (process line))
You have the clauses with an identifier on the front.
In the C version you have to scan the line
find at the end what happens if the condition is true.
I would recommend a coding style that is more declarative
and less imperative. Declarative means that you have
symbols telling you what the statement is for, instead
of having it to infer from how it is used.
If you have a lot loops with these 'guards', then you could
invent some construct that expresses a bit better
what you want to write.
For example a PROCESSING-LINES macro:
(processing-lines (stream)
:exit-on (complete-bullshit-p line)
:skip-on (comment-p line)
:skip-on (uninteresting-in-context-p line context)
:do (process line))
--
http://lispm.dyndns.org/
From: Tobias C. Rittweiler
Subject: Re: Does CL have sth for interaction/loop control struction like "continue" for for/while in C or Python
Date:
Message-ID: <87bq911ogk.fsf@freebits.de>
Rainer Joswig <······@lisp.de> writes:
> In article <··············@snobis.de>, Stefan Nobis <······@gmx.de>
> wrote:
>
> > Hmmm... I like to write something like this:
> >
> > while (line = read_from_file()) {
> > if (complete_bullshit(line)) break;
> > if (comment(line)) continue;
> > if (uninteresting_in_context(line, context)) continue;
> >
> > process(line);
> > }
> >
>
> The LOOP version would be something like this:
>
> (loop for line = (read-line stream nil nil)
> while line
> until (complete-bullshit-p line)
> unless (or (comment-p line)
> (uninteresting-in-context-p line context))
> do (process line))
I think I'd write it as:
(loop for line = (read-line stream nil nil)
while line do
(cond ((complete-bullshit-p line) (loop-finish))
((commentp line) :skip)
((uninteresting-in-context-p line context) :skip)
(t (process line))))
-T.
From: Timofei Shatrov
Subject: Re: Does CL have sth for interaction/loop control struction like "continue" for for/while in C or Python
Date:
Message-ID: <4756fbd9.41311202@news.readfreenews.net>
On Wed, 5 Dec 2007 05:46:40 -0800 (PST), Paul Khuong <·······@gmail.com> tried
to confuse everyone with this message:
>Rainer Joswig wrote:
>> In article
>> <····································@a39g2000pre.googlegroups.com>,
>> Brian Jiang <········@gmail.com> wrote:
>>
>> > As title. The "continue" statement is very useful when writing loop
>> > structure. But I cannot find the counterpart in CL. Do it mean I can
>> > only use tagbody/go to do the same thing in CL, or re-organize the
>> > codes?
>>
>>
>> LOOP has no 'continue'. You need to restructure your code.
>>
>
>I'm not sure (loop ... do (block continue ... (return-from
>continue) ...)) qualifies as `restructuring'.
It certainly does if you use other loop keywords besides do.
--
|Don't believe this - you're not worthless ,gr---------.ru
|It's us against millions and we can't take them all... | ue il |
|But we can take them on! | @ma |
| (A Wilhelm Scream - The Rip) |______________|
On 2007-12-05 14:29:26 -0500, ····@mail.ru (Timofei Shatrov) said:
> On Wed, 5 Dec 2007 05:46:40 -0800 (PST), Paul Khuong <·······@gmail.com> tried
> to confuse everyone with this message:
>
>> Rainer Joswig wrote:
>>> In article
>>> <····································@a39g2000pre.googlegroups.com>,
>>> Brian Jiang <········@gmail.com> wrote:
>>>
>>>> As title. The "continue" statement is very useful when writing loop
>>>> structure. But I cannot find the counterpart in CL. Do it mean I can
>>>> only use tagbody/go to do the same thing in CL, or re-organize the
>>>> codes?
>>>
>>>
>>> LOOP has no 'continue'. You need to restructure your code.
>>>
>>
>> I'm not sure (loop ... do (block continue ... (return-from
>> continue) ...)) qualifies as `restructuring'.
>
> It certainly does if you use other loop keywords besides do.
? (loop named foo
for i from 1 to 100
collect (if (/= i 50) i (return-from foo i-list)) into i-list)
(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49)
Works with collect. [1]
? (loop named bar
for i from 1 to 100
sum (if (< i 70) i (return-from bar i-sum)) into i-sum)
2415
works with sum [1]
What other loop keywords were you thinking of?
[1] naturally these are more idiomatically expressed with:
? (loop named foo
for i from 1 to 100
when (/= i 50) collect i into i-list
when (= i 50) do (return-from foo i-list))
(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49)
but you said I couldn't use the loop keyword 'do'
From: Timofei Shatrov
Subject: Re: Does CL have sth for interaction/loop control struction like "continue" for for/while in C or Python
Date:
Message-ID: <4758f4c0.1636613@news.readfreenews.net>
On Thu, 6 Dec 2007 18:21:46 -0500, Raffael Cavallaro
<················@pas-d'espam-s'il-vous-plait-mac.com> tried to confuse everyone
with this message:
>On 2007-12-05 14:29:26 -0500, ····@mail.ru (Timofei Shatrov) said:
>
>> On Wed, 5 Dec 2007 05:46:40 -0800 (PST), Paul Khuong <·······@gmail.com> tried
>> to confuse everyone with this message:
>>
>>> Rainer Joswig wrote:
>>>> In article
>>>> <····································@a39g2000pre.googlegroups.com>,
>>>> Brian Jiang <········@gmail.com> wrote:
>>>>
>>>>> As title. The "continue" statement is very useful when writing loop
>>>>> structure. But I cannot find the counterpart in CL. Do it mean I can
>>>>> only use tagbody/go to do the same thing in CL, or re-organize the
>>>>> codes?
>>>>
>>>>
>>>> LOOP has no 'continue'. You need to restructure your code.
>>>>
>>>
>>> I'm not sure (loop ... do (block continue ... (return-from
>>> continue) ...)) qualifies as `restructuring'.
>>
>> It certainly does if you use other loop keywords besides do.
<snip> irrelevant examples
>
>but you said I couldn't use the loop keyword 'do'
>
Never did I say such a thing. I said that if your loop body contains keywords
other than do, you cannot simply transform it into the form
(loop ...
do (block continue
...
(return-from continue)
...))
In that case you need to do some restructuring. In fact, even a simple "for"
totally breaks Paul Khuong's thesis that you can trivially express any loop in
the above form.
--
|Don't believe this - you're not worthless ,gr---------.ru
|It's us against millions and we can't take them all... | ue il |
|But we can take them on! | @ma |
| (A Wilhelm Scream - The Rip) |______________|
On 2007-12-07 02:30:25 -0500, ····@mail.ru (Timofei Shatrov) said:
> In that case you need to do some restructuring. In fact, even a simple "for"
> totally breaks Paul Khuong's thesis that you can trivially express any loop in
> the above form.
The (loop named .. form is the equivalent of Paul's do (block foo, and
it is built into loop.
Paul's point is that the restructuring (such as it is) consists of
using a named block and (return-from name... and that such a simple
modification is not what many people would call "restructuring" your
code.
Finally (pun intended) we should point out that similar effects can be
had with loop-finish and finally:
? (loop
for elt in (list 'john 'paul 'george 'ringo 'murray-the-k 'pete-best )
collect (if (neq elt 'murray-the-k) elt (loop-finish)) into beatle-list
finally (return beatle-list))
(JOHN PAUL GEORGE RINGO)
On Dec 7, 9:48 am, Raffael Cavallaro <················@pas-d'espam-
s'il-vous-plait-mac.com> wrote:
> On 2007-12-07 02:30:25 -0500, ····@mail.ru (Timofei Shatrov) said:
>
> > In that case you need to do some restructuring. In fact, even a simple "for"
> > totally breaks Paul Khuong's thesis that you can trivially express any loop in
> > the above form.
>
> The (loop named .. form is the equivalent of Paul's do (block foo, and
> it is built into loop.
No, it is not. Your version exits the loop, Paul's exits only
the block, the loop "continues".
> Paul's point is that the restructuring (such as it is) consists of
> using a named block and (return-from name... and that such a simple
> modification is not what many people would call "restructuring" your
> code.
Paul's solution, by enclosing the iterative portion in
a block, prevents the use of collect, summing, etc. All
of the loop control keywords outside the block are fine.
> Finally (pun intended) we should point out that similar effects can be
> had with loop-finish and finally:
>
> ? (loop
> for elt in (list 'john 'paul 'george 'ringo 'murray-the-k 'pete-best )
> collect (if (neq elt 'murray-the-k) elt (loop-finish)) into beatle-list
> finally (return beatle-list))
> (JOHN PAUL GEORGE RINGO)
Yours, well it just exits too soon, it should have included PETE. :)
---
Geoff
On 2007-12-07 14:17:07 -0500, Geoffrey Summerhayes <·······@gmail.com> said:
> On Dec 7, 9:48 am, Raffael Cavallaro <················@pas-d'espam-
> s'il-vous-plait-mac.com> wrote:
>> On 2007-12-07 02:30:25 -0500, ····@mail.ru (Timofei Shatrov) said:
>>
>>> In that case you need to do some restructuring. In fact, even a simple "for"
>>> totally breaks Paul Khuong's thesis that you can trivially express any loop in
>>> the above form.
>>
>> The (loop named .. form is the equivalent of Paul's do (block foo, and
>> it is built into loop.
>
> No, it is not. Your version exits the loop, Paul's exits only
> the block, the loop "continues".
Ah, ok, you want a direct equivalent of continue, not just the ability
to break. That's the when/unless form as Rainer pointed out, which also
works with sum, collect, etc.
? (loop for elt in
(list 'john 'paul 'george 'ringo 'murray-the-k 'pete-best)
unless (eq elt 'murray-the-k) collect elt into real-beatles
collect elt into possible-beatles
finally
(format t "Possible Beatles: ~a~%Real Beatles: ~a" possible-beatles
real-beatles ))
Possible Beatles: (JOHN PAUL GEORGE RINGO MURRAY-THE-K PETE-BEST)
Real Beatles: (JOHN PAUL GEORGE RINGO PETE-BEST)
And Pete is restored to his rightful Beatle status as well ;^)