Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #36263 > unrolled thread
| Started by | Faisal <faisalm83@gmail.com> |
|---|---|
| First post | 2015-02-03 23:24 -0800 |
| Last post | 2015-02-05 08:54 -0800 |
| Articles | 15 — 8 participants |
Back to article view | Back to comp.lang.forth
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
| From | Faisal <faisalm83@gmail.com> |
|---|---|
| Date | 2015-02-03 23:24 -0800 |
| Subject | What 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]
| From | Mark Wills <markwills1970@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Mark Wills <markwills1970@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Coos Haak <chforth@hccnet.nl> |
|---|---|
| Date | 2015-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]
| From | "Rod Pemberton" <buzz@notnotnontnooatno.cmm> |
|---|---|
| Date | 2015-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2015-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2015-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]
| From | JennyB <jennybrien@googlemail.com> |
|---|---|
| Date | 2015-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2015-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]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2015-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2015-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]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2015-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2015-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]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2015-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]
| From | lehs <skydda.barnen@gmail.com> |
|---|---|
| Date | 2015-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