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


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

BEGIN WHILE UNTIL THEN

Started byJulian Fondren <julian.fondren@gmail.com>
First post2016-01-04 14:50 -0800
Last post2016-01-08 03:04 -0800
Articles 20 on this page of 100 — 18 participants

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


Contents

  BEGIN WHILE UNTIL THEN Julian Fondren <julian.fondren@gmail.com> - 2016-01-04 14:50 -0800
    Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-05 11:24 +1100
      Re: BEGIN WHILE UNTIL THEN Julian Fondren <julian.fondren@gmail.com> - 2016-01-04 16:47 -0800
        Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-05 12:17 +1100
        Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-05 10:51 +0000
          Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-05 15:06 +0000
    Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-04 17:25 -0800
      Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-05 13:06 +1100
        Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-04 21:42 -0800
          Re: BEGIN WHILE UNTIL THEN rickman <gnuarm@gmail.com> - 2016-01-05 01:48 -0500
          Re: BEGIN WHILE UNTIL THEN Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-05 11:15 +0000
          Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-06 14:35 +1100
    Re: BEGIN WHILE UNTIL THEN Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-05 02:04 +0000
    Re: BEGIN WHILE UNTIL THEN Julian Fondren <julian.fondren@gmail.com> - 2016-01-04 18:37 -0800
      Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-04 19:17 -0800
      Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-05 11:10 +0000
      Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-06 15:02 +1100
    Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:03 -0800
      Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:07 -0800
        Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:18 -0800
        Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:21 -0800
    Re: BEGIN WHILE UNTIL THEN Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-07 05:13 -0500
      Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-08 12:36 +1100
        Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-08 10:32 +0000
          Re: BEGIN WHILE UNTIL THEN Raimond Dragomir <raimond.dragomir@gmail.com> - 2016-01-08 02:55 -0800
            Re: BEGIN WHILE UNTIL THEN Coos Haak <chforth@hccnet.nl> - 2016-01-08 13:57 +0100
              Re: BEGIN WHILE UNTIL THEN Raimond Dragomir <raimond.dragomir@gmail.com> - 2016-01-08 06:55 -0800
                Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-08 15:06 -0800
                Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-08 16:59 -0800
                  Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-08 16:15 -1000
                    Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-08 22:23 -0800
                      Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-08 21:12 -1000
                        Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-09 08:04 -0800
                          Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-09 09:16 -1000
                            Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-10 15:31 +0000
                              Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-10 08:11 -0800
                              Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-10 09:42 -1000
                                Re: BEGIN WHILE UNTIL THEN Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-11 13:02 +0000
                                Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-13 16:20 +0000
                            Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-10 14:10 -0800
                            Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-11 18:38 -0800
                              Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-14 08:47 +1100
                                Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-13 17:24 -0800
                                  Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-13 19:25 -0800
                                  Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-14 22:09 +1100
                                    Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-14 16:21 +0000
                                      Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-16 11:34 +1100
                                        Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-16 03:43 +0100
                                          Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-19 18:01 +1100
                                            Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-19 23:07 +0100
                                              Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-21 14:29 +1100
                                                Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-21 22:25 +0100
                                                  Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-24 13:28 +1100
                                                    Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-25 01:31 +0100
                                                      Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-25 21:45 +1100
                                                        Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-25 10:24 -0800
                                                        Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-25 20:41 +0100
                                                          Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-28 20:39 +1100
                                                            Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-28 16:05 +0100
                                                Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-21 20:52 -0800
                                                  Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-24 13:16 +1100
                                    Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-14 08:46 -0800
                                      Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-16 11:34 +1100
                                        Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-15 20:53 -0800
                                Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-13 19:31 -0800
                      Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-11 09:29 +1100
                        Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-10 21:18 -0800
                          Re: BEGIN WHILE UNTIL THEN Paul Rubin <no.email@nospam.invalid> - 2016-01-10 21:29 -0800
                          Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-10 20:37 -1000
                          Re: BEGIN WHILE UNTIL THEN Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-11 09:05 +0000
                          Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-12 12:26 +1100
                    Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-10 14:18 -0800
                  Re: BEGIN WHILE UNTIL THEN Raimond Dragomir <raimond.dragomir@gmail.com> - 2016-01-08 23:31 -0800
                    Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-09 08:09 -0800
                  Re: BEGIN WHILE UNTIL THEN Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-09 05:31 -0600
                    Re: BEGIN WHILE UNTIL THEN Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-09 07:52 -0600
                Re: BEGIN WHILE UNTIL THEN Ron Aaron <rambamist@gmail.com> - 2016-01-09 18:22 +0200
                Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-09 16:29 +0000
            Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-08 11:23 +0000
              Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-10 20:17 -0800
                Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-11 11:56 +0000
                Re: BEGIN WHILE UNTIL THEN Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-11 11:59 +0000
                  generalized CASE (was: BEGIN WHILE UNTIL THEN) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-11 12:30 +0000
                    Re: generalized CASE (was: BEGIN WHILE UNTIL THEN) hughaguilar96@gmail.com - 2016-01-11 13:52 -0800
                    Re: generalized CASE Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-11 22:00 +0000
                      Re: generalized CASE Coos Haak <chforth@hccnet.nl> - 2016-01-12 01:50 +0100
                  Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-11 14:16 -0800
                    Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-11 16:17 -0800
                    Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-12 13:07 +0000
                    Re: BEGIN WHILE UNTIL THEN Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-12 20:48 +0000
                      Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-12 14:16 -0800
            Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-08 16:21 +0000
              Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-08 20:12 +0000
                Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-09 18:19 +0000
                Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-11 09:34 +1100
              Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-08 21:13 +0100
          Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-09 23:46 +1100
        Re: BEGIN WHILE UNTIL THEN Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-08 10:11 -0500
          Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-11 08:38 +1100
    Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-08 03:04 -0800

Page 5 of 5 — ← Prev page 1 2 3 4 [5]


#44757

Fromstephen@mpeforth.com (Stephen Pelc)
Date2016-01-11 11:56 +0000
Message-ID<56939737.2219350329@news.eternal-september.org>
In reply to#44750
On Sun, 10 Jan 2016 20:17:09 -0800 (PST), hughaguilar96@gmail.com
wrote:

>Anyway, your CASE ... NEXTCASE isn't as robust as Raimond's BREAK because y=
>ou require the test to be a comparison of two cells, whereas in Raimond's s=
>ystem the test can be anything --- if you are going to require the test to =
>be a comparison of two cells, then you would be better off with a jump-tabl=
>e as I described earlier.

The discussion includes possible options for standardisation to avoid
vendor lock-in. Surely that's part of my job as a standards committee 
member?

You make a valid point about two-cell comparison for equality only.
Many Forth systems (including VFX) provide ?OF as well as OF. Perhaps
that should be standardised too?

Stephen

-- 
Stephen Pelc, stephenXXX@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

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


#44758

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2016-01-11 11:59 +0000
Message-ID<n7059h$vai$1@dont-email.me>
In reply to#44750
On 11/01/2016 04:17, hughaguilar96@gmail.com wrote:
> On Friday, January 8, 2016 at 8:58:37 PM UTC-7, Stephen Pelc wrote:
>> >On Fri, 8 Jan 2016 02:55:19 -0800 (PST), Raimond Dragomir
>> ><raimond.dragomir@gmail.com>  wrote:
>> >
>>> > >Or implement a BREAK word for BEGIN...AGAIN and BEGIN...UNTIL loops:
>>> > >
>>> > >begin
>>> > >   test1 if thing1 break then
>>> > >   test2 if thing2 break then
>>> > >   ...
>>> > >again
>>> > >
>>> > >This way we can get rid of BEGIN...WHILE...REPEAT loops entirely.
>> >
>> >That looks almost like
>> >   CASE
>> >     test1 OF ... ENDOF
>> >     test2 OF ... ENDOF
>> >   NEXTCASE
>> >
>> >and all the infrastructure is already present in most systems.
>> >As I have said before, once you have such facilities, you will
>> >probably find find that are not used enough to justify their
>> >existence.
> I never heard of NEXTCASE before. This is because I never did
>  RTFM the VFX manual, as you have repeatedly told me to do.
>
> Maybe the reason why these facilities aren't used is because people don't
>  want vendor lock-in with VFX --- they are trying to write ANS-Forth code
> for portability --- ANS-Forth code isn't very portable though, so they
>  might as well just give up and accept vendor lock-in.

In 2012 in a similar discussion I posted an ANS Forth implementation 
NEXTCASE and other words that seem to meet your and Chris Curls 
objections. Another opportunity for you to complain about 'ugly, 
inefficient Forth code' :)

See 
https://groups.google.com/forum/?hl=en#!searchin/comp.lang.forth/nextcase/comp.lang.forth/64GKthsYVFs/1QTLZCyiHCUJ 
for the discussion, code and test program. For convenience the code follows:

-----------------------------------------------------

: case  ( -- dest 0 )  postpone begin 0 ; immediate

: cs-swap  ( orig1/dest1 orig2/dest2 -- orig2/dest2 orig1/dest1 )
     1 cs-roll
;

: of  ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 )
     >r
     postpone over postpone = postpone if postpone drop
     cs-swap r> 1+
; immediate

\ ?of tests a flag
: ?of  ( dest #of -- orig dest #of+1 ) \ run-time ( f -- )
     >r postpone if cs-swap r> 1+
; immediate

: endof  ( orig dest #of -- orig2 dest #of ) \ run-time ( -- )
     >r cs-swap postpone else cs-swap r>
; immediate

\ ?break is equivalent to an empty ?OF ENDOF
: ?break  ( dest #of -- orig dest #of+1 ) \ run-time ( f -- )
     >r postpone 0= postpone if cs-swap r> 1+
; immediate

: contof  ( orig dest #of -> dest #of-1 ) \ run-time ( -- )
     >r
     0 cs-pick postpone again cs-swap postpone then
     r> 1-
; immediate

: resolve-origs  ( orig1 ... orign n -- )
     0 ?do postpone then loop
;

: endcase  ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
     >r postpone drop postpone ahead cs-swap postpone again
     r> 1+ resolve-origs
; immediate

\ NEXTCASE loops back to CASE
: nextcase  ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
     >r postpone drop postpone again r> resolve-origs
; immediate

--------------------------------------------------------

-- 
Gerry

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


#44761 — generalized CASE (was: BEGIN WHILE UNTIL THEN)

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-01-11 12:30 +0000
Subjectgeneralized CASE (was: BEGIN WHILE UNTIL THEN)
Message-ID<2016Jan11.133011@mips.complang.tuwien.ac.at>
In reply to#44758
Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
>: of  ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 )
>     >r
>     postpone over postpone = postpone if postpone drop
>     cs-swap r> 1+
>; immediate

The compile-time stack effect should be: 

( dest #of -- orig dest #of+1), as for ?OF.

It seems to me that the whole package would be slightly simpler if the
stack effect would be ( dest #of -- dest orig #of+1 ), and that of
ENDOF ( dest orig #of -- orig2 dest #of ).

>\ NEXTCASE loops back to CASE
>: nextcase  ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
>     >r postpone drop postpone again r> resolve-origs
>; immediate

VFX also has NEXT-CASE (as well as an END-CASE) that does not expect
and drop the x.  I have a hard time coming up with loops where
NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE
seems more useful than ENDCASE.  However, I expect that the name
similarity to NEXTCASE/ENDCASE may confuse programmers and lead to
bugs.

In the Gforth sources we currently have DEFAULT: to deal with that: If
you don't use DEFAULT:, ENDCASE and NEXTCASE drop a value at run-time,
if you use DEFAULT:, they don't.  The idea is to use this in the
simplest case as:

CASE
  ... ?OF ... ENDOF
  ... ?OF ... ENDOF
  DEFAULT: defaultcode
ENDCASE
  
However, thinking about it again, this seems too roundabout, and we
are probably better off with

CASE
  ... ?OF ... ENDOF
  ... ?OF ... ENDOF
  defaultcode
0 ENDCASE

Of course the even better variant would be to only have END-CASE and
NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have
ENDCASE and have to live with it for a long time.  For the looping
variant, maybe we should go with NEXT-CASE only, though.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2015: http://www.rigwit.co.uk/EuroForth2015/

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


#44763 — Re: generalized CASE (was: BEGIN WHILE UNTIL THEN)

Fromhughaguilar96@gmail.com
Date2016-01-11 13:52 -0800
SubjectRe: generalized CASE (was: BEGIN WHILE UNTIL THEN)
Message-ID<342e3527-8524-48c8-a9e5-a25bd5ace982@googlegroups.com>
In reply to#44761
On Monday, January 11, 2016 at 7:44:05 AM UTC-7, Anton Ertl wrote:
> Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
> >: of  ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 )
> >     >r
> >     postpone over postpone = postpone if postpone drop
> >     cs-swap r> 1+
> >; immediate
> 
> The compile-time stack effect should be: 
> 
> ( dest #of -- orig dest #of+1), as for ?OF.
> 
> It seems to me that the whole package would be slightly simpler if the
> stack effect would be ( dest #of -- dest orig #of+1 ), and that of
> ENDOF ( dest orig #of -- orig2 dest #of ).
> 
> >\ NEXTCASE loops back to CASE
> >: nextcase  ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
> >     >r postpone drop postpone again r> resolve-origs
> >; immediate
> 
> VFX also has NEXT-CASE (as well as an END-CASE) that does not expect
> and drop the x.  I have a hard time coming up with loops where
> NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE
> seems more useful than ENDCASE.  However, I expect that the name
> similarity to NEXTCASE/ENDCASE may confuse programmers and lead to
> bugs.
> 
> In the Gforth sources we currently have DEFAULT: to deal with that: If
> you don't use DEFAULT:, ENDCASE and NEXTCASE drop a value at run-time,
> if you use DEFAULT:, they don't.  The idea is to use this in the
> simplest case as:
> 
> CASE
>   ... ?OF ... ENDOF
>   ... ?OF ... ENDOF
>   DEFAULT: defaultcode
> ENDCASE
>   
> However, thinking about it again, this seems too roundabout, and we
> are probably better off with
> 
> CASE
>   ... ?OF ... ENDOF
>   ... ?OF ... ENDOF
>   defaultcode
> 0 ENDCASE
> 
> Of course the even better variant would be to only have END-CASE and
> NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have
> ENDCASE and have to live with it for a long time.  For the looping
> variant, maybe we should go with NEXT-CASE only, though.
> 
> - anton
> -- 
> M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
> comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
>      New standard: http://www.forth200x.org/forth200x.html
>    EuroForth 2015: http://www.rigwit.co.uk/EuroForth2015/

You've got your NEXTCASE and ENDCASE mixed up throughout your post.

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


#44764 — Re: generalized CASE

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2016-01-11 22:00 +0000
SubjectRe: generalized CASE
Message-ID<n718hl$gd4$1@dont-email.me>
In reply to#44761
On 11/01/2016 12:30, Anton Ertl wrote:
> Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
>> : of  ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 )
>>      >r
>>      postpone over postpone = postpone if postpone drop
>>      cs-swap r> 1+
>> ; immediate
>
> The compile-time stack effect should be:
>
> ( dest #of -- orig dest #of+1), as for ?OF.

Yes, thank you.

>
> It seems to me that the whole package would be slightly simpler if the
> stack effect would be ( dest #of -- dest orig #of+1 ), and that of
> ENDOF ( dest orig #of -- orig2 dest #of ).
>
>> \ NEXTCASE loops back to CASE
>> : nextcase  ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
>>      >r postpone drop postpone again r> resolve-origs
>> ; immediate
>
> VFX also has NEXT-CASE (as well as an END-CASE) that does not expect
> and drop the x.  I have a hard time coming up with loops where
> NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE
> seems more useful than ENDCASE.  However, I expect that the name
> similarity to NEXTCASE/ENDCASE may confuse programmers and lead to
> bugs.

When I did this in 2012 I can't remember being aware of NEXT-CASE and 
END-CASE and I agree if they co-existed with ENDCASE and NEXTCASE that 
would be too confusing.

>
> Of course the even better variant would be to only have END-CASE and
> NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have
> ENDCASE and have to live with it for a long time.  For the looping
> variant, maybe we should go with NEXT-CASE only, though.
>

Given that virtually every other compound word is hyphenated it is 
rather strange that ENDOF and ENDCASE weren't hyphenated, I don't think 
they were standardised previously.

I think you and others have said that words like these CASE extensions 
have not been much used. I have to say that having written the code I 
posted I don't think I have ever used any of the extensions, certainly I 
haven't built them into my system.

-- 
Gerry

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


#44768 — Re: generalized CASE

FromCoos Haak <chforth@hccnet.nl>
Date2016-01-12 01:50 +0100
SubjectRe: generalized CASE
Message-ID<ysa9yvy1x1yl.1d04lcd1xoveo$.dlg@40tude.net>
In reply to#44764
Op Mon, 11 Jan 2016 22:00:56 +0000 schreef Gerry Jackson:

> On 11/01/2016 12:30, Anton Ertl wrote:
>> Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
>>> : of  ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 )
>>>      >r
>>>      postpone over postpone = postpone if postpone drop
>>>      cs-swap r> 1+
>>> ; immediate
>>
>> The compile-time stack effect should be:
>>
>> ( dest #of -- orig dest #of+1), as for ?OF.
> 
> Yes, thank you.
> 
>>
>> It seems to me that the whole package would be slightly simpler if the
>> stack effect would be ( dest #of -- dest orig #of+1 ), and that of
>> ENDOF ( dest orig #of -- orig2 dest #of ).
>>
>>> \ NEXTCASE loops back to CASE
>>> : nextcase  ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
>>>      >r postpone drop postpone again r> resolve-origs
>>> ; immediate
>>
>> VFX also has NEXT-CASE (as well as an END-CASE) that does not expect
>> and drop the x.  I have a hard time coming up with loops where
>> NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE
>> seems more useful than ENDCASE.  However, I expect that the name
>> similarity to NEXTCASE/ENDCASE may confuse programmers and lead to
>> bugs.
> 
> When I did this in 2012 I can't remember being aware of NEXT-CASE and 
> END-CASE and I agree if they co-existed with ENDCASE and NEXTCASE that 
> would be too confusing.
> 
>>
>> Of course the even better variant would be to only have END-CASE and
>> NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have
>> ENDCASE and have to live with it for a long time.  For the looping
>> variant, maybe we should go with NEXT-CASE only, though.
>>
> 
> Given that virtually every other compound word is hyphenated it is 
> rather strange that ENDOF and ENDCASE weren't hyphenated, I don't think 
> they were standardised previously.

The names ENDOF and ENDCASE were in the Case Context of Forth Dimensions
II, 3. That was back in 1980. The standard of the '90s did not change them.
I suppose that ENDOF was derived from ENDIF that had no hyphen either.

> 
> I think you and others have said that words like these CASE extensions 
> have not been much used. I have to say that having written the code I 
> posted I don't think I have ever used any of the extensions, certainly I 
> haven't built them into my system.

I heard about NEXTCASE only a few months ago and saw them in Gforth.
I can load it, and CONTOF, but never found it necessary.

groet Coos

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


#44765

Fromhughaguilar96@gmail.com
Date2016-01-11 14:16 -0800
Message-ID<1300bc89-75f3-4ac1-992d-0f0c2251deb0@googlegroups.com>
In reply to#44758
On Monday, January 11, 2016 at 4:59:16 AM UTC-7, Gerry wrote:
> In 2012 in a similar discussion I posted an ANS Forth implementation 
> NEXTCASE and other words that seem to meet your and Chris Curls 
> objections. Another opportunity for you to complain about 'ugly, 
> inefficient Forth code' :)

Your code is just generating nested IF statements. This is pretty much the same as that Forth Dimensions contest winner from the 1980s. 

Did you read what I said about the jump-table? This is how C does their SWITCH statement (also HLA and most likely every other serious language). This is two or three orders of magnitude faster than your method, depending upon how many test values there are.

What is sad about all of this is that Bernd Paysan and Anton Ertl are obviously aware of how fast this method is, because they write their Forth interpreter in C and they depend upon SWITCH to be fast. They don't consider using this method in Forth though, because they just consider Forth to be a toy language and they have no concern about speed. Anton Ertl is a college professor --- his students are writing toy programs that will never be used in the real world, so speed is not a concern --- all he really cares about is grading people's Forth code, as if he is naturally above everybody else (he was actually appointed to his job as Forth-200x chair-person by Elizabeth Rather, the ANS-Forth chair-person who appointed herself to that job).

In my experience, when I say that I'm a Forth programmer, the typical C programmer will say that he is not just a mere Forth application-programmer like me, but is a Forth compiler-writer, so he knows ever so much more about Forth than I do. In his next breath he will say that writing a Forth interpreter is a good exercise for people learning C, but the Forth interpreter itself is utterly useless for writing application programs. Rod Pemberton is typical in this with his assertion that C is the "God language" that toy interpreters (Forth, Python, Lua, etc.) are entirely dependent upon.

Since you are so proud of your CASE NEXTCASE code, how about writing a byte-code interpreter? A byte-code interpreter has upwards of 256 opcodes, so with your method that is upwards of 256 conditional tests for every opcode before your program figures out which opcode it has and is able to emulate it. Your program should be about three orders of magnitude slower than a comparable C program --- a great way to disprove the C programmers' assertion that Forth is too slow to be useful in the real world.

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


#44767

FromChris Curl <ccurl609@gmail.com>
Date2016-01-11 16:17 -0800
Message-ID<00034aff-8f9e-4ca4-aa7f-40aaf44805af@googlegroups.com>
In reply to#44765
On Monday, January 11, 2016 at 5:16:51 PM UTC-5, hughag...@gmail.com wrote:
> ...
> Since you are so proud of your CASE NEXTCASE code, how about writing a byte-code interpreter? 
> A byte-code interpreter has upwards of 256 opcodes, so with your method that is upwards of 256 
> conditional tests for every opcode before your program figures out which opcode it has and is
> able to emulate it. Your program should be about three orders of magnitude slower than a
> comparable C program --- a great way to disprove the C programmers' assertion that Forth is
> too slow to be useful in the real world.
My byte-code interpreter (written in assembler) has a jump table for the opcodes. It currently
 has about 100 such opcodes.

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


#44780

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-01-12 13:07 +0000
Message-ID<2016Jan12.140723@mips.complang.tuwien.ac.at>
In reply to#44765
hughaguilar96@gmail.com writes:
>What is sad about all of this is that Bernd Paysan and Anton Ertl are obvio=
>usly aware of how fast this method is, because they write their Forth inter=
>preter in C and they depend upon SWITCH to be fast.

LOL.  There are some usages of switch in the Gforth sources, but not
in parts where Gforth typically spends much time.  For anybody
interested in facts rather than (wrong) guesses, you can find what we
did in the beginning in [ertl93]

@InProceedings{ertl93,
  author = 	 "M. Anton Ertl",
  title = 	 "A Portable {Forth} Engine",
  booktitle =	 "EuroFORTH '93 conference proceedings",
  year =	 "1993",
  address =	 "Mari\'ansk\'e L\'azn\`e (Marienbad)",
  url =		 "http://www.complang.tuwien.ac.at/papers/ertl93.ps.gz",
  abstract = 	 "The Forth engine discussed in this paper is written
		  in GNU C, which provides several extensions that are
		  important for Forth implementation. The indirect
		  threaded Forth engine is completely
		  machine-independent, direct threading requires a few
		  machine-specific lines for each machine. Using
		  a portable language like GNU C encourages producing
		  an engine with many primitives. In order to make the
		  development of primitives easier and less
		  error-prone, an automatic tool generates most of the
		  code for a Forth primitive from the stack effect
		  notation, even if the TOS is kept in a register. The
		  engine is combined with the parts of the system
		  written in Forth by loading a machine-independent
		  image file that contains the executable Forth code
		  in relocatable form."
}

Later we expanded on that:

@InProceedings{ertl&gregg03,
  author =       "M. Anton Ertl and David Gregg",
  title =        "Optimizing Indirect Branch Prediction Accuracy in Virtual Machine Interpreters",
  crossref =     "sigplan03",
  OPTpages =	 "",
  url =		 "http://www.complang.tuwien.ac.at/papers/ertl%26gregg03.ps.gz",
  abstract =     "Interpreters designed for efficiency execute a huge
                  number of indirect branches and can spend more than
                  half of the execution time in indirect branch
                  mispredictions.  Branch target buffers are the best
                  widely available\mn{on all recent general-purpose
                  machines?} form of indirect branch prediction;
                  however, their prediction accuracy for existing
                  interpretes is only 2\%--50\%.  In this paper we
                  investigate two methods for improving the prediction
                  accuracy of BTBs for interpreters: replicating
                  virtual machine (VM) instructions and combining
                  sequences of VM instructions into superinstructions.
                  We investigate static (interpreter build-time) and
                  dynamic (interpreter run-time) variants of these
                  techniques and compare them and several combinations
                  of these techniques.  These techniques can eliminate
                  nearly all of the dispatch branch mispredictions,
                  and have other benefits, resulting in speedups by a
                  factor of up to 3.17 over efficient threaded-code
                  interpreters, and speedups by a factor of up to 1.3
                  over techniques relying on superinstructions alone."
}

@Proceedings{sigplan03,
  booktitle =    "SIGPLAN Conference on Programming Language
                  Design and Implementation (PLDI'03)",
  title =        "SIGPLAN Conference on Programming Language
                  Design and Implementation (PLDI'03)",
  year =         "2003",
  key =          "PLDI '03"
}

@InProceedings{ertl&gregg05,
  author =       {M. Anton Ertl and David Gregg},
  title =        {Stack Caching in {Forth}},
  crossref =     {euroforth05},
  pages =        {6--15},
  url =          {http://www.complang.tuwien.ac.at/papers/ertl%26gregg05.ps.gz},
  pdfurl =       {http://www.complang.tuwien.ac.at/anton/euroforth2005/papers/ertl%26gregg05.pdf},
  OPTnote =	 {not refereed},
  abstract =     {Stack caching speeds Forth up by keeping stack items
                  in registers, reducing the number of memory accesses
                  for stack items. This paper describes our work on
                  extending Gforth's stack caching implementation to
                  support more than one register in the canonical
                  state, and presents timing results for the resulting
                  Forth system. For single-representation stack
                  caches, keeping just one stack item in registers is
                  usually best, and provides speedups up to a factor
                  of 2.84 over the straight-forward stack
                  representation. For stack caches with multiple stack
                  representations, using the one-register
                  representation as canonical representation is
                  usually optimal, resulting in an overall speedup of
                  up to a factor of 3.80 (and up to a factor of 1.53
                  over single-representation stack caching).}
}

>Since you are so proud of your CASE NEXTCASE code, how about writing a byte=
>-code interpreter? A byte-code interpreter has upwards of 256 opcodes, so w=
>ith your method that is upwards of 256 conditional tests for every opcode b=
>efore your program figures out which opcode it has and is able to emulate i=
>t. Your program should be about three orders of magnitude slower than a com=
>parable C program --- a great way to disprove the C programmers' assertion =
>that Forth is too slow to be useful in the real world.

One will obviously not use Eaker's CASE for a virtual-machine
interpreter.  The standard Forth way to do large dispatches is to use
EXECUTE.  There are performance problems with that, because standard
Forth does not guarantee tail-call elimination, and compilers are
limited in their register allocation by not knowing the stack effect
of the EXECUTEd xt; PAF is a Forth dialect designed to fill these
holes, but for now is just an idea:

@InProceedings{ertl13-paf,
  author =       {M. Anton Ertl},
  title =        {{PAF}: A Portable Assembly Language},
  crossref =     {euroforth13},
  pages =        {30--38},
  url =          {http://www.complang.tuwien.ac.at/anton/euroforth/ef13/papers/ertl-paf.pdf},
  OPTnote =      {not refereed},
  abstract =     {A portable assembly language provides access to
                  machine-level features like memory addresses,
                  machine words, code addresses, and modulo
                  arithmetics, like assembly language, but abstracts
                  away differences between architectures like the
                  assembly language syntax, instruction encoding,
                  register set size, and addressing modes.  Forth
                  already satisfies a number of the characteristics of
                  a portable assembly language, and is therefore a
                  good basis.  This paper presents PAF, a portable
                  assembly language based on Forth, and specifically
                  discusses language features that other portable
                  assembly languages do not have, and their benefits;
                  it also discusses the differences from Forth.  The
                  main innovations of PAF are: tags indicate the
                  control flow for indirect branches and calls; and
                  PAF has two kinds of calls and definitions: the ABI
                  ones follow the platform's calling convention and
                  are useful for interfacing to the outside world,
                  while the PAF ones allow tail-call elimination and
                  are useful for implementing general control
                  structures.}
}

@Proceedings{euroforth13,
  title = 	 {29th EuroForth Conference},
  booktitle = 	 {29th EuroForth Conference},
  year = 	 {2013},
  key =		 {EuroForth'13},
  url =          {http://www.complang.tuwien.ac.at/anton/euroforth/ef13/papers/proceedings.pdf}
}

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2015: http://www.rigwit.co.uk/EuroForth2015/

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


#44793

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2016-01-12 20:48 +0000
Message-ID<n73omj$63c$1@dont-email.me>
In reply to#44765
On 11/01/2016 22:16, hughaguilar96@gmail.com wrote:
> On Monday, January 11, 2016 at 4:59:16 AM UTC-7, Gerry wrote:
>> In 2012 in a similar discussion I posted an ANS Forth implementation
>> NEXTCASE and other words that seem to meet your and Chris Curls
>> objections. Another opportunity for you to complain about 'ugly,
>> inefficient Forth code' :)
>
> Your code is just generating nested IF statements.

Tell me something I don't know.

>
> Did you read what I said about the jump-table? This is how C does their SWITCH statement (also HLA and most likely every other serious language). This is two or three orders of magnitude faster than your method, depending upon how many test values there are.
>

The specification for CASE etc permits code such as:
: foo  ( x -- )
    >r
    case
       aaa true of ( action a ) endof
       bbb true of ( action b ) endof
       ccc r@   of ( action c ) endof
       ddd wxyz of ( action d ) endof
       ...
    endcase
    ...
;
where aaa etc represent one or more Forth words. The values compared by 
OF may be repeated, calculated, passed in on the stack and may, 
therefore, be unknown at compile time. How would a jump-table handle 
those cases?

> Since you are so proud of your CASE NEXTCASE code, how about writing
>  a byte-code interpreter? A byte-code interpreter has upwards of 256
>  opcodes, so with your method that is upwards of 256 conditional tests
>  for every opcode before your program figures out which opcode it has
> and is able to emulate it. Your program should be about three orders
>  of magnitude slower than a comparable C program --- a great way to
>  disprove the C programmers' assertion that Forth is too slow to be
>  useful in the real world.

Surely you're not serious, are you being sarcastic? Anyway you're wrong, 
with a (large) tree of nested CASE statements it could be done in 8 
comparisons, e.g. testing opcode bit 7, then bit 6 etc. (this may not be 
a practical solution but suffices to refute your claim - in fact I'd 
hate to set it up and would use a jump table instead). Also look up the 
meaning of "upwards of".

-- 
Gerry

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


#44798

Fromhughaguilar96@gmail.com
Date2016-01-12 14:16 -0800
Message-ID<0eab0f6c-42f1-4cbc-bb4d-e3f9a478e4fe@googlegroups.com>
In reply to#44793
On Tuesday, January 12, 2016 at 1:48:56 PM UTC-7, Gerry wrote:
> On 11/01/2016 22:16, hughaguilar96@gmail.com wrote:
> > On Monday, January 11, 2016 at 4:59:16 AM UTC-7, Gerry wrote:
> >> In 2012 in a similar discussion I posted an ANS Forth implementation
> >> NEXTCASE and other words that seem to meet your and Chris Curls
> >> objections. Another opportunity for you to complain about 'ugly,
> >> inefficient Forth code' :)
> >
> > Your code is just generating nested IF statements.
> 
> Tell me something I don't know.

You can write nested IF statements yourself. Either use my method of putting the structure in a function by itself and using EXIT to get out, or just do this:

IF
ELSE IF
ELSE IF
ELSE IF
THEN THEN THEN THEN

If you don't want to count how many IF you have, and risk having the wrong number of THEN, then write some meta-compiling code that generates this for you (computers are good at counting).

If you are going to use CASE though, and it is going to compare a parameter to constant test values, then you should generate a jump-table because it is orders of magnitude more efficient.

> > Did you read what I said about the jump-table? This is how C does their SWITCH statement (also HLA and most likely every other serious language). This is two or three orders of magnitude faster than your method, depending upon how many test values there are.
> >
> 
> The specification for CASE etc permits code such as:
> : foo  ( x -- )
>     >r
>     case
>        aaa true of ( action a ) endof
>        bbb true of ( action b ) endof
>        ccc r@   of ( action c ) endof
>        ddd wxyz of ( action d ) endof
>        ...
>     endcase
>     ...
> ;
> where aaa etc represent one or more Forth words. The values compared by 
> OF may be repeated, calculated, passed in on the stack and may, 
> therefore, be unknown at compile time. How would a jump-table handle 
> those cases?

This is a very disengenious argument. It is obvious that if you need to do a series of conditional tests then you need nested IF statements. When you ask me how a jump-table would handle this, you are implying that I don't know anything about computer programming --- this is safer and more politically correct for you than to admit that Elizabeth Rather (the author of ANS-Forth) doesn't know anything about computer programming, which is why this goofy CASE statement became part of the Standard.

Also obvious, is that generating a flag and then comparing the flag to TRUE is nonsense --- this is going to result in inefficient code in a compiler such as SwiftForth that doesn't do any optimization, and it is just weird and hard-to-read --- you are contorting the ANS-Forth CASE in a desperate attempt to make it appear useful.

What I'm saying is that if you are going to compare a value to several constant test values (all from an ENUM most of the time), then it is best to use a jump-table.

> > Since you are so proud of your CASE NEXTCASE code, how about writing
> >  a byte-code interpreter? A byte-code interpreter has upwards of 256
> >  opcodes, so with your method that is upwards of 256 conditional tests
> >  for every opcode before your program figures out which opcode it has
> > and is able to emulate it. Your program should be about three orders
> >  of magnitude slower than a comparable C program --- a great way to
> >  disprove the C programmers' assertion that Forth is too slow to be
> >  useful in the real world.
> 
> Surely you're not serious, are you being sarcastic? Anyway you're wrong, 
> with a (large) tree of nested CASE statements it could be done in 8 
> comparisons, e.g. testing opcode bit 7, then bit 6 etc. (this may not be 
> a practical solution but suffices to refute your claim - in fact I'd 
> hate to set it up and would use a jump table instead). 

Nested CASE statements for a byte-code interpreter??? Surely you are not serious! You need to just use a jump-table.

I can write code in Forth to manually build a jump-table. I can do this in assembly-language too. The point of having a high-level language rather than assembly-language is that basic control structures such as this are provided --- you don't have to write low-level code like this manually --- similarly you have IF ELSE THEN rather than have to use labels like in most assembly-languages, and you don't write spaghetti code as bad assembly-language programmers are prone to doing.

I use jump-tables in Stundurd Forth --- note that I have a GOTO instruction in the processor --- I added GOTO specifically for the purpose of making jump-tables efficient.

I don't think that anybody on the ANS-Forth committee knew what a jump-table is. This is why they made that goofy CASE standard, when it is actually just nested IF statements. This is also why there is no GOTO in ANS-Forth.

> Also look up the 
> meaning of "upwards of".

Well, I looked it up --- you got me on that one --- I have apparently been using the term incorrectly for 40 years.

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


#44703

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-01-08 16:21 +0000
Message-ID<2016Jan8.172115@mips.complang.tuwien.ac.at>
In reply to#44685
Raimond Dragomir <raimond.dragomir@gmail.com> writes:
>Or implement a BREAK word for BEGIN...AGAIN and BEGIN...UNTIL loops:
>
>begin
>   test1 if thing1 break then
>   test2 if thing2 break then
>   ...
>again
>
>This way we can get rid of BEGIN...WHILE...REPEAT loops entirely.

You would also need a word to resolve all the BREAKs.  Redefining
AGAIN (one of the basic control flow words) to do that does not appear
to be a good idea.

Anyway, at one point following that line of thought led both Stephen
Pelc and me to implement generalized CASE variants (because the IF
... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not
make use of them.  Did we follow that line of thought too far?  But
other variants have not become popular, either.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2015: http://www.rigwit.co.uk/EuroForth2015/

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


#44711

Fromstephen@mpeforth.com (Stephen Pelc)
Date2016-01-08 20:12 +0000
Message-ID<56901637.1989718589@news.eternal-september.org>
In reply to#44703
On Fri, 08 Jan 2016 16:21:15 GMT, anton@mips.complang.tuwien.ac.at
(Anton Ertl) wrote:

>Anyway, at one point following that line of thought led both Stephen
>Pelc and me to implement generalized CASE variants (because the IF
>... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not
>make use of them.  Did we follow that line of thought too far?  But
>other variants have not become popular, either.

  CASE
    test1 OF ... ENDOF
    test2 OF ... ENDOF
  NEXTCASE

I view this as a "get out of jail card".

Forth has no easy way to produce a multiple-exit loop with
exit conditions. Despite lots of recommendations that people
factor more and perhaps (ooh! gasp!) return exit flags, people
persist in writing ugly code. IMHO, because CASE ... ENDCASE
has been in widespread use for a very long time, and is now
standard, perhaps we should consider adding NEXTCASE or some
other extension to solve the problem.

It may be that we have a chicken and egg problem here. If
we provide a solution it may get used,

Stephen

-- 
Stephen Pelc, stephenXXX@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

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


#44728

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-01-09 18:19 +0000
Message-ID<2016Jan9.191925@mips.complang.tuwien.ac.at>
In reply to#44711
stephen@mpeforth.com (Stephen Pelc) writes:
>On Fri, 08 Jan 2016 16:21:15 GMT, anton@mips.complang.tuwien.ac.at
>(Anton Ertl) wrote:
>
>>Anyway, at one point following that line of thought led both Stephen
>>Pelc and me to implement generalized CASE variants (because the IF
>>... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not
>>make use of them.  Did we follow that line of thought too far?  But
>>other variants have not become popular, either.
>
>  CASE
>    test1 OF ... ENDOF
>    test2 OF ... ENDOF
>  NEXTCASE

IIRC NEXTCASE has an inconvenient stack effect, and you also provide
NEXT-CASE with a better one.

Gforth (development version) also provides CONTOF for ending an OF and
jumping back to the CASE.  So if you do

CASE
  test1 ?OF ... CONTOF
  test2 ?OF ... CONTOF
  ...
ENDCASE

this corresponds to Dijkstra's do...od repetition: repeat until none
of the guards are true.

>It may be that we have a chicken and egg problem here. If
>we provide a solution it may get used,

My own non-existent usage of CONTOF and NEXTCASE argues against that,
but it might appeal to others.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2015: http://www.rigwit.co.uk/EuroForth2015/

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


#44748

From"HAA" <someone@microsoft.com>
Date2016-01-11 09:34 +1100
Message-ID<n6um98$16af$1@gioia.aioe.org>
In reply to#44711
Stephen Pelc wrote:
> On Fri, 08 Jan 2016 16:21:15 GMT, anton@mips.complang.tuwien.ac.at
> (Anton Ertl) wrote:
>
> >Anyway, at one point following that line of thought led both Stephen
> >Pelc and me to implement generalized CASE variants (because the IF
> >... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not
> >make use of them.  Did we follow that line of thought too far?  But
> >other variants have not become popular, either.
>
>   CASE
>     test1 OF ... ENDOF
>     test2 OF ... ENDOF
>   NEXTCASE
>
> I view this as a "get out of jail card".
>
> Forth has no easy way to produce a multiple-exit loop with
> exit conditions. Despite lots of recommendations that people
> factor more and perhaps (ooh! gasp!) return exit flags, people
> persist in writing ugly code. IMHO, because CASE ... ENDCASE
> has been in widespread use for a very long time, and is now
> standard, perhaps we should consider adding NEXTCASE or some
> other extension to solve the problem.
>
> It may be that we have a chicken and egg problem here. If
> we provide a solution it may get used,

The solution is to extend the control-flow words.  Justifying it is harder.


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


#44712

FromBernd Paysan <bernd.paysan@gmx.de>
Date2016-01-08 21:13 +0100
Message-ID<n6p54a$3nm$1@dont-email.me>
In reply to#44703
Anton Ertl wrote:

> Raimond Dragomir <raimond.dragomir@gmail.com> writes:
>>Or implement a BREAK word for BEGIN...AGAIN and BEGIN...UNTIL loops:
>>
>>begin
>>   test1 if thing1 break then
>>   test2 if thing2 break then
>>   ...
>>again
>>
>>This way we can get rid of BEGIN...WHILE...REPEAT loops entirely.
> 
> You would also need a word to resolve all the BREAKs.  Redefining
> AGAIN (one of the basic control flow words) to do that does not appear
> to be a good idea.

In Gforth, you can use BEGIN .. LEAVE .. DONE for that, all the LEAVEs will 
jump to DONE.  If you want a loop inside that, you need

BEGIN BEGIN
  test1 if thing1 LEAVE then
  test2 if thing2 LEAVE then
AGAIN DONE

Of course, you could write an AGAIN-DONE that only needs one BEGIN:

: AGAIN-DONE ( begin-sys -- )  ]] YET AGAIN DONE [[ ; immediate

(YET is 0 cs-pick, but immediate).

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ*
http://bernd-paysan.de/

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


#44720

From"HAA" <someone@microsoft.com>
Date2016-01-09 23:46 +1100
Message-ID<n6qvf5$tib$1@gioia.aioe.org>
In reply to#44683
Anton Ertl wrote:
> "HAA" <someone@microsoft.com> writes:
> >This is the problem ANS WHILE was designed to solve.  It lets you exit the
> >loop at different points avoiding the need to test (again) which condition
> >caused the exit e.g.
> >
> >    BEGIN   test1 WHILE   test2 WHILE ... REPEAT  exit2  ELSE  exit1  THEN
> >
> >    BEGIN   test1 WHILE   test2 UNTIL  exit2   ELSE  exit1  THEN
> >
> >Other variations:
> >
> >    BEGIN   test1 WHILE   test2 WHILE ... REPEAT  exit2  THEN  exit1
> >
> >    BEGIN   test1 WHILE   test2 WHILE ... REPEAT  THEN  exit1/exit2
> >
> >The topic is discussed by Brodie/Moore in 'Thinking FORTH' Chapter 8 ...
> >
> >"The value is that you get simpler programs.  And it costs nothing."
>
> There is a mind load cost in the first three examples: the exit
> fragments are not right where the corresponding conditions are, but
> you have to count the WHILEs and THENs and ELSEs, and match them up.
> That's why I prefer things like:
>
> begin
>   test1 if exit1 EXIT then
>   test2 if exit2 EXIT then
>   ...
> again

It appears not everyone on the GForth team shares your reservations...


Examples of multiple WHILE use in GForth 0.7.0

: scan
 >r BEGIN dup WHILE over c@ r@ <> WHILE 1 /string REPEAT THEN rdrop ;

: s>unumber? ( addr u -- ud flag )
    over [char] ' =
    IF  \ a ' alone is rather unusual :-)
 drop char+ c@ 0 true EXIT
    THEN
    base @ >r  dpl on  getbase
    0. 2swap
    BEGIN ( d addr len )
 dup >r >number dup
    WHILE \ there are characters left
 dup r> -
    WHILE \ the last >number parsed something
 dup 1- dpl ! over c@ [char] . =
    WHILE \ the current char is '.'
 1 /string
    REPEAT  THEN \ there are unparseable characters left
 2drop false
    ELSE
 rdrop 2drop true
    THEN
    r> base ! ;

: skip-defs ( -- )
    BEGIN  refill  WHILE  source -trailing nip 0= UNTIL  THEN ;

: (done) ( do-addr -- )
\G resolve branches of leave and ?leave and ?do
\G do-addr is the address of the beginning of our
\G loop so we can take care of nested loops
    tleavings @
    BEGIN  dup
    WHILE
 >r dup r@ cell+ @ \ address of branch
 u> 0=    \ lower than DO?
    WHILE
 r@ 2 cells + @ \ branch token
 branchtoresolve,
 r@ @ r> free throw
    REPEAT  r>  THEN
    tleavings ! drop ;

: (_debug) ( body ip -- )
        0 Nesting !
        BEGIN   Unnest off
                cr ." Scanning code..." cr C-Formated on
                swap scanword dbg-ip !
                cr ." Nesting debugger ready!" cr
                BEGIN   d.s disp-step D-Key
                WHILE   C-Stop @ 0=
                WHILE   0 get-next set-bp
                        dbg-ip @ jump
                        [ here DebugLoop ! ]
                        restore-bp
                REPEAT
                Nesting @ 0= IF EXIT THEN
                -1 Nesting +! r>
                ELSE
                get-next >r 1 Nesting +!
                THEN
                dup
        AGAIN ;

: -zeros ( addr u -- addr' u' )
  BEGIN  dup  WHILE  1- 2dup + c@ '0 <>  UNTIL  1+  THEN ;

: find-prev-line ( max addr -- max span addr pos2 )
  backward^ 2@ forward^ 2!
  over 2 + negate s>d backward^ 2@ d+ 0. dmax 2dup hist-setpos
  BEGIN
      backward^ 2!   2dup get-line  WHILE
      hist-pos 2dup forward^ 2@ d<  WHILE
      rot drop
  REPEAT  2drop  THEN  tuck ;

: extract-word ( addr len -- addr' len' )  dup >r
  BEGIN  1- dup 0>=  WHILE  2dup + c@ bl =  UNTIL  THEN  1+
  tuck + r> rot - ;

: \"-parse ( "string"<"> -- c-addr u ) \ gforth-internal  backslash-quote-parse
\G parses string, translating @code{\}-escapes to characters (as in
\G C).  The resulting string resides at @code{here}.  See @code{S\"}
\G for the supported @code{\-escapes}.
    here >r
    >in @ chars source chars over + >r + begin ( parse-area R: here parse-end )
 dup r@ < while
     dup c@ '" <> while
  dup c@ dup '\ = if ( parse-area c R: here parse-end )
      drop char+ dup r@ = abort" unfinished \-escape"
      \-escape c,
  else
      c, char+
  endif
 repeat then
    char+ source >r - r> min char/ >in !
    r> drop
    here r> - dup negate allot
    here swap char/ ;

: (BranchAddr?) ( a-addr1 -- a-addr2 true | false )
\ searches a branch with destination a-addr1
\ a-addr1: branch destination
\ a-addr2: pointer in branch table
        SearchPointer @
        BEGIN   dup BranchPointer @ u<
        WHILE
                dup @ 2 pick <>
        WHILE   3 cells +
        REPEAT
        nip dup  3 cells + SearchPointer ! true
        ELSE
        2drop false
        THEN ;

: MyBranch      ( a-addr -- a-addr a-addr2 )
\ finds branch table entry for branch at a-addr
                dup @
                BranchAddr?
                BEGIN
                WHILE 1 cells - @
                      over <>
                WHILE dup @
                      MoreBranchAddr?
                REPEAT
                SearchPointer @ 3 cells -
                ELSE    true ABORT" SEE: Table failure"
                THEN ;

: RepeatCheck ( a-addr1 a-addr2 true | false -- false )
        IF  BEGIN  2dup
                   1 cells - @ swap @
                   u<=
            WHILE  drop dup cell+
                   MoreBranchAddr? 0=
            UNTIL  false
            ELSE   true
            THEN
        ELSE false
        THEN ;

: see-code-next-inline { addr1 addr2 -- addr3 }
    \ decompile starting at addr1 until an inlined primitive is found,
    \ or addr2 is reached; addr3 is addr2 or the next inlined
    \ primitive
    addr1 begin { addr }
        addr addr2 u< while
            addr @ dup decompile-prim = while
                addr cr simple-see-word
                addr cell+
        repeat then
    addr ;

: u8len ( u8 -- n )
    dup      max-single-byte u< IF  drop 1  EXIT  THEN \ special case ASCII
    $800  2 >r
    BEGIN  2dup u>=  WHILE  5 lshift r> 1+ >r  dup 0= UNTIL  THEN
    2drop r> ;

: $> ( -- )
    BEGIN  source >in @ /string s" <$" search  0= WHILE
        type cr refill  0= UNTIL  EXIT  THEN
    nip source >in @ /string rot - dup 2 + >in +! type ;

: read-chunked ( fid -- ) base @ >r hex >r
    BEGIN  pad $100 r@ read-line throw  WHILE
 pad swap s>number drop dup WHILE  r@ add-chunk drop
 pad 1 r@ read-line throw  nip 0= UNTIL
    ELSE  drop  THEN  THEN  rdrop r> base ! ;

: skip   ( addr1 n1 char -- addr2 n2 ) \ gforth
    \G skip all characters equal to char
    >r
    BEGIN
 dup
    WHILE
 over c@ r@  =
    WHILE
 1 /string
    REPEAT  THEN
    rdrop ;

: -trailing  ( c_addr u1 -- c_addr u2 ) \ string dash-trailing
\G Adjust the string specified by @i{c-addr, u1} to remove all
\G trailing spaces. @i{u2} is the length of the modified string.
    BEGIN
 dup
    WHILE
 1- 2dup + c@ bl <>
    UNTIL  1+  THEN ;

: (f83find)  ( c_addr u f83name1 -- f83name2 )
    BEGIN  dup WHILE  (find-samelen)  dup  WHILE
 >r 2dup r@ cell+ char+ capscomp  0=
 IF  2drop r>  EXIT  THEN
 r> @
    REPEAT  THEN  nip nip ;

: (find-samelen) ( u f83name1 -- u f83name2/0 )
    BEGIN  2dup cell+ c@ $1F and <> WHILE  @  dup 0= UNTIL  THEN ;

: (parse-white)  ( c_addr1 u1 -- c_addr2 u2 )
 BEGIN  dup  WHILE  over c@ bl <=  WHILE  1 /string
 REPEAT  THEN  2dup
 BEGIN  dup  WHILE  over c@ bl >   WHILE  1 /string
 REPEAT  THEN  nip - ;

....





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


#44692

FromRod Pemberton <NoHaveNotOne@bcczxcfre.cmm>
Date2016-01-08 10:11 -0500
Message-ID<20160108101153.4d4729cc@_>
In reply to#44671
On Fri, 8 Jan 2016 12:36:25 +1100
"HAA" <someone@microsoft.com> wrote:

> Rod Pemberton wrote:

> > Since the BEGIN-UNTIL now exits for two
> > conditions, you must determine which condition caused
> > it to exit, afterwards.
> > ...  
> 
> This is the problem ANS WHILE was designed to solve.  It lets you
> exit the loop at different points avoiding the need to test (again)
> which condition caused the exit e.g.
> 
> ...
> 
> The topic is discussed by Brodie/Moore in 'Thinking FORTH' Chapter
> 8 ...
> 
> "The value is that you get simpler programs.  And it costs nothing."

It doesn't cost nothing.  The branching clearly increases.

My understanding is that modern processors are good with
single loops with a backwards branch.  That might be
somewhat simplistic or out of date, but the point of
branching complexity not being good remains.


Rod Pemberton

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


#44743

From"HAA" <someone@microsoft.com>
Date2016-01-11 08:38 +1100
Message-ID<n6uivl$t5q$1@gioia.aioe.org>
In reply to#44692
Rod Pemberton wrote:
> On Fri, 8 Jan 2016 12:36:25 +1100
> "HAA" <someone@microsoft.com> wrote:
>
> > Rod Pemberton wrote:
>
> > > Since the BEGIN-UNTIL now exits for two
> > > conditions, you must determine which condition caused
> > > it to exit, afterwards.
> > > ...
> >
> > This is the problem ANS WHILE was designed to solve.  It lets you
> > exit the loop at different points avoiding the need to test (again)
> > which condition caused the exit e.g.
> >
> > ...
> >
> > The topic is discussed by Brodie/Moore in 'Thinking FORTH' Chapter
> > 8 ...
> >
> > "The value is that you get simpler programs.  And it costs nothing."
>
> It doesn't cost nothing.  The branching clearly increases.
> ...

In general I expect ANS WHILE to reduce tests and branching.  When
you post complete working code it can be compared against the original.
The complexity of the logic you propose to use makes me suspicious.



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


#44686

Fromnovember.nihal@gmail.com
Date2016-01-08 03:04 -0800
Message-ID<24458bec-ee0e-4fbf-ba58-f79a56a80798@googlegroups.com>
In reply to#44558
On Monday, 4 January 2016 22:50:26 UTC, Julian Fondren  wrote:
> Hello clf,
> 
> The following code is from SwoopPortable.f
> 
>   : UPDATE-LINKS ( super link -- )   >R
>      BEGIN
>         DUP @ DUP WHILE                \ prev cur
>         R@ BEGIN                          \ prev cur sup
>            @ DUP WHILE                 \ prev cur sup'
>            2DUP = UNTIL
>            2DROP  R> @ SWAP !  EXIT
>         THEN DROP NIP
>      REPEAT R> DROP  2DROP ;
> 
> Can someone rewrite this with normal control-flow?
> 
> 
> Thanks,
> Julian


Hi Julian,


: update-links1 ( s a l -- T )(l -- ) 
		( s a l -- a F )(l -- l)

	begin @ dup while 	        ( s a l -- s a b ?b==true ) \ b <- l @ 
		2dup = if 		( s a b -- s a b ?a==b )
			2drop r> @ swap ! true exit ( s a b -- T) ( l -- ) 
		then 
	repeat 
	drop nip false ( s a b -- a F )( l -- l )   
	; 

: update-links ( s l -- ) 
	>r begin                   ( s l -- s )( -- l ) 
		dup @ dup while    ( s -- s a ?a==true )( l -- ) \ a<- s @  
		r@ update-links1 if exit then 
	repeat r> drop 2drop ;                              \ a become new s 


NN

[toc] | [prev] | [standalone]


Page 5 of 5 — ← Prev page 1 2 3 4 [5]

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


csiph-web