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


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

The extended Eaker-Pelc CASE as general control structure

Started byanton@mips.complang.tuwien.ac.at (Anton Ertl)
First post2016-02-06 18:15 +0000
Last post2016-02-11 19:45 +0000
Articles 10 on this page of 30 — 7 participants

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


Contents

  The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-06 18:15 +0000
    Re: The extended Eaker-Pelc CASE as general control structure JennyB <jennybrien@googlemail.com> - 2016-02-07 03:57 -0800
      Re: The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-08 12:59 +0000
        Re: The extended Eaker-Pelc CASE as general control structure JennyB <jennybrien@googlemail.com> - 2016-02-08 09:48 -0800
          Re: The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-08 18:10 +0000
            Re: The extended Eaker-Pelc CASE as general control structure JennyB <jennybrien@googlemail.com> - 2016-02-09 14:02 -0800
              Short-circuit evaluation (was: The extended Eaker-Pelc CASE ...) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-10 16:10 +0000
    Re: The extended Eaker-Pelc CASE as general control structure "WJ" <w_a_x_man@yahoo.com> - 2016-02-07 14:32 +0000
    Re: The extended Eaker-Pelc CASE as general control structure "WJ" <w_a_x_man@yahoo.com> - 2016-02-07 14:53 +0000
      Re: The extended Eaker-Pelc CASE as general control structure Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-02-07 15:56 +0000
        Re: The extended Eaker-Pelc CASE as general control structure stephen@mpeforth.com (Stephen Pelc) - 2016-02-07 18:11 +0000
          Re: The extended Eaker-Pelc CASE as general control structure "HAA" <someone@microsoft.com> - 2016-02-08 12:04 +1100
            Re: The extended Eaker-Pelc CASE as general control structure stephen@mpeforth.com (Stephen Pelc) - 2016-02-08 10:29 +0000
              Re: The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-08 11:00 +0000
                Re: The extended Eaker-Pelc CASE as general control structure stephen@mpeforth.com (Stephen Pelc) - 2016-02-08 12:28 +0000
                  Re: The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-08 15:26 +0000
                    Re: The extended Eaker-Pelc CASE as general control structure stephen@mpeforth.com (Stephen Pelc) - 2016-02-08 16:16 +0000
                      Re: The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-08 16:37 +0000
                    Re: The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-08 16:21 +0000
              Re: The extended Eaker-Pelc CASE as general control structure "HAA" <someone@microsoft.com> - 2016-02-11 21:12 +1100
                Re: The extended Eaker-Pelc CASE as general control structure stephen@mpeforth.com (Stephen Pelc) - 2016-02-11 10:46 +0000
        Re: The extended Eaker-Pelc CASE as general control structure JennyB <jennybrien@googlemail.com> - 2016-02-07 12:33 -0800
          Re: The extended Eaker-Pelc CASE as general control structure stephen@mpeforth.com (Stephen Pelc) - 2016-02-08 10:38 +0000
    Re: The extended Eaker-Pelc CASE as general control structure "HAA" <someone@microsoft.com> - 2016-02-08 12:07 +1100
      Re: The extended Eaker-Pelc CASE as general control structure anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-08 11:11 +0000
        Re: The extended Eaker-Pelc CASE as general control structure Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-02-08 14:49 +0000
        Re: The extended Eaker-Pelc CASE as general control structure "HAA" <someone@microsoft.com> - 2016-02-09 20:31 +1100
          Re: The extended Eaker-Pelc CASE as general control structure hughaguilar96@gmail.com - 2016-02-09 12:38 -0800
        Re: The extended Eaker-Pelc CASE as general control structure "WJ" <w_a_x_man@yahoo.com> - 2016-02-11 14:23 +0000
          Re: The extended Eaker-Pelc CASE as general control structure "WJ" <w_a_x_man@yahoo.com> - 2016-02-11 19:45 +0000

Page 2 of 2 — ← Prev page 1 [2]


#45441

Fromstephen@mpeforth.com (Stephen Pelc)
Date2016-02-11 10:46 +0000
Message-ID<56bc6623.24895107@news.eternal-september.org>
In reply to#45439
On Thu, 11 Feb 2016 21:12:24 +1100, "HAA" <someone@microsoft.com>
wrote:

>Standardize?  In the 397 source files included with the VFX demo, not a
>single use of NEXTCASE or NEXT-CASE.  Oh yes - Forth desperately
>needs this.

I wasn't the one who proposed it for standardisation. What I have said
is that IMHO it's a neater notation for loops with multiple exits and
multiple exit actions.

Readable code matters.

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]


#45342

FromJennyB <jennybrien@googlemail.com>
Date2016-02-07 12:33 -0800
Message-ID<80b46ec0-08dd-41d3-b23a-0b235793d48c@googlegroups.com>
In reply to#45338
On Sunday, 7 February 2016 15:56:49 UTC, Albert van der Horst  wrote:

> I hate it when CASE is transformed into a disguised loop.

Me too. I've just noticed that

CASE 
     cond1 IF 
      ... 
     cond n IF 

     action 
   UNCASE 

 And Wil Baden's short-circuiting ORIF and AND IF 


  If cond1 or (cond2 and cond3) 

   CASE 
    cond1 FALSE OF 
    cond2 TRUE OF 
    cond3 
   UNCASE 
    IF  

won't work if CASE adds a hidden dest, because it will be hidden from UNCASE by the unresolved forward branches.

So: CASE always means  'upcoming forward branches to be resolved at a single point' and BEGIN always means 'upcoming backward branches ditto.' and if you need both, then you use both. 

Just as with   WHILE ... AGAIN ... THEN the forward branches don't have to be resolved at a backwards bracnh. so you you can do:

   CASE BEGIN ...  UNTIL done_only_on false_until UNCASE
or CASE BEGIN ...  WHILE ... RETURN done_only_on_false_while UNCASE

> If I'd redesign the Forth looping, I'd totally ignore the pseudo
> general control flow stack and I'd go for
> 
> do   : start of loop
> od   : end of loop:
>        if there are loop parameters, increment like LOOP else
>        just restart (like AGAIN)

I don't see how you can distinguish loop parameters from whatever else might be on the stack.

If I were doing counted loops from scratch, I'd use a primitive that did a count-to-zero and didn't do any cleanup, and a similar one that took an increment from the stack.  In high level code:

      : (NEXT) ]] R> 1- DUP R> 0= UNTIL [[ ; Immediate
      : (STEP) ]] DUP R@ U> SWAP R> U- >R UNTIL [[ ; Immediate

(I think - I'm a bit rusty at this) 

A high-level loop that needs an index would push a suitable base under the count and use 2R@ - to count up towards it, or 2R@ - to count down.

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


#45352

Fromstephen@mpeforth.com (Stephen Pelc)
Date2016-02-08 10:38 +0000
Message-ID<56b86e55.162984665@news.eternal-september.org>
In reply to#45342
On Sun, 7 Feb 2016 12:33:23 -0800 (PST), JennyB
<jennybrien@googlemail.com> wrote:

>> I hate it when CASE is transformed into a disguised loop.
>
>Me too. I've just noticed that

Much as I normally agree with arguments such as this, the problem
being solved is about readability of code in a coding situation
that is already ugly - there is no neat solution except for 
"don't do that".

My original proposition was that to produce a loop with multiple
exit conditions and associated exit actions, the Eaker CASE notation
was good because the exit conditions and actions are close together
in the source code. The only syntactic change required was the
addition of NEXTCASE.

As discussed elsewhere, the current VFX implementation uses
BEGINCASE ... NEXTCASE as well as CASE ... ENDCASE. The use of 
OF and friends remains unchanged.

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]


#45344

From"HAA" <someone@microsoft.com>
Date2016-02-08 12:07 +1100
Message-ID<n98pmj$1lca$2@gioia.aioe.org>
In reply to#45329
Anton Ertl wrote:
> ...
> On the benefits: Consider a loop with three exit conditions, with a
> different action necessary on each exit, and afterwards a common
> action is necessary.  With the extended CASE you can write this as
>
> case
>   condition1 ?of exit-action1 endof
>   condition2 ?of exit-action2 endof
>   condition3 ?of exit-action3 endof
>   ...
> next-case
> common-action
>
> If you want to do this with EXIT or a multi-WHILE loop, things get
> cumbersome.  Of course, Forthers often try to rationalize such
> problems as encouraging factoring or somesuch, but if it really is
> better factoring, do you really need to restrict your tools to achieve
> this; and the workarounds for such problems are not always better
> factoring.

But such examples are the exception - not the rule.  It's cheaper (and
IMO cleaner) to factor out a large multi-test loop than to create tools
you'll rarely use to put it in-line.

< ...
> CONTOF is useful if you have
> different iteration actions depending on the condition.  Here's an
> example:
>
> : gcd ( n1 n2 -- n )
>     case
>         2dup > ?of tuck - contof
>         2dup < ?of over - contof
>     endcase ;
>
> ...
> And here's an example where the all words except ENDCASE are used:
>
> : collatz ( u -- )
>     \ print the 3n+1 sequence starting at u until we reach 1
>     case
>         dup .
>         1 of endof
>         dup 1 and ?of 3 * 1+ contof
>         2/
>     next-case ;

WHILE exists and is an everyday word.  This fact alone makes it worth
learning how to use it to your advantage.

: gcd ( n1 n2 -- n )
    begin begin
        2dup > while  tuck - again  then
        2dup < while  over - again  then
    drop ;

: collatz ( u -- )
    \ print the 3n+1 sequence starting at u until we reach 1
    begin begin
        dup .
        1 over = if  drop exit  then
        dup 1 and while  3 * 1+ again  then
        2/
    again ;




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


#45357

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-02-08 11:11 +0000
Message-ID<2016Feb8.121100@mips.complang.tuwien.ac.at>
In reply to#45344
"HAA" <someone@microsoft.com> writes:
>Anton Ertl wrote:
>> ...
>> On the benefits: Consider a loop with three exit conditions, with a
>> different action necessary on each exit, and afterwards a common
>> action is necessary.  With the extended CASE you can write this as
>>
>> case
>>   condition1 ?of exit-action1 endof
>>   condition2 ?of exit-action2 endof
>>   condition3 ?of exit-action3 endof
>>   ...
>> next-case
>> common-action
>>
>> If you want to do this with EXIT or a multi-WHILE loop, things get
>> cumbersome.  Of course, Forthers often try to rationalize such
>> problems as encouraging factoring or somesuch, but if it really is
>> better factoring, do you really need to restrict your tools to achieve
>> this; and the workarounds for such problems are not always better
>> factoring.
>
>But such examples are the exception - not the rule.  It's cheaper (and
>IMO cleaner) to factor out a large multi-test loop than to create tools
>you'll rarely use to put it in-line.

Actually multi-exit loops are not that rare; every search loop has
multiple exits: one for the search and the other for reaching the end
of the search space.  If we use CASE for every multi-exit loop, it
will not be rare.  And the benefit IMO is that it is more readable
than BEGIN ... WHILE ... WHILE ... REPEAT ... ELSE ... THEN, and also
more readable than unnatural factorings based on using EXIT.

Sure, a common Forth approach is to provide several special, cheaper
solutions instead of an expensive general one, and let the user select
among these special solutions depending on the problem, and try to
bend the problem towards these special solutions if necessary.

And once you have that mindset, you tend to see all general solutions
as expensive, and bending the problem as a virtue.  But in the present
case the general solution is cheap, and using it has the potential
benefit of more readability from always using the same approach for
multi-condition loops.

>WHILE exists and is an everyday word.  This fact alone makes it worth
>learning how to use it to your advantage.
>
>: gcd ( n1 n2 -- n )
>    begin begin
>        2dup > while  tuck - again  then
>        2dup < while  over - again  then
>    drop ;

Cute.  AGAIN THEN is REPEAT, and with more conventional indentation we
get:

: gcd ( n1 n2 -- n )
  begin
    begin
      2dup > while
         tuck -
    repeat
    2dup < while
      over - 
  repeat ;

>: collatz ( u -- )
>    \ print the 3n+1 sequence starting at u until we reach 1
>    begin begin
>        dup .
>        1 over = if  drop exit  then
>        dup 1 and while  3 * 1+ again  then
>        2/
>    again ;

: collatz ( u -- )
  begin
    begin
      dup .
      dup 1 = if
        drop exit then
      dup 1 and while
        3 * 1+
    repeat
    2/
  again ;

But here we already use EXIT (making common code afterwards
cumbersome), because we cannot use WHILE in that spot to jump behind
the AGAIN.

- 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]


#45363

FromAlbert van der Horst <albert@spenarnc.xs4all.nl>
Date2016-02-08 14:49 +0000
Message-ID<56b8ab15$0$23851$e4fe514c@news.xs4all.nl>
In reply to#45357
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:

<SNIP>
>Actually multi-exit loops are not that rare; every search loop has
>multiple exits: one for the search and the other for reaching the end
>of the search space.  If we use CASE for every multi-exit loop, it
>will not be rare.  And the benefit IMO is that it is more readable
>than BEGIN ... WHILE ... WHILE ... REPEAT ... ELSE ... THEN, and also
>more readable than unnatural factorings based on using EXIT.

Right.
Multiple exits/breaks fly in the face of the control stack.
They are supposed to jump to the same location, but there was
only one location stored on the control stack.
So confronted with this a Forth selects one of :
   using do loop (running out is one other exit )
   using multiple leaves
   an extra word with multiple exits.

As soon as neither of those is a natural fit for the problem,
things get ugly.

>Sure, a common Forth approach is to provide several special, cheaper
>solutions instead of an expensive general one, and let the user select
>among these special solutions depending on the problem, and try to
>bend the problem towards these special solutions if necessary.

>And once you have that mindset, you tend to see all general solutions
>as expensive, and bending the problem as a virtue.  But in the present
>case the general solution is cheap, and using it has the potential
>benefit of more readability from always using the same approach for
>multi-condition loops.

I agree that we should look for a general solution, at last.

<SNIP>

Groetjes Albert

>- 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/
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

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


#45385

From"HAA" <someone@microsoft.com>
Date2016-02-09 20:31 +1100
Message-ID<n9cbjo$qjb$1@gioia.aioe.org>
In reply to#45357
Anton Ertl wrote:
> "HAA" <someone@microsoft.com> writes:
> >Anton Ertl wrote:
> ...
> Actually multi-exit loops are not that rare; every search loop has
> multiple exits: one for the search and the other for reaching the end
> of the search space.

That's 2 exits.  One or two exits are commonplace.  Nobody uses CASE
when there is one or two exits because they know it's overkill.

MPE's NEXTCASE has been around for a decade or more yet AFAIK no
other Forth has bothered to implement it.  What does that tell you about
the practical need for such a thing.

> >: gcd ( n1 n2 -- n )
> >    begin begin
> >        2dup > while  tuck - again  then
> >        2dup < while  over - again  then
> >    drop ;
>
> Cute.

Cute because the code is near identical to yours *without* any extensions.

> >: collatz ( u -- )
> >    \ print the 3n+1 sequence starting at u until we reach 1
> >    begin begin
> >        dup .
> >        1 over = if  drop exit  then
> >        dup 1 and while  3 * 1+ again  then
> >        2/
> >    again ;
>
> : collatz ( u -- )
>   begin
>     begin
>       dup .
>       dup 1 = if
>         drop exit then
>       dup 1 and while
>         3 * 1+
>     repeat
>     2/
>   again ;
>
> But here we already use EXIT (making common code afterwards
> cumbersome), because we cannot use WHILE in that spot to jump behind
> the AGAIN.

I didn't choose the example.  EXIT is perfectly fine here.

Your problem is finding a loop example that justifies the CASE extensions.
The example has to be simple enough that factoring it out is not justified,
but not so simple that existing techniques can be used to solve it.
I doubt such an example exists because none have come to light in
40+ years of Forth.


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


#45411

Fromhughaguilar96@gmail.com
Date2016-02-09 12:38 -0800
Message-ID<d368b171-1609-4704-9dc5-67cec7d1d5be@googlegroups.com>
In reply to#45385
On Tuesday, February 9, 2016 at 2:30:39 AM UTC-7, HAA wrote:
> Anton Ertl wrote:
> > But here we already use EXIT (making common code afterwards
> > cumbersome), because we cannot use WHILE in that spot to jump behind
> > the AGAIN.
> 
> I didn't choose the example.  EXIT is perfectly fine here.
> 
> Your problem is finding a loop example that justifies the CASE extensions.
> The example has to be simple enough that factoring it out is not justified,
> but not so simple that existing techniques can be used to solve it.
> I doubt such an example exists because none have come to light in
> 40+ years of Forth.

You say that if the code inside is simple then factoring is not justified and so the EXIT technique (what I use) is inappropriate --- this isn't true --- the problem with factoring is that the code inside (whether simple or complicated) needs access to the local variables.

The solution is to have quotations with access to the parent function's local variables --- then the EXIT technique works fine --- weird nonsense such as this Eaker/Pelc CASE can be discarded.

The Forth-200x committee fail badly at fundamental language design --- they have two techniques that they use to avoid thinking:

1.) They just fake it --- the Paysan-faked quotations that aren't actually quotations because they lack access to the parent function's local variables --- putting such grossly fake code in the Forth-200x Standard makes the entire Forth community look stupid.

2.) They cover up their many failures with weird nonsense such as this Eaker/Pelc CASE construct --- Forth-200x is about an order of magnitude more complicated than necessary, so most novices quickly give up on learning it and never realize that buried underneath this great steaming pile of fertilizer is a rose.

The Forth-200x motto seems to be: "If you can't dazzle them with brilliance, then baffle them with bull!"

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


#45460

From"WJ" <w_a_x_man@yahoo.com>
Date2016-02-11 14:23 +0000
Message-ID<n9i5hl$nki$1@dont-email.me>
In reply to#45357
Anton Ertl wrote:

> 
> : collatz ( u -- )
>   begin
>     begin
>       dup .
>       dup 1 = if
>         drop exit then
>       dup 1 and while
>         3 * 1+
>     repeat
>     2/
>   again ;

Oforth:

: collatz(n)
  n .
  n 2 < ifTrue: [return]
  n n isOdd ifTrue: [3 * 1+] else: [2 /]
  collatz ;

33 collatz

33 100 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 ok

-- 
The report card by the American Society of Civil Engineers showed the national
infrastructure a single grade above failure, a step from declining to the point
where everyday things simply stop working the way people expect them to. ---
washingtonpost.com/local/trafficandcommuting/us-infrastructure-gets-d-in-annual-report/2013/03/19/c48cb010-900b-11e2-9cfd-36d6c9b5d7ad_story.html

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


#45465

From"WJ" <w_a_x_man@yahoo.com>
Date2016-02-11 19:45 +0000
Message-ID<n9ioc0$6dk$1@dont-email.me>
In reply to#45460
WJ wrote:

> Anton Ertl wrote:
> 
> > 
> > : collatz ( u -- )
> >   begin
> >     begin
> >       dup .
> >       dup 1 = if
> >         drop exit then
> >       dup 1 and while
> >         3 * 1+
> >     repeat
> >     2/
> >   again ;
> 
> Oforth:
> 
> : collatz(n)
>   n .
>   n 2 < ifTrue: [return]
>   n n isOdd ifTrue: [3 * 1+] else: [2 /]
>   collatz ;
> 
> 33 collatz
> 
> 33 100 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 ok

Which 2-digit number produces the longest Collatz sequence, and
how long is that sequence?

Oforth:

: collatz-length(n,len)
  n 2 < ifTrue: [len return]
  n n isOdd ifTrue: [3 * 1+] else: [2 /]
  len 1+ collatz-length ;

seqFrom(2,99) map(#[dup 1 collatz-length [,]]) maxFor(#last) .
 ===>
[97, 119] ok

-- 
Amazon bans book.  After nearly a month on the site, all traces of the book and
its 80 reviews have been removed.
http://jamesfetzer.blogspot.com/2015/11/debunking-sandy-hook-debunkers-5.html
https://www.youtube.com/watch?v=EEl_1HWFRfo

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

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


csiph-web