Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #36263 > unrolled thread

What is the word to break a do while loop?

Started byFaisal <faisalm83@gmail.com>
First post2015-02-03 23:24 -0800
Last post2015-02-05 08:54 -0800
Articles 15 — 8 participants

Back to article view | Back to comp.lang.forth


Contents

  What is the word to break a do while loop? Faisal <faisalm83@gmail.com> - 2015-02-03 23:24 -0800
    Re: What is the word to break a do while loop? Mark Wills <markwills1970@gmail.com> - 2015-02-04 01:53 -0800
    Re: What is the word to break a do while loop? Mark Wills <markwills1970@gmail.com> - 2015-02-04 02:15 -0800
    Re: What is the word to break a do while loop? Coos Haak <chforth@hccnet.nl> - 2015-02-04 12:54 +0100
      Re: What is the word to break a do while loop? "Rod Pemberton" <buzz@notnotnontnooatno.cmm> - 2015-02-04 18:50 -0500
      Re: What is the word to break a do while loop? hughaguilar96@gmail.com - 2015-02-04 18:29 -0800
        Re: What is the word to break a do while loop? hughaguilar96@gmail.com - 2015-02-04 18:43 -0800
    Re: What is the word to break a do while loop? JennyB <jennybrien@googlemail.com> - 2015-02-04 05:53 -0800
      Re: What is the word to break a do while loop? hughaguilar96@gmail.com - 2015-02-04 18:36 -0800
        Re: What is the word to break a do while loop? "HAA" <someone@microsoft.com> - 2015-02-08 17:31 +1100
          Re: What is the word to break a do while loop? hughaguilar96@gmail.com - 2015-02-08 09:13 -0800
            Re: What is the word to break a do while loop? "HAA" <someone@microsoft.com> - 2015-02-09 16:45 +1100
              Re: What is the word to break a do while loop? hughaguilar96@gmail.com - 2015-02-09 22:36 -0800
                Re: What is the word to break a do while loop? "HAA" <someone@microsoft.com> - 2015-02-11 10:30 +1100
    Re: What is the word to break a do while loop? lehs <skydda.barnen@gmail.com> - 2015-02-05 08:54 -0800

#36263 — What is the word to break a do while loop?

FromFaisal <faisalm83@gmail.com>
Date2015-02-03 23:24 -0800
SubjectWhat is the word to break a do while loop?
Message-ID<53c95926-d610-4995-8746-5a9166ea3b75@googlegroups.com>
I tried LEAVE, but it is not working

: test
	begin dup 0 >= while
		dup .
		1 -
		exitapp@ 1 = IF
		  leave 
		then 
	repeat
	.
;

[toc] | [next] | [standalone]


#36265

FromMark Wills <markwills1970@gmail.com>
Date2015-02-04 01:53 -0800
Message-ID<7efd6392-25f5-49ec-9eea-b1bf33dfdf18@googlegroups.com>
In reply to#36263
On Wednesday, 4 February 2015 07:24:32 UTC, Faisal  wrote:
> I tried LEAVE, but it is not working
> 
> : test
> 	begin dup 0 >= while
> 		dup .
> 		1 -
> 		exitapp@ 1 = IF
> 		  leave 
> 		then 
> 	repeat
> 	.
> ;

The word LEAVE is used to break out of a DO...LOOP structure. Your code is
not using a DO...LOOP structure, you are using BEGIN...WHILE...REPEAT

Your code will exit (i.e. jump to the code after REPEAT) when the
WHILE condition is false.

It looks like your WHILE condition is testing a value passed in from the
stack (there's no stack comment ;-) and if it is >= zero then the code
between WHILE and REPEAT will execute, otherwise it will skip the WHILE
block and continue with the code following REPEAT.

: exitapp@ ( -- n ) 10 rnd ;

: test ( startValue -- endValue )
  begin dup 0 >= while dup . 1 - exitapp@ 1 = until ;

Here, I'm using UNTIL. UNTIL will loop back to BEGIN if it receives
FALSE (0). We compare the value returned by exitapp@ to 1, and if 
the comparison is TRUE then UNTIL will *not* loop back to begin, and
your code exits.

Hope this helps.

[toc] | [prev] | [next] | [standalone]


#36266

FromMark Wills <markwills1970@gmail.com>
Date2015-02-04 02:15 -0800
Message-ID<bce04e33-615c-4809-b280-ae9a829f09d9@googlegroups.com>
In reply to#36263
On Wednesday, 4 February 2015 07:24:32 UTC, Faisal  wrote:
> I tried LEAVE, but it is not working
> 
> : test
> 	begin dup 0 >= while
> 		dup .
> 		1 -
> 		exitapp@ 1 = IF
> 		  leave 
> 		then 
> 	repeat
> 	.
> ;

My earlier post was erroneous. Please dis-regard.

This is how I solved it using begin/while/repeat as in your
example code:

: exitapp@ ( -- n ) 20 rnd ; 

: test ( startValue -- ) 
  0 >r 
  begin dup 0 >= while 
    dup . 1 -
    exitapp@ 1 = if r> drop >r 0 then
  repeat
  drop r> .
;

It requires one extra iteration of the loop when the exit
condition is detected. The 0 >R at the start is just in case
exitapp@ never returns 1.

Hope this helps.

[toc] | [prev] | [next] | [standalone]


#36268

FromCoos Haak <chforth@hccnet.nl>
Date2015-02-04 12:54 +0100
Message-ID<12dlay6wqdj74.s5sar1seepvu$.dlg@40tude.net>
In reply to#36263
Op Tue, 3 Feb 2015 23:24:31 -0800 (PST) schreef Faisal:

> I tried LEAVE, but it is not working
> 
>: test
> 	begin dup 0 >= while
> 		dup .
> 		1 -
> 		exitapp@ 1 = IF
> 		  leave 
> 		then 
> 	repeat
> 	.
> ;

There is no do-while loop in Forth. You wrote a correct begin-while-repeat
loop, but leave does not work here, use the word exit here. You can use
exit in begin-until and begin-again loops too. Remember that exit leaves
the word test and does not reach the . after repeat.

Leave belongs to the do-loop construct:
  do / ?do ... leave ... loop / +loop
LEAVE continues after loop.

The construct
  do .. if unloop exit then .. loop
will leave the definition and not continue after loop

UNLOOP and LEAVE remove the control parameters (apparently on the return
stack) that the do-loop uses. EXIT does not know about those.

-- 
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html 

[toc] | [prev] | [next] | [standalone]


#36287

From"Rod Pemberton" <buzz@notnotnontnooatno.cmm>
Date2015-02-04 18:50 -0500
Message-ID<op.xtj4i4ecv6dtjm@localhost>
In reply to#36268
On Wed, 04 Feb 2015 06:54:55 -0500, Coos Haak <chforth@hccnet.nl> wrote:
> Op Tue, 3 Feb 2015 23:24:31 -0800 (PST) schreef Faisal:

>> I tried LEAVE, but it is not working
>>
>> : test
>> 	begin dup 0 >= while
>> 		dup .
>> 		1 -
>> 		exitapp@ 1 = IF
>> 		  leave
>> 		then
>> 	repeat
>> 	.
>> ;
>
> There is no do-while loop in Forth. You wrote a correct
> begin-while-repeat loop, but leave does not work here,
> use the word exit here.  You can use exit in begin-until
> and begin-again loops too.
...

> Remember that exit leaves
> the word test and does not reach the . after repeat.

It's good someone mentioned that, but no one told him
that using two words solves the problem with EXIT exiting
the current definition:

: testbody
    begin
    ...
    while
    ...
     if
      exit
     then
    ...
    repeat
;

: test testbody . ;


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#36289

Fromhughaguilar96@gmail.com
Date2015-02-04 18:29 -0800
Message-ID<482d0924-e169-4880-84c3-c9c17061bb02@googlegroups.com>
In reply to#36268
On Wednesday, February 4, 2015 at 5:04:03 AM UTC-7, Coos Haak wrote:
> ...use the word exit here. You can use
> exit in begin-until and begin-again loops too. 

This is what I always do --- factor out the loop into a colon word of its own, then use EXIT to break out of it.

[toc] | [prev] | [next] | [standalone]


#36291

Fromhughaguilar96@gmail.com
Date2015-02-04 18:43 -0800
Message-ID<f16fbec8-342a-41a6-9ffe-0ca0778e69c0@googlegroups.com>
In reply to#36289
On Wednesday, February 4, 2015 at 7:30:00 PM UTC-7, hughag...@gmail.com wrote:
> On Wednesday, February 4, 2015 at 5:04:03 AM UTC-7, Coos Haak wrote:
> > ...use the word exit here. You can use
> > exit in begin-until and begin-again loops too. 
> 
> This is what I always do --- factor out the loop into a colon word of its own, then use EXIT to break out of it.

On a related note, I never use CASE either. I always factor that out into a colon word of its own, then use IF ... EXIT THEN to break out of it.

[toc] | [prev] | [next] | [standalone]


#36273

FromJennyB <jennybrien@googlemail.com>
Date2015-02-04 05:53 -0800
Message-ID<c0f56ca0-7d8d-4099-a026-22fd12265397@googlegroups.com>
In reply to#36263
On Wednesday, 4 February 2015 07:24:32 UTC, Faisal  wrote:
> I tried LEAVE, but it is not working
> 
> : test
> 	begin dup 0 >= while
> 		dup .
> 		1 -
> 		exitapp@ 1 = IF
> 		  leave 
> 		then 
> 	repeat
> 	.
> ;

As Coos says, LEAVE and UNLOOP work with counted loops. 

The Standard Forth way to exit a Begin loop on more than one condition is a bit odd:

: test 
        begin dup 0 >= while 
                dup . 
                1 - 
                exitapp@ 1 = until
                then
        . 
; 

or 

: test 
        begin dup 0 >= while 
                dup . 
                1 - 
                exitapp@ 1 <> while
                
        repeat
        then
        . 
; 

Each extra WHILE you use has to be resolved by its own THEN (or ELSE THEN) outside the loop. It helps if you think of REPEAT as a shorthand for AGAIN THEN  and UNTIL a shorthand for <> WHILE AGAIN THEN

Consider, though, how you would know if the test failed on the last iteration.


   

[toc] | [prev] | [next] | [standalone]


#36290

Fromhughaguilar96@gmail.com
Date2015-02-04 18:36 -0800
Message-ID<dc873b28-4c51-49cb-ba0a-f169c167570e@googlegroups.com>
In reply to#36273
On Wednesday, February 4, 2015 at 6:53:55 AM UTC-7, JennyB wrote:
> The Standard Forth way to exit a Begin loop on more than one condition is a bit odd:

It is more than a bit odd --- using ELSE and THEN without a corresponding IF is extremely confusing! --- I have never used this, and don't plan on ever doing so.

In UR/Forth I wrote code that allowed BEGIN REPEAT loops to have any number of WHILE statements (including zero, which was effectively the same as using AGAIN rather than REPEAT). I don't recall ever actually using this in a real program however --- in practice, I just used the technique described above in which the loop was factored out in its own colon word and EXIT was used to break out.

[toc] | [prev] | [next] | [standalone]


#36383

From"HAA" <someone@microsoft.com>
Date2015-02-08 17:31 +1100
Message-ID<mb6vor$2tp$1@speranza.aioe.org>
In reply to#36290
hughaguilar96@gmail.com wrote:
> On Wednesday, February 4, 2015 at 6:53:55 AM UTC-7, JennyB wrote:
> > The Standard Forth way to exit a Begin loop on more than one condition is a bit odd:
>
> It is more than a bit odd --- using ELSE and THEN without a corresponding IF is
> extremely confusing! --- I have never used this, and don't plan on ever doing so.

Nor is it confusing for those who use it.  Because ANS WHILE costs nothing to
provide, I'm open to learn what it can do for me.  It's a free lunch.


[toc] | [prev] | [next] | [standalone]


#36389

Fromhughaguilar96@gmail.com
Date2015-02-08 09:13 -0800
Message-ID<281b571d-a1c6-429a-ba9e-8096e220ac38@googlegroups.com>
In reply to#36383
On Saturday, February 7, 2015 at 11:29:51 PM UTC-7, HAA wrote:
> hughaguilar96@gmail.com wrote:
> > On Wednesday, February 4, 2015 at 6:53:55 AM UTC-7, JennyB wrote:
> > > The Standard Forth way to exit a Begin loop on more than one condition is a bit odd:
> >
> > It is more than a bit odd --- using ELSE and THEN without a corresponding IF is
> > extremely confusing! --- I have never used this, and don't plan on ever doing so.
> 
> Nor is it confusing for those who use it.  Because ANS WHILE costs nothing to
> provide, I'm open to learn what it can do for me.  It's a free lunch.

In many cases, a BRANCH takes more time than an EXIT --- it is also larger in the threaded-code, typically 2 cells compared to 1 --- when I wrote MFX I was focused on performance because the program was a commercial application.

[toc] | [prev] | [next] | [standalone]


#36405

From"HAA" <someone@microsoft.com>
Date2015-02-09 16:45 +1100
Message-ID<mb9heu$jbn$1@speranza.aioe.org>
In reply to#36389
hughaguilar96@gmail.com wrote:
> On Saturday, February 7, 2015 at 11:29:51 PM UTC-7, HAA wrote:
> > hughaguilar96@gmail.com wrote:
> > > On Wednesday, February 4, 2015 at 6:53:55 AM UTC-7, JennyB wrote:
> > > > The Standard Forth way to exit a Begin loop on more than one condition is a bit
> > > > odd:
> > >
> > > It is more than a bit odd --- using ELSE and THEN without a corresponding IF is
> > > extremely confusing! --- I have never used this, and don't plan on ever doing so.
> >
> > Nor is it confusing for those who use it.  Because ANS WHILE costs nothing to
> > provide, I'm open to learn what it can do for me.  It's a free lunch.
>
> In many cases, a BRANCH takes more time than an EXIT --- it is also larger in the
> threaded-code, typically 2 cells compared to 1 --- when I wrote MFX I was focused on
> performance because the program was a commercial application.

If there was a faster or more space efficient way than multiple WHILE I would use it.
Not sure what you mean by BRANCH.  There's one in ELSE but its use with multiple
WHILE is optional and rarely needed in my experience.


[toc] | [prev] | [next] | [standalone]


#36423

Fromhughaguilar96@gmail.com
Date2015-02-09 22:36 -0800
Message-ID<712920a4-4782-41b3-8657-dbcc9dd20142@googlegroups.com>
In reply to#36405
On Sunday, February 8, 2015 at 10:44:03 PM UTC-7, HAA wrote:
> hughaguilar96@gmail.com wrote:
> > On Saturday, February 7, 2015 at 11:29:51 PM UTC-7, HAA wrote:
> > > hughaguilar96@gmail.com wrote:
> > > > On Wednesday, February 4, 2015 at 6:53:55 AM UTC-7, JennyB wrote:
> > > > > The Standard Forth way to exit a Begin loop on more than one condition is a bit
> > > > > odd:
> > > >
> > > > It is more than a bit odd --- using ELSE and THEN without a corresponding IF is
> > > > extremely confusing! --- I have never used this, and don't plan on ever doing so.
> > >
> > > Nor is it confusing for those who use it.  Because ANS WHILE costs nothing to
> > > provide, I'm open to learn what it can do for me.  It's a free lunch.
> >
> > In many cases, a BRANCH takes more time than an EXIT --- it is also larger in the
> > threaded-code, typically 2 cells compared to 1 --- when I wrote MFX I was focused on
> > performance because the program was a commercial application.
> 
> If there was a faster or more space efficient way than multiple WHILE I would use it.
> Not sure what you mean by BRANCH.  There's one in ELSE but its use with multiple
> WHILE is optional and rarely needed in my experience.

I meant 0BRANCH --- in the WHILE.

Actually, now that I think about it, WHILE has one 0BRANCH, but IF EXIT THEN has a 0BRANCH (the IF) plus an EXIT --- so my technique is slightly slower. On the MiniForth, calling a colon word was very fast, but this isn't necessarily true on other Forths --- so, putting the loop in its own colon word can make my technique yet slower.

As a practical matter, we are talking about a few microseconds difference here, so it doesn't really matter very much.

I think my technique results in much more readable code than the ANS-Forth multiple-WHILE technique due to ANS-Forth requiring THEN after the REPEAT which is pretty baffling --- ANS-Forth is gratuitously complicated and generally baffling --- ANS-Forth is just a problem that has to be worked around.

[toc] | [prev] | [next] | [standalone]


#36444

From"HAA" <someone@microsoft.com>
Date2015-02-11 10:30 +1100
Message-ID<mbe48a$ve0$1@speranza.aioe.org>
In reply to#36423
hughaguilar96@gmail.com wrote:
> On Sunday, February 8, 2015 at 10:44:03 PM UTC-7, HAA wrote:
> > hughaguilar96@gmail.com wrote:
> > > On Saturday, February 7, 2015 at 11:29:51 PM UTC-7, HAA wrote:
> > [...]
> > If there was a faster or more space efficient way than multiple WHILE I would use it.
> > Not sure what you mean by BRANCH.  There's one in ELSE but its use with multiple
> > WHILE is optional and rarely needed in my experience.
>
> I meant 0BRANCH --- in the WHILE.
>
> Actually, now that I think about it, WHILE has one 0BRANCH, but IF EXIT THEN has a
> 0BRANCH (the IF) plus an EXIT --- so my technique is slightly slower. On the MiniForth,
> calling a colon word was very fast, but this isn't necessarily true on other Forths ---
> so, putting the loop in its own colon word can make my technique yet slower.
>
> As a practical matter, we are talking about a few microseconds difference here, so it
> doesn't really matter very much.
>
> I think my technique results in much more readable code than the ANS-Forth
> multiple-WHILE technique due to ANS-Forth requiring THEN after the REPEAT which is
> pretty baffling --- ANS-Forth is gratuitously complicated and generally baffling ---
> ANS-Forth is just a problem that has to be worked around.

UNTIL/REPEAT ... THEN is apt indicating the multiple exit points which
users may exploit.  Use in Forth predates ANS (Thinking Forth, cmFORTH).




[toc] | [prev] | [next] | [standalone]


#36307

Fromlehs <skydda.barnen@gmail.com>
Date2015-02-05 08:54 -0800
Message-ID<1b420c91-f8d4-45fc-8537-2fe9b1433747@googlegroups.com>
In reply to#36263
Den onsdag 4 februari 2015 kl. 08:24:32 UTC+1 skrev Faisal:
> I tried LEAVE, but it is not working
> 
> : test
> 	begin dup 0 >= while
> 		dup .
> 		1 -
> 		exitapp@ 1 = IF
> 		  leave 
> 		then 
> 	repeat
> 	.
> ;

I sometimes use a redefined control structure:
VARIABLE CSP
: +CSP ( -- p )  CSP @ DUP CELL+ CSP ! ;
: -CSP ( -- )  CSP @ 1 CELLS - CSP ! ;
: !CSP ( -- )  SP@ +CSP ! ;
: CSP@ ( -- )  CSP @ 1 CELLS - @ ;
: BEGIN! [COMPILE] BEGIN !CSP ; IMMEDIATE
: BREAK? POSTPONE 0= [COMPILE] IF ; IMMEDIATE

: AGAIN? \ --
  [COMPILE] IF
  POSTPONE FALSE
  BEGIN SP@ CSP@ = 0=
  WHILE
    [COMPILE] ELSE
    POSTPONE TRUE
    [COMPILE] THEN
  REPEAT -CSP
  [COMPILE] UNTIL
; IMMEDIATE

: EXAMPLE
  10
  BEGIN! 1- DUP . DUP 0=
  BREAK? 1- DUP . DUP 0=
  BREAK? 1- DUP . DUP 
  AGAIN? DROP ;

It works on SP-FORTH, but EXAMPLE doesn't load in SwiftForth for evaluation..?

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.forth


csiph-web