[comp.lang.forth] FOR NEXT etc

wsbusup@eutws1.win.tue.nl (Jan Stout) (02/07/91)

FS>      might I offer clarity, simplicity, readability arguments in favor  of
FS>FOR/NEXT?  In addition there are the many loops that do not need  access to
FS>the index.  FOR/NEXT's index is down counting.  In many  situations its index
FS>I can be used as conveniently as FOR/NEXT's I.   And, since implementations
FS>vary, I don't see that it is clear that  DO/LOOP is more efficient even in
FS>those cases that do use the  upcounting index.  Depending on the
FS>implementation, it may be that  either computing the index is less efficient
FS>or that testing the loop  termination condition is less efficient (or both)
FS>than using FOR/NEXT  either with or without its index.  I believe that Robert
FS>Berkey has  offered implementation examples of both FOR/NEXT and DO/LOOP in
FS>terms  of the other.  All in all I am of the opinion that neither can be 
FS>declared the "best" loop based only in terms of efficiency of its 
FS>implementation.

After your reply I tried real hard at reading PYGMY.SCR and finding ways
to DO FOR in, but I admit to've found very little.
(Except perhaps for the missing +NEXT so I can
 - . 2^i (1<=2^i<N) with : .EM ( N) 
                            1 SWAP
                            FOR  DUP .  2*  DUP +NEXT  DROP ;
 - : -TRAILING ( A #)
      DUP
      FOR  1- 2DUP  C@ BL =
         IF 1 ELSE DUP THEN
      +NEXT DROP ; 
   ( Admittedly a trick but I'd prefer this to the WHILE/THEN approach)

I tend to agree on the readability & don't consider Mitch's 0 ?DO a real
solution, letting the programmer type what he knows will be 'ignored' by
the compiler.(see below)
So I think you unwillingly (?) created another FOR NEXTer.

FS>I have even been speculating lately whether I should  convert to an *up-
FS>counting* index in FOR/NEXT.  One of the arguments in  favor of FOR/NEXT has
FS>been its simplicity of keeping only one item on  the return stack and the ease
FS>of testing it for loop termination (<is  it zero yet?>).  I would give that up
FS>to get my up-counting index.  I  have come to no conclusion yet about this.

To assist you in reaching a conclusion:

: THRU ( 1st last) ( keep scr# on returnstack)
   ( * this would get much simpler if FOR used an upcounting I)
   OVER - 1+ SWAP PUSH
   FOR POP POP DUP 1+ PUSH SWAP PUSH LOAD ?SCROLL NEXT
   POP DROP ;

converts nicely into the "FOR counter (location) independant"

: THRU ( 1st last)
   1+ OVER -
   FOR  DUP PUSH  LOAD  POP 1+  ?SCROLL  NEXT  DROP ;

Only I would not rename >R and R> because I'd like to have
PUSH & POP available for my STACK abstract data type, so that:
: >R   RETURN-STACK PUSH ;  
: R@   RETURN-STACK TOP ;
: R>   RETURN-STACK POP ;
and perhaps
: >USER USER-STACK PUSH ;
: USER@ USER-STACK TOP ;
: USER> USER-STACK POP ;
but of course that my opinion :) 

BTW Robert Berkeys DO implementation (as appeared in PYGMY.SCR) with
    I adding an offset was more or less the way I implemented it in ML,
    so use of I whitin FOR NEXT seems dangerous practice in the portability
    sense, it even may suggest no addressing of the counter all...?)

FS>    First, I'm not very interested in conforming to the standards of  other
FS>language so that "we" will be better accepted.  I may be wrong in  this.  Jax
FS>argues eloquently for the standard from a financial  standpoint.  I might even
FS>use the standard for that very purpose  someday.  If we want to be better
FS>accepted by making Forth look like C  or Pascal or Fortran there is a much
FS>cheaper, more straight forward  shortcut to that goal: just use C or Pascal or
FS>Fortran.  Bang! An  instant solution. 
FS>   Second, didn't Dijkstra complain that other languages were  standardized
way too soon? 

Ok if it was just a question of use in contemperary CLs I would not argue this
so hard, the fact is that the {whole scientific}\{Forth 'xx} community uses the dp this way
and I think in that ligth the semantic change seems ridiculus.

RC> There are two ways of judging a new idea:
RC>  1. Reject it and try and find ways to substantiate your rejection (you will
RC>     always succeed).
RC>  2. Accept it and try it with a positive attitude.

Ok but judgement becomes a lot more acceptable to the being judged when
some kind of argument is given to the acception (I figure rejectors already
take this attitude:)

MB>It should be easy for the compiler to figure out that it can do the
MB>optimization.  Chuck wasted a lot of people's time when he introduced
MB>a new function to handle a special case of an existing construct, rather
MB>than make his compiler a little smarter.  The compiler optimization would
MB>have made everybody's existing code run faster, rather than making everybody
MB>rewrite their code, which then would be incompatible with systems without
MB>FOR .. NEXT .
MB>Admittedly, DO .. LOOP is a bit of a crock, but it is a crock with a lot
MB>of history behind it, and it does in fact work.

I would take the attitude of a ' DOILOOPBLOCK LOAD in the existing application
and use FORNEXT in the newer ones, fully exploiting the wellpraised
extensibility of FORTH.

Jan Stout, wsbusup@eutws1.win.tue.nl