1. Goto (Was Re: Open Source)

In all my years of using Euphoria, I've never come across a situation where
I needed a goto. Well, not that I can remember. Even now, in my BBCMF program,
which is 839KB of code and 38 base include files (doesn't include the
include files included by the base include files), the only problems I've had
dealt with calling funcs/procs before they were defined. A simple/not-so-simple
shuffling of code usually deals with that and I find my code is better
organized afterward.

Would goto make my code quicker (like when breaking out of if...then)? That
would be the only reason I'd tolerate its inclusion into the interpreter.

new topic     » topic index » view message » categorize

2. Re: Goto (Was Re: Open Source)

Matt Lewis wrote:
> 
> Juergen Luethje wrote:
> > 
> > I do not make it a religion. Please do not put words into my mouth.
> > I just say that it's obsolete in high-level languages. This is of
> > course only true if a language provides sufficient other possibilities.
> > For instance in Euphoria, it would be useful not only to have an 'exit'
> > statement, but also the possibility to write something like
> > 
> >    exit <number of levels>
> 
> I've often thought this, too, although that construct worries me.  What
> happens if the levels change?  Even if they don't change, it's not trivial 
> to figure out the target of that exit.  A label-based exit, OTOH, can be 
> very useful, and explicit.
> 
> For example, perl allows you to name a block (which could be a while/for/etc)
> and to use the next/last operators along with the block name:
> 
> <a
> href="http://en.wikipedia.org/wiki/Perl_control_structures">http://en.wikipedia.org/wiki/Perl_control_structures</a>
> 
> A euphorian implementation might look like:
> }}}
<eucode>
> :mainloop for i = 1 to n do
>     ...
>     :jloop for j = 1 to m do
>         ....
>         if foo then 
>             exit :mainloop 
>         end if
>         while foo > 5 do
>             ...
>             if bar then
>                exit :jloop
>             end if
>             ...
>     end for
> end for
> </eucode>
{{{

> That keeps the labels firmly associated with their proper loops.  It 
> makes the goal very clear, although at the expense of clarity of where
> you're going:
> }}}
<eucode>
> 
> for i = 1 to n do
>     ...
>     for j = 1 to m do
>         ....
>         if foo then 
>             goto :mainloop 
>         end if
>         while foo > 5 do
>             ...
>             if bar then
>                goto :jloop
>             end if
>             ...
>     end for
>     :jloop
> end for
> :mainloop
> </eucode>
{{{

> I can see benefits to both ways, though I think I would prefer keeping 
> them associated with the loop.  It's also how exits work right now.
> 
> Matt

Or maybe, a more restricted solution that doesn't include labels:
   exit <for-loop variable>
The for-loop variable would be optional.

- Fernando

new topic     » goto parent     » topic index » view message » categorize

3. Re: Goto (Was Re: Open Source)

c.k.lester wrote:
> 
> In all my years of using Euphoria, I've never come across a situation where
> I needed a goto.
Happened to me once, when translating some old COBOL I had lying around...
Otherwise I have no need for it.

That said, I would accept goto with the following restrictions, ottomh:

1) goto is not permitted outside routines, much like the return statement.
   (bleats of "why not?" are quite likely to go unanswered)
2) All labels are local/private and all goto targets must be resolved by
   the <end routine> statement. There is no chance ever of jumping from
   one routine to another, by accident or design.
3) goto labels are simple fixed static literals, not variables/strings.
   I personally think <label>:: is best, to avoid conflict with namespaces.
4) Backward jumps are illegal while any forward jump is unresolved. When a  
   label is defined, if any forward references to it are resolved then all 
   prior labels are tagged as invalid. These measures should effectively 
   prevent spaghetti code. You can have as many forward jumps to as many 
   labels as you like, or the same for backward jumps, but once they start 
   to overlap then all the problems begin.
5) The tail-resursive goto <this routine>(params) should be supported.
   (technical details permitting)
6) next j and redo j should be supported at any nesting level within a for 
   j=<init> to <limit> loop. while loops have no such special keywords.
   For some reason I always find "continue" a bit vague and ambiguous.
7) Jumps into for loops are not permitted since the control var is not 
   initialised and anything that deals with it up to and including the 
   endfor is optimised to not have to deal with that case (trust me, you'd 
   be miffed at the performance hit if it had to).
8) exit N and friends should not be supported as they thwart refactoring,
   as well as, I predict, being worse than goto to decipher.
9) The docs should say something like: goto can be used to escape from 
   deeply nested clauses, in cases where you cannot see a better way to do 
   it or you want to avoid setting a flag and testing it 3 or 4 times on the
   way out, or if you want a single block of error handling code (with 
   multiple entry points) separate from the main algorithm. However if you 
   find yourself adding more than one or two goto statements a day, there is 
   probably something wrong with your coding style. To avoid excessive use, 
   Eu prohibits overlapping forward and backward jumps (aka "spaghetti 
   code"), also jumps into for loops are not permitted since <as above>

While I certainly do not want to see the likes of goto "Z" & ias[idx], I would
accept a (fixed literal) jump table as eg:
goto {Zint,Zatm,Zseq}[idx]
Zint:: puts(1,"Z is an integer, well idx is 1 anyway\n")
       return
Zatm:: puts(1,"Z is an atom, well idx is 2 anyway\n")
       return
Zseq:: puts(1,"Z is a sequence, well idx is 3 anyway\n")
       return

That is, until someone comes up with something better (as opposed to something
horribly inelegant and downright dangerous, doh).

Again though, I have no personal need for any of this stuff.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

4. Re: Goto (Was Re: Open Source)

I'm sorry for the delay in repleying.

Fernando Bauer wrote:

> Matt Lewis wrote:
> > 
> > Juergen Luethje wrote:
> > > 
> > > I do not make it a religion. Please do not put words into my mouth.
> > > I just say that it's obsolete in high-level languages. This is of
> > > course only true if a language provides sufficient other possibilities.
> > > For instance in Euphoria, it would be useful not only to have an 'exit'
> > > statement, but also the possibility to write something like
> > > 
> > >    exit <number of levels>
> > 
> > I've often thought this, too, although that construct worries me.  What
> > happens if the levels change?  Even if they don't change, it's not trivial 
> > to figure out the target of that exit.  A label-based exit, OTOH, can be 
> > very useful, and explicit.
> > 
> > For example, perl allows you to name a block (which could be a
> > while/for/etc)
> > and to use the next/last operators along with the block name:
> > 
> > <a
> > href="http://en.wikipedia.org/wiki/Perl_control_structures">http://en.wikipedia.org/wiki/Perl_control_structures</a>
> > 
> > A euphorian implementation might look like:
> > }}}
<eucode>
> > :mainloop for i = 1 to n do
> >     ...
> >     :jloop for j = 1 to m do
> >         ....
> >         if foo then 
> >             exit :mainloop 
> >         end if
> >         while foo > 5 do
> >             ...
> >             if bar then
> >                exit :jloop
> >             end if
> >             ...
> >     end for
> > end for
> > </eucode>
{{{

> > That keeps the labels firmly associated with their proper loops.

Matt, I agree that would be better than my proposal above.
BTW: I vaguely recall now, that Derek had suggested something similiar
some years ago, but I can't remember any details.

> > It 
> > makes the goal very clear, although at the expense of clarity of where
> > you're going:
> > }}}
<eucode>
> > 
> > for i = 1 to n do
> >     ...
> >     for j = 1 to m do
> >         ....
> >         if foo then 
> >             goto :mainloop 
> >         end if
> >         while foo > 5 do
> >             ...
> >             if bar then
> >                goto :jloop
> >             end if
> >             ...
> >     end for
> >     :jloop
> > end for
> > :mainloop
> > </eucode>
{{{

> > I can see benefits to both ways, though I think I would prefer keeping 
> > them associated with the loop.  It's also how exits work right now.
> > 
> > Matt
> 
> Or maybe, a more restricted solution that doesn't include labels:
>    exit <for-loop variable>
> The for-loop variable would be optional.
> 
> - Fernando

This would not always work for 'while' loops. I'd prefer a generic
solution that works for all kinds of loops.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

5. Re: Goto (Was Re: Open Source)

Juergen Luethje wrote:
> Matt, I agree that would be better than my proposal above.
> BTW: I vaguely recall now, that Derek had suggested something similiar
> some years ago, but I can't remember any details.

Yes I did.

http://www.users.bigpond.com/ddparnell/euphoria/product.htm

Item #24 "Support for named loops and blocks"

-- 
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell

new topic     » goto parent     » topic index » view message » categorize

6. Re: Goto (Was Re: Open Source)

Derek Parnell wrote:
> 
> Juergen Luethje wrote:
> > Matt, I agree that would be better than my proposal above.
> > BTW: I vaguely recall now, that Derek had suggested something similiar
> > some years ago, but I can't remember any details.
> 
> Yes I did.
> 
> http://www.users.bigpond.com/ddparnell/euphoria/product.htm
> 
> Item #24 "Support for named loops and blocks"

I had totally forgotten about that page.  It's kinda neat to see that we've
managed to get a few of those into the code:

  1. Namespaces (the page is light on details, but I think it's basically
     the same as what's in there now)
  6. 'Length of Sequence' syntax item.
 30. User defined crash routines.
 32. 'Compile-to-P-code' option.

And then there are those that I think are good ideas to consider:

  3. Assignment on declaration
  4. 'Next Interation' keyword
  5. 'Repeat Current Iteration' keyword
  7. Scope of a 'For' loop counter to extend beyond the loop.
  8. 'Constant' declaration to be scoped at routine-level.
 14. Ensure that the interpreter can support operating system threads.
 20. Pass parameters by reference.
 21. GOTO construct.
 23. Code blocks within routines with their own scope.
 24. Named loops and blocks
 25. Memory mapped data (C structs)
 26. Dynamic interpretation (execute strings)
 47. Case Statement
 48. Routine_id() for Built-ins
 49. Variable_id() function

Matt

new topic     » goto parent     » topic index » view message » categorize

7. Re: Goto (Was Re: Open Source)

Matt Lewis wrote:
> 
> Derek Parnell wrote:
> > 
> > Juergen Luethje wrote:
> > > Matt, I agree that would be better than my proposal above.
> > > BTW: I vaguely recall now, that Derek had suggested something similiar
> > > some years ago, but I can't remember any details.
> > 
> > Yes I did.
> > 
> > <a
> > href="http://www.users.bigpond.com/ddparnell/euphoria/product.htm">http://www.users.bigpond.com/ddparnell/euphoria/product.htm</a>
> > 
> > Item #24 "Support for named loops and blocks"
> 
> I had totally forgotten about that page.  It's kinda neat to see that we've
> managed to get a few of those into the code:
> 
>   1. Namespaces (the page is light on details, but I think it's basically
>      the same as what's in there now)
>   6. 'Length of Sequence' syntax item.
>  30. User defined crash routines.
>  32. 'Compile-to-P-code' option.
> 
> And then there are those that I think are good ideas to consider:
> 
>   3. Assignment on declaration
>   4. 'Next Interation' keyword
>   5. 'Repeat Current Iteration' keyword
>   7. Scope of a 'For' loop counter to extend beyond the loop.
>   8. 'Constant' declaration to be scoped at routine-level.
>  14. Ensure that the interpreter can support operating system threads.
>  20. Pass parameters by reference.
>  21. GOTO construct.
>  23. Code blocks within routines with their own scope.
>  24. Named loops and blocks
>  25. Memory mapped data (C structs)
>  26. Dynamic interpretation (execute strings)
>  47. Case Statement
>  48. Routine_id() for Built-ins
>  49. Variable_id() function
> 
> Matt

Items #7 and #21...

I hope by scope you mean old scope and new scope, where the old
scope stays only until the new scope begins otherwise much code
as it is now would not work at all.

As for #21, in the whole time i have used Eu i have only really
needed a goto once i think (well ok maybe three times in the
same block of code).  I do agree that there should be some
other way to get out of nested loops.

while 1 do
  while 2 do
    while 3 do
      while 4 do
        if x<1 then
          goto Exit
        end if
      end while --4
    end while --3
  end while --2
end while --1

:Exit:
DoMoreStuff()


The very block of code i am talking about i went to rewrite
one time and found it almost easier to emulate a forward goto
with tests and stuff rather than figure out how to exit the
tests using while loops.  Strange though, that was the only time
in almost ten years of using Eu i had a problem that goto would
have solved.


Take care,
Al

E boa sorte com sua programacao Euphoria!


My bumper sticker: "I brake for LED's"

 From "Black Knight":
"I can live with losing the good fight,
 but i can not live without fighting it".
"Well on second thought, maybe not."

new topic     » goto parent     » topic index » view message » categorize

8. Re: Goto (Was Re: Open Source)

Al Getz wrote:
> 
> Matt Lewis wrote:
> > 
> > Derek Parnell wrote:
> > > 
> > > http://www.users.bigpond.com/ddparnell/euphoria/product.htm


> >   7. Scope of a 'For' loop counter to extend beyond the loop.
> >  21. GOTO construct.

> Items #7 and #21...
> 
> I hope by scope you mean old scope and new scope, where the old
> scope stays only until the new scope begins otherwise much code
> as it is now would not work at all.

I don't really mean anything by them, since I didn't write them.  However,
for an answer to your question, I would suggest to RTFP: 

http://www.users.bigpond.com/ddparnell/euphoria/product.htm#Allow%20the%20scope%20of%20a%20'For'%20loop%20counter%20to%20extend%20beyond%20the%20loop.
 
Matt

new topic     » goto parent     » topic index » view message » categorize

9. Re: Goto (Was Re: Open Source)

Matt Lewis wrote:
> 
> Derek Parnell wrote:
> > 
> > Juergen Luethje wrote:
> > > Matt, I agree that would be better than my proposal above.
> > > BTW: I vaguely recall now, that Derek had suggested something similiar
> > > some years ago, but I can't remember any details.
> > 
> > Yes I did.
> > 
> > <a
> > href="http://www.users.bigpond.com/ddparnell/euphoria/product.htm">http://www.users.bigpond.com/ddparnell/euphoria/product.htm</a>
> > 
> > Item #24 "Support for named loops and blocks"
> 
> I had totally forgotten about that page.  It's kinda neat to see that we've
> managed to get a few of those into the code:
> 
>   1. Namespaces (the page is light on details, but I think it's basically
>      the same as what's in there now)
>   6. 'Length of Sequence' syntax item.
>  30. User defined crash routines.
>  32. 'Compile-to-P-code' option.
> 
> And then there are those that I think are good ideas to consider:
> 
> Matt
 
I would suggest that that page is an excellent list of ideas that should be
considered before venturing further (I've been left far behind in some of the
discussions here i.e. on Namespacing).
As perhaps a more basic coder I like the ones that reduce the verbosity of the
code (and the 'problems' I have to cope with the most) and I feel these would be
most appreciated by new users. So IMVHO the ones I think should be considered for
adding first are (with some comments)..
 
  3. Assignment on declaration 
- I can't see any downside to this? It removes a potentially confusing
       difference between constants and other variables and more importantly saves
       typing!
  24. Named loops and blocks 
- I like the elegance of "exit i" but as discussed it won't work on while
       loops so I guess labels are the way to go and this would save all those extra
       flags you have to add.
  4. 'Next Interation' keyword
  5. 'Repeat Current Iteration' keyword
  7. Scope of a 'For' loop counter to extend beyond the loop.
<whispering>
  21. GOTO construct. 
- I have no great desire for this and don't (really don't!) want to start
       any new disputes but just a small suggestion.. GOTO is disliked as it could
       branch anywhere in the code and thus become difficult to follow. How about if it
       was only allowed within the scope of its own proc/func?
<\whispering>

Regards PeteS

new topic     » goto parent     » topic index » view message » categorize

10. Re: Goto (Was Re: Open Source)

Pete Stoner wrote:

<snip>

> <whispering>
>   21. GOTO construct. 
>        - I have no great desire for this and don't (really don't!) want to
>        start
> any new disputes but just a small suggestion.. GOTO is disliked as it could
> branch anywhere in the code and thus become difficult to follow. How about if
> it was only allowed within the scope of its own proc/func? 
> <\whispering>

That means people can write procedures/functions with 200, 500 or even
more lines, and then jump back and forth in those routines like they want.
What is the advantage?

This whole discussion is not logical for me. Someone asks for intrducing
GOTO into Euphoria, and other people make suggestions how to limit the
damage then.
The first question should be: Why does someone want GOTO, and exactly
_for what purposes_? I'm pretty sure then we can find more appropriate
constructs for the desired purposes -- high level constructs for the
high level language Euphoria.

Regards, Juergen

new topic     » goto parent     » topic index » view message » categorize

11. Re: Goto (Was Re: Open Source)

Juergen Luethje wrote:
> 
> This whole discussion is not logical for me. Someone asks for intrducing
> GOTO into Euphoria, and other people make suggestions how to limit the
> damage then.
> The first question should be: Why does someone want GOTO, and exactly
> _for what purposes_? I'm pretty sure then we can find more appropriate
> constructs for the desired purposes -- high level constructs for the
> high level language Euphoria.
> 
Since you ask, I would say to translate a working program written in another
language to Eu. As I recently said, I am not advocating goto, just not standing
against it. Here is one case you probably already saw:

int parse()
{
    Token   tok;

reading:
    tok = gettoken();
    if (tok == END)
        return ACCEPT;
shifting:
    if (shift(tok))
        goto reading;
reducing:
    if (reduce(tok))
        goto shifting;
    return ERROR;
}

And here is that cobol fragment I spoke of last week:

PAGE "Optimised best-fit algorithm"
PROGRAM BEST
DATA DIVISION
77 REQUIRED PIC 9(12) COMP
	VALUE 1659  * Size of G1A
*
77 LIMIT    PIC 9(4) COMP
	VALUE 6     * Length of table
*
01 SIZES
  02 SIZE OCCURS 250	PIC 9(12) COMP
	    VALUE  798
	    VALUE  344
	    VALUE  650
	    VALUE  410
	    VALUE  382
	    VALUE  734
*
01 TS
  02 FILLER PIC 9(4) COMP
	VALUE 6     * Entry length in bytes
  02 TSMAX  PIC 9(4) COMP   * No of entries
  02 FILLER PIC 9(4) COMP   * Work field for sort
  02 FILLER PIC 9(4) COMP
	VALUE 1     * Start of sort key
  02 FILLER PIC 9(4) COMP
	VALUE 6     * Length of sort key
*
01 INCSET
  02 INCLUDE OCCURS 250 PIC X	* 1..250
*
77 LOW-BEST PIC 9(12) COMP
77 LOW-LEVEL	PIC 9(4) COMP
77 LOWSET   PIC X(250)
*
77 HIGH-BEST	PIC 9(12) COMP
77 HIGH-LEVEL	PIC 9(4) COMP
77 HIGHSET  PIC X(250)
*
77 WORK-TOT PIC 9(12) COMP
77 BA-TOT   PIC 9(12) COMP
*
77 LEVEL    PIC 9(4) COMP
77 BA-LEVEL PIC 9(4) COMP
*
77 ITEM     PIC 9(4) COMP
*
01 FILLER REDEFINES ITEM
  02 FILLER PIC X
  02 ITB2   PIC X	* 1..250
*
77 BA-ITEM  PIC 9(4) COMP
*
01 FILLER REDEFINES BA-ITEM
  02 FILLER PIC X
  02 BA-ITB2	PIC X	    * 1..250
*
77 INDEX    PIC 9(4) COMP
77 BA-IDX   PIC 9(4) COMP
*
PROCEDURE DIVISION
    MOVE LIMIT TO TSMAX
    CALL TSRT$ USING TS SIZES          -- a sort()
    PERFORM DA-FIND-COMBINATION
    ON NO EXCEPTION                    -- eg "EXIT 1" gives exception;
	DO                             --  (In Eu just use a flag)
	MOVE WORK-TOT TO BA-TOT
	MOVE LEVEL TO BA-LEVEL
	PERFORM BA-DISPLAY
	PERFORM DA200
	ON EXCEPTION FINISH
	ENDDO
    END
    MOVE LOWSET TO INCSET
    MOVE LOW-LEVEL TO BA-LEVEL
    MOVE LOW-BEST TO BA-TOT
    DISPLAY "Lower figure"
    PERFORM BA-DISPLAY
    MOVE HIGHSET TO INCSET
    MOVE HIGH-LEVEL TO BA-LEVEL
    MOVE HIGH-BEST TO BA-TOT
    DISPLAY "Higher figure"
    PERFORM BA-DISPLAY
EXIT
 
SECTION BA-DISPLAY
    DISPLAY BA-TOT
    DO FOR BA-IDX = 1 TO BA-LEVEL
	MOVE 0 TO BA-ITEM
	MOVE INCLUDE(BA-IDX) TO BA-ITB2       -- uses () for subscripts!
	DISPLAY BA-ITEM
	DISPLAY "  " SAMELINE
	DISPLAY SIZE(BA-ITEM) SAMELINE
    ENDDO
    DISPLAY "       Key <CR>"
    SVC 6 USING 1                   -- wait_key()
    ON EXCEPTION
    END
EXIT
 
SECTION DA-FIND-COMBINATION
*
* This section tries to find a set of sizes which add up to the
* required amount exactly.
*
    MOVE 1 TO LEVEL
    MOVE 0 TO LOW-BEST
    MOVE 999999999 TO HIGH-BEST
    MOVE LIMIT TO ITEM
DA100.
    MOVE ITB2 TO INCLUDE(LEVEL)
*
* Add size(item) to work-tot
*
    $LOAD SIZE(ITEM)     -- you can follow this, I trust. acc = size[item].
    $ADDS WORK-TOT                               --  work_tot+=acc
    $SUB REQUIRED                    -- acc = size[item]+work_tot-required
    $EXIT EQ		* Found exact fit
    $JUMP GT DA200	    * Too big
*
* This set is smaller than required - save it if it is best so far
*
    IF WORK-TOT > LOW-BEST
	$ADDS LOW-BEST
	MOVE LEVEL TO LOW-LEVEL
	MOVE INCSET TO LOWSET
    END
    IF ITEM > 1 	* More to be tested
	$STORE ITEM
	ADD 1 TO LEVEL	    * Leave item in table;
	GOTO DA100
DA200.
*
* This set is larger than required - save it if it is best so far
*
	IF WORK-TOT < HIGH-BEST
	$ADDS HIGH-BEST
	MOVE LEVEL TO HIGH-LEVEL
	MOVE INCSET TO HIGHSET
	END
    END
DA300.
*
* Now we need to backtrack;  remove item from running total and look
* at the next instead.
*
* Subtract size(item) from work-tot
*
    $LOAD 0
    $SUB SIZE(ITEM)
    $ADDS WORK-TOT
    IF ITEM > 1 	* More to be tested
	$STORE ITEM	* Look at next (overwrite item in table)
	GOTO DA100
    END
*
* We have exhausted all possibilities at this level; backtrack to
* a previous level.
*
    MOVE #00 TO INCLUDE(LEVEL)
    ADD -1 TO LEVEL
    $EXIT EQ 1		* All done
    MOVE 0 TO ITEM
    MOVE INCLUDE(LEVEL) TO ITB2
    GOTO DA300
 
ENDPROG

I found it quite a challenge to get that working in Eu.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

12. Re: Goto (Was Re: Open Source)

Pete Lomax wrote:

> Juergen Luethje wrote:
> > 
> > This whole discussion is not logical for me. Someone asks for intrducing
> > GOTO into Euphoria, and other people make suggestions how to limit the
> > damage then.
> > The first question should be: Why does someone want GOTO, and exactly
> > _for what purposes_? I'm pretty sure then we can find more appropriate
> > constructs for the desired purposes -- high level constructs for the
> > high level language Euphoria.
> > 
> Since you ask, I would say to translate a working program written in another
> language to Eu.

This is a concrete reason which provides a solid basis for discussing, thanks.

> As I recently said, I am not advocating goto, just not standing
> against it. Here is one case you probably already saw:
> 
> int parse()
> {
>     Token   tok;
> 
> reading:
>     tok = gettoken();
>     if (tok == END)
>         return ACCEPT;
> shifting:
>     if (shift(tok))
>         goto reading;
> reducing:
>     if (reduce(tok))
>         goto shifting;
>     return ERROR;
> }

If I didn't make a mistake, this translates to the following Eu program:
procedure foo ()
   Token tok
   
   while 1 do
      -- reading
      tok = gettoken()
      if tok = END then
         return ACCEPT
      end if
      
      while 1 do
         -- shifting
         if shift(tok) then
            exit
         end if
         -- reducing
         if not reduce(tok) then
            return ERROR
         end if
      end while
   end while
end procedure


> And here is that cobol fragment I spoke of last week:
> 
> PAGE "Optimised best-fit algorithm"
> PROGRAM BEST
> DATA DIVISION
> 77 REQUIRED PIC 9(12) COMP
> 	VALUE 1659  * Size of G1A
> *
> 77 LIMIT    PIC 9(4) COMP
> 	VALUE 6     * Length of table
> *
> 01 SIZES
>   02 SIZE OCCURS 250	PIC 9(12) COMP
> 	    VALUE  798
> 	    VALUE  344
> 	    VALUE  650
> 	    VALUE  410
> 	    VALUE  382
> 	    VALUE  734
> *
> 01 TS
>   02 FILLER PIC 9(4) COMP
> 	VALUE 6     * Entry length in bytes
>   02 TSMAX  PIC 9(4) COMP   * No of entries
>   02 FILLER PIC 9(4) COMP   * Work field for sort
>   02 FILLER PIC 9(4) COMP
> 	VALUE 1     * Start of sort key
>   02 FILLER PIC 9(4) COMP
> 	VALUE 6     * Length of sort key
> *
> 01 INCSET
>   02 INCLUDE OCCURS 250 PIC X	* 1..250
> *
> 77 LOW-BEST PIC 9(12) COMP
> 77 LOW-LEVEL	PIC 9(4) COMP
> 77 LOWSET   PIC X(250)
> *
> 77 HIGH-BEST	PIC 9(12) COMP
> 77 HIGH-LEVEL	PIC 9(4) COMP
> 77 HIGHSET  PIC X(250)
> *
> 77 WORK-TOT PIC 9(12) COMP
> 77 BA-TOT   PIC 9(12) COMP
> *
> 77 LEVEL    PIC 9(4) COMP
> 77 BA-LEVEL PIC 9(4) COMP
> *
> 77 ITEM     PIC 9(4) COMP
> *
> 01 FILLER REDEFINES ITEM
>   02 FILLER PIC X
>   02 ITB2   PIC X	* 1..250
> *
> 77 BA-ITEM  PIC 9(4) COMP
> *
> 01 FILLER REDEFINES BA-ITEM
>   02 FILLER PIC X
>   02 BA-ITB2	PIC X	    * 1..250
> *
> 77 INDEX    PIC 9(4) COMP
> 77 BA-IDX   PIC 9(4) COMP
> *
> PROCEDURE DIVISION
>     MOVE LIMIT TO TSMAX
>     CALL TSRT$ USING TS SIZES          -- a sort()
>     PERFORM DA-FIND-COMBINATION
>     ON NO EXCEPTION                    -- eg "EXIT 1" gives exception;
> 	DO                             --  (In Eu just use a flag)
> 	MOVE WORK-TOT TO BA-TOT
> 	MOVE LEVEL TO BA-LEVEL
> 	PERFORM BA-DISPLAY
> 	PERFORM DA200
> 	ON EXCEPTION FINISH
> 	ENDDO
>     END
>     MOVE LOWSET TO INCSET
>     MOVE LOW-LEVEL TO BA-LEVEL
>     MOVE LOW-BEST TO BA-TOT
>     DISPLAY "Lower figure"
>     PERFORM BA-DISPLAY
>     MOVE HIGHSET TO INCSET
>     MOVE HIGH-LEVEL TO BA-LEVEL
>     MOVE HIGH-BEST TO BA-TOT
>     DISPLAY "Higher figure"
>     PERFORM BA-DISPLAY
> EXIT
>  
> SECTION BA-DISPLAY
>     DISPLAY BA-TOT
>     DO FOR BA-IDX = 1 TO BA-LEVEL
> 	MOVE 0 TO BA-ITEM
> 	MOVE INCLUDE(BA-IDX) TO BA-ITB2       -- uses () for subscripts!
> 	DISPLAY BA-ITEM
> 	DISPLAY "  " SAMELINE
> 	DISPLAY SIZE(BA-ITEM) SAMELINE
>     ENDDO
>     DISPLAY "       Key <CR>"
>     SVC 6 USING 1                   -- wait_key()
>     ON EXCEPTION
>     END
> EXIT
>  
> SECTION DA-FIND-COMBINATION
> *
> * This section tries to find a set of sizes which add up to the
> * required amount exactly.
> *
>     MOVE 1 TO LEVEL
>     MOVE 0 TO LOW-BEST
>     MOVE 999999999 TO HIGH-BEST
>     MOVE LIMIT TO ITEM
> DA100.
>     MOVE ITB2 TO INCLUDE(LEVEL)
> *
> * Add size(item) to work-tot
> *
>     $LOAD SIZE(ITEM)     -- you can follow this, I trust. acc = size[item].
>     $ADDS WORK-TOT                               --  work_tot+=acc
>     $SUB REQUIRED                    -- acc = size[item]+work_tot-required
>     $EXIT EQ		* Found exact fit
>     $JUMP GT DA200	    * Too big
> *
> * This set is smaller than required - save it if it is best so far
> *
>     IF WORK-TOT > LOW-BEST
> 	$ADDS LOW-BEST
> 	MOVE LEVEL TO LOW-LEVEL
> 	MOVE INCSET TO LOWSET
>     END
>     IF ITEM > 1 	* More to be tested
> 	$STORE ITEM
> 	ADD 1 TO LEVEL	    * Leave item in table;
> 	GOTO DA100
> DA200.
> *
> * This set is larger than required - save it if it is best so far
> *
> 	IF WORK-TOT < HIGH-BEST
> 	$ADDS HIGH-BEST
> 	MOVE LEVEL TO HIGH-LEVEL
> 	MOVE INCSET TO HIGHSET
> 	END
>     END
> DA300.
> *
> * Now we need to backtrack;  remove item from running total and look
> * at the next instead.
> *
> * Subtract size(item) from work-tot
> *
>     $LOAD 0
>     $SUB SIZE(ITEM)
>     $ADDS WORK-TOT
>     IF ITEM > 1 	* More to be tested
> 	$STORE ITEM	* Look at next (overwrite item in table)
> 	GOTO DA100
>     END
> *
> * We have exhausted all possibilities at this level; backtrack to
> * a previous level.
> *
>     MOVE #00 TO INCLUDE(LEVEL)
>     ADD -1 TO LEVEL
>     $EXIT EQ 1		* All done
>     MOVE 0 TO ITEM
>     MOVE INCLUDE(LEVEL) TO ITB2
>     GOTO DA300
>  
> ENDPROG
> 
> I found it quite a challenge to get that working in Eu.

Sorry, I do not know anything about COBOL.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

13. Re: Goto (Was Re: Open Source)

Me wrote:

> Pete Lomax wrote:
> 
> > Juergen Luethje wrote:
> > > 
> > > This whole discussion is not logical for me. Someone asks for intrducing
> > > GOTO into Euphoria, and other people make suggestions how to limit the
> > > damage then.
> > > The first question should be: Why does someone want GOTO, and exactly
> > > _for what purposes_? I'm pretty sure then we can find more appropriate
> > > constructs for the desired purposes -- high level constructs for the
> > > high level language Euphoria.
> > > 
> > Since you ask, I would say to translate a working program written in another
> > language to Eu.
> 
> This is a concrete reason which provides a solid basis for discussing, thanks.
> 
> > As I recently said, I am not advocating goto, just not standing
> > against it. Here is one case you probably already saw:
> > 
> > int parse()
> > {
> >     Token   tok;
> > 
> > reading:
> >     tok = gettoken();
> >     if (tok == END)
> >         return ACCEPT;
> > shifting:
> >     if (shift(tok))
> >         goto reading;
> > reducing:
> >     if (reduce(tok))
> >         goto shifting;
> >     return ERROR;
> > }
> 
> If I didn't make a mistake, this translates to the following Eu program:
> }}}
<eucode>
> procedure foo ()
>    Token tok
>    
>    while 1 do
>       -- reading
>       tok = gettoken()
>       if tok = END then
>          return ACCEPT
>       end if
>       
>       while 1 do
>          -- shifting
>          if shift(tok) then
>             exit
>          end if
>          -- reducing
>          if not reduce(tok) then
>             return ERROR
>          end if
>       end while
>    end while
> end procedure
> </eucode>
{{{


Must of course be 'function', not 'procedure'.

I actually would prefer to write the code this way:
function foo ()
   Token tok
   
   tok = gettoken()
   while tok != END do
      while not shift(tok) do
         if not reduce(tok) then
            return ERROR
         end if
      end while
      tok = gettoken()
   end while
   return ACCEPT
end function


Now this is short and pretty clear. Without using GOTO, the structure of
the program (2 nested loops) is directly visible. So the "nature" of the
program can be understood immediately and intuitively.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

14. Re: Goto (Was Re: Open Source)

Juergen Luethje wrote:
> > If I didn't make a mistake, this translates to the following Eu program:
<snip>
> I actually would prefer to write the code this way:
<snip>
> Now this is short and pretty clear. Without using GOTO, the structure of
> the program (2 nested loops) is directly visible. So the "nature" of the
> program can be understood immediately and intuitively.
No arguments here, but you did need two attempts even on such a trivial piece of
code smile

> Sorry, I do not know anything about COBOL.
Try this then:
-- optimised best-fit algorithm
include sort.e

integer required
	required = 2482
-- expected results with first sizes set:
--Exact 2482:  12 505, 10 425, 7 396, 6 391, 5 388, 1 377
-- expected results with second sizes set:
--Lower 2324: 6 798, 5 734, 3 410, 2 382
--Higher 2520: 5 734, 4 650, 3 410, 2 382, 1 344
	required = 1659
-- expected results with first sizes set:
--Exact 1659: 11 488, 7 396, 6 391, 3 384
-- expected results with second sizes set:
--Lower 1590: 6 798, 3 410, 2 382
--Higher 1728: 5 734, 4 650, 1 344

sequence sizes
--	 sizes = {377,378,384,387,388,391,396,422,424,425,488,505}
	 sizes = {798,344,650,410,382,734}

sequence incset

integer lowbest, lowlevel, highbest, highlevel, worktot, level, item
sequence lowset, highset

procedure display(integer tot, integer level, sequence incset)
integer item
    printf(1,"%d ",tot)
    for i = 1 to level do
	item = incset[i]
	printf(1,"%d %d ",{item,sizes[item]})
    end for
    puts(1,"       key <cr>")
    if getc(0) then end if
    puts(1,"\n")
end procedure
 
function find_combination(integer jumpToDa200)
--
-- this section tries to find a set of sizes which add up to the
-- required amount exactly.
--
    if jumpToDa200 then goto da200 end if
    level = 1
    lowbest = 0
    highbest = 999999999
    item = length(sizes)
    incset=repeat(0,item)
    worktot=0
da100::
    incset[level] = item
    worktot += sizes[item]
    if worktot = required then return 0 end if	      -- found exact fit
    if worktot > required then goto da200 end if	    -- too big
--
-- this set is smaller than required - save it if it is best so far
--
    if worktot > lowbest then
	lowbest = worktot
	lowlevel = level
	lowset = incset
    end if
    if item > 1 then	    -- more to be tested
	item -= 1
	level += 1	    -- leave item in table;
	goto da100
    end if
    goto da300
da200::
--
-- this set is larger than required - save it if it is best so far
--
    if worktot < highbest then
	highbest = worktot
	highlevel = level
	highset = incset
    end if
da300::
--
-- now we need to backtrack;  remove item from running total and look
-- at the next instead.
--
    worktot -= sizes[item]
    if item > 1 then	-- more to be tested
	item -= 1	-- look at next (overwrite item in table)
	goto da100
    end if
--
-- we have exhausted all possibilities at this level; backtrack to
-- a previous level.
--
    incset[level] = 0
    level -= 1
    if level = 0 then return 1 end if		-- all done
    item = incset[level]
    goto da300
 
end function

procedure main()
    sizes=sort(sizes)
    if not find_combination(0) then
	while 1 do
	    display(worktot,level,incset)
--	    if da200() then exit end if
	    if find_combination(1) then exit end if
	end while
    end if
    puts(1,"lower figure ")
    display(lowbest,lowlevel,lowset)
    puts(1,"higher figure ")
    display(highbest,highlevel,highset)
end procedure
main()


I wasn't really keeping track but I think it just took me a shade under an hour
to hack that into something working, then again I know how it works and I've
managed that trick once before, and that I tried and failed many moons ago when I
was still an Eu novice. While messing about I trigered two fatal crashes in Edita
(in re-indent and CtrlBracket) which I fixed (as part of that hour), so at least
it was not a complete and utter waste of time smile

One thing I would like to say is that the original of that code was used as part
of the compilation process in a team of ten programmers for many years, so any
restructuring or rewrite would, I felt, carry a strong chance of (re-)introducing
bugs that had been ironed out long ago. OTOH if you translate some code from
language A to language B then a) that is a big enough upheaval anyway, and b) if
you don't test it thoroughly then you know what to expect.

The point that this is the only real nasty I have encountered in 5+ years with
Eu is not a small point either.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

15. Re: Goto (Was Re: Open Source)

Pete Lomax wrote:

> Juergen Luethje wrote:
> > > If I didn't make a mistake, this translates to the following Eu program:
> <snip>
> > I actually would prefer to write the code this way:
> <snip>
> > Now this is short and pretty clear. Without using GOTO, the structure of
> > the program (2 nested loops) is directly visible. So the "nature" of the
> > program can be understood immediately and intuitively.
> No arguments here, but you did need two attempts even on such a trivial piece
> of code smile

I probably better shouldn't do things like that before breakfast. smile

> > Sorry, I do not know anything about COBOL.
> Try this then:
> 
> -- optimised best-fit algorithm
> include sort.e
> 
> integer required
>   required = 2482
> -- expected results with first sizes set:
> --Exact 2482:  12 505, 10 425, 7 396, 6 391, 5 388, 1 377
> -- expected results with second sizes set:
> --Lower 2324: 6 798, 5 734, 3 410, 2 382
> --Higher 2520: 5 734, 4 650, 3 410, 2 382, 1 344
>   required = 1659
> -- expected results with first sizes set:
> --Exact 1659: 11 488, 7 396, 6 391, 3 384
> -- expected results with second sizes set:
> --Lower 1590: 6 798, 3 410, 2 382
> --Higher 1728: 5 734, 4 650, 1 344
> 
> sequence sizes
> --         sizes = {377,378,384,387,388,391,396,422,424,425,488,505}
>    sizes = {798,344,650,410,382,734}
> 
> sequence incset
> 
> integer lowbest, lowlevel, highbest, highlevel, worktot, level, item
> sequence lowset, highset
> 
> procedure display(integer tot, integer level, sequence incset)
> integer item
>     printf(1,"%d ",tot)
>     for i = 1 to level do
>   item = incset[i]
>   printf(1,"%d %d ",{item,sizes[item]})
>     end for
>     puts(1,"       key <cr>")
>     if getc(0) then end if
>     puts(1,"\n")
> end procedure
>  
> function find_combination(integer jumpToDa200)
> --
> -- this section tries to find a set of sizes which add up to the
> -- required amount exactly.
> --
>     if jumpToDa200 then goto da200 end if
>     level = 1
>     lowbest = 0
>     highbest = 999999999
>     item = length(sizes)
>     incset=repeat(0,item)
>     worktot=0
> da100::
>     incset[level] = item
>     worktot += sizes[item]
>     if worktot = required then return 0 end if              -- found exact fit
>     if worktot > required then goto da200 end if       -- too big
> --
> -- this set is smaller than required - save it if it is best so far
> --
>     if worktot > lowbest then
>   lowbest = worktot
>   lowlevel = level
>   lowset = incset
>     end if
>     if item > 1 then     -- more to be tested
>   item -= 1
>   level += 1          -- leave item in table;
>   goto da100
>     end if
>     goto da300
> da200::
> --
> -- this set is larger than required - save it if it is best so far
> --
>     if worktot < highbest then
>   highbest = worktot
>   highlevel = level
>   highset = incset
>     end if
> da300::
> --
> -- now we need to backtrack;  remove item from running total and look
> -- at the next instead.
> --
>     worktot -= sizes[item]
>     if item > 1 then -- more to be tested
>   item -= 1       -- look at next (overwrite item in table)
>   goto da100
>     end if
> --
> -- we have exhausted all possibilities at this level; backtrack to
> -- a previous level.
> --
>     incset[level] = 0
>     level -= 1
>     if level = 0 then return 1 end if         -- all done
>     item = incset[level]
>     goto da300
>  
> end function
> 
> procedure main()
>     sizes=sort(sizes)
>     if not find_combination(0) then
>   while 1 do
>       display(worktot,level,incset)
> --            if da200() then exit end if
>       if find_combination(1) then exit end if
>   end while
>     end if
>     puts(1,"lower figure ")
>     display(lowbest,lowlevel,lowset)
>     puts(1,"higher figure ")
>     display(highbest,highlevel,highset)
> end procedure
> main()

There are only GOTOs in one routine, and this is my translated code
(untested):
function find_combination(integer jumpToDa200)
   --
   -- this section tries to find a set of sizes which add up to the
   -- required amount exactly.
   --
   if not jumpToDa200 then
      level = 1
      lowbest = 0
      highbest = 999999999
      item = length(sizes)
      incset=repeat(0,item)
      worktot=0
   end if

   while 1 do
      flag = FALSE
      if not jumpToDa200 then
         while 1 do
            incset[level] = item
            worktot += sizes[item]
            if worktot = required then
               return 0
            end if              -- found exact fit
            if worktot > required then
               flag = TRUE
               exit
            end if       -- too big
            --
            -- this set is smaller than required - save it if it is best so far
            --
            if worktot > lowbest then
               lowbest = worktot
               lowlevel = level
               lowset = incset
            end if
            if item <= 1 then
               exit
            end if
            -- more to be tested
            item -= 1
            level += 1          -- leave item in table;
         end while
      end if

      if jumpToDa200 or flag = TRUE then
         --
         -- this set is larger than required - save it if it is best so far
         --
         if worktot < highbest then
            highbest = worktot
            highlevel = level
            highset = incset
         end if
      end if

      while 1 do
         --
         -- now we need to backtrack;  remove item from running total and look
         -- at the next instead.
         --
         worktot -= sizes[item]
         if item > 1 then    -- more to be tested
            item -= 1        -- look at next (overwrite item in table)
            exit
         end if
         --
         -- we have exhausted all possibilities at this level; backtrack to
         -- a previous level.
         --
         incset[level] = 0
         level -= 1
         if level = 0 then
            return 1
         end if         -- all done
         item = incset[level]
      end while
   end while      
end function


> I wasn't really keeping track but I think it just took me a shade under an
> hour to hack
> that into something working, then again I know how it works and I've managed
> that trick
> once before, and that I tried and failed many moons ago when I was still an Eu
> novice.
> While messing about I trigered two fatal crashes in Edita (in re-indent and
> CtrlBracket)
> which I fixed (as part of that hour), so at least it was not a complete and
> utter waste
> of time smile
> 
> One thing I would like to say is that the original of that code was used as
> part of the compilation process in a team of ten programmers for many years,
> so any restructuring or rewrite would, I felt, carry a strong chance of
> (re-)introducing
> bugs that had been ironed out long ago.

I agree.

> OTOH if you translate some code from
> language A to language B then a) that is a big enough upheaval anyway, and b)
> if you don't test it thoroughly then you know what to expect.

I agree. However, proper testing sometimes is not so easy.
I mean a situation when you have copied e.g. some COBOL code from a
website (and you can understand COBOL code), but you don't have a COBOL
interpreter or compiler available on your system. Then you can test your
translated Eu program, but you can't test the original program, and so
you can't compare the behaviour of both versions of the programm.

Especially in such a situation it's good when you can translate as much
as possible (at least in the beginning of the translation) just by using
'search and replace', e.g. when translating a BASIC programm:
- replace "ElseIf" with "elsif"
- replace "Wend" with "end while"
- replace "Next" with "end for"
- etc.

The more similar Euphoria is to the language in which the source code is
written, the more parts of the code can be translated in such a safe
"mechanical" way. So if the source code contains GOTO, I agree that
translation especially of complex code might be safer when Euohoria
had a GOTO statement, too.

> The point that this is the only real nasty I have encountered in 5+ years with
> Eu is not a small point either.

I also only remember 1 time, when I had severe problems with translating
code to Euphoria that contained GOTO. My first goal was to create a
running Eu programm, by changing as few as possible in the code. So I
created code for Matt's OOEU, which does support GOTO. Then I removed
the GOTOs step by step and so in the end I had a program for the
standard Eu interpreter.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

16. Re: Goto (Was Re: Open Source)

Juergen Luethje wrote:
> 
> this is my translated code (untested):

Your code worked perfectly on the second test set, and gave initially correct
answers on the first set, before yielding negative highvalues...

I toyed with the idea of challenging you to find the bug smile

The mistake you made is this:
> Pete Lomax wrote:
> > Try this then:
> > function find_combination(integer jumpToDa200)
> >     if jumpToDa200 then goto da200 end if
> > da200::
you translated this as:
> }}}
<eucode>
> function find_combination(integer jumpToDa200)
>    if not jumpToDa200 then
>    end if
>    while 1 do
>       if not jumpToDa200 then
>       end if
>       if jumpToDa200 or flag = TRUE then
<da200:: was here>
>       end if
>    end while      
> </eucode>
{{{

The original jumped to da200 from the top of the routine, whereas you test the
parameter again on every iteration around the loop. Clearing the flag at the
point where the label used to be fixes it.

From the number of tests it passed despite this flaw, I feel lucky to have
 spotted it at all.

> I created code for Matt's OOEU, which does support GOTO. Then I removed
> the GOTOs step by step and so in the end I had a program for the
> standard Eu interpreter.
Not really the answer though, installing two different interpreters, is it?

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

17. Re: Goto (Was Re: Open Source)

Pete Lomax wrote:

> Juergen Luethje wrote:
> > 
> > this is my translated code (untested):
> 
> Your code worked perfectly on the second test set, and gave initially correct
> answers on the first set, before yielding negative highvalues...
> 
> I toyed with the idea of challenging you to find the bug smile
> 
> The mistake you made is this:
> > Pete Lomax wrote:
> > > Try this then:
> > > function find_combination(integer jumpToDa200)
> > >     if jumpToDa200 then goto da200 end if
> > > da200::
> you translated this as:
> > 
> > function find_combination(integer jumpToDa200)
> >    if not jumpToDa200 then
> >    end if
> >    while 1 do
> >       if not jumpToDa200 then
> >       end if
> >       if jumpToDa200 or flag = TRUE then
> <da200:: was here>
> >       end if
> >    end while      
> > 
> The original jumped to da200 from the top of the routine, whereas you test the
> parameter again on every iteration around the loop. Clearing the flag at the
> point where the label used to be fixes it.

I see.

>  From the number of tests it passed despite this flaw, I feel lucky to have
> spotted it at all.
> 
> > I created code for Matt's OOEU, which does support GOTO. Then I removed
> > the GOTOs step by step and so in the end I had a program for the
> > standard Eu interpreter.
> Not really the answer though, installing two different interpreters, is it?

Up to now, I have encountered this special problem only once. Since I
registered Euphoria in April 2002, this means only once in 5+ years --
pretty much the same what you wrote. And in this rare situation I used
an appropriate tool to solve the special problem. That was/is fine with
me.
What is the answer in your opinion?

Regards,
   Juergen


PS: IMHO it would be very cool if there were a kind of pre-processor,
that could automagically translate GOTOs into more structured code.
This would be a nice challenge for you and other "senior programmers",
no? smile
(I am curious whether this is actually possible from a theoretical point
of view.)

new topic     » goto parent     » topic index » view message » categorize

18. Re: Goto (Was Re: Open Source)

Juergen Luethje wrote:
> 
> Pete Lomax wrote:
> 
> > Juergen Luethje wrote:
> > > 
> > > this is my translated code (untested):
> > 
> > Your code worked perfectly on the second test set, and gave initially
> > correct
> > answers on the first set, before yielding negative highvalues...
> > 
> > I toyed with the idea of challenging you to find the bug smile
> > 
> > The mistake you made is this:
> > > Pete Lomax wrote:
> > > > Try this then:
> > > > function find_combination(integer jumpToDa200)
> > > >     if jumpToDa200 then goto da200 end if
> > > > da200::
> > you translated this as:
> > > 
> > > function find_combination(integer jumpToDa200)
> > >    if not jumpToDa200 then
> > >    end if
> > >    while 1 do
> > >       if not jumpToDa200 then
> > >       end if
> > >       if jumpToDa200 or flag = TRUE then
> > <da200:: was here>
> > >       end if
> > >    end while      
> > > 
> > The original jumped to da200 from the top of the routine, whereas you test
> > the
> > parameter again on every iteration around the loop. Clearing the flag at the
> > point where the label used to be fixes it.
> 
> I see.
> 
> >  From the number of tests it passed despite this flaw, I feel lucky to have
> > spotted it at all.
> > 
> > > I created code for Matt's OOEU, which does support GOTO. Then I removed
> > > the GOTOs step by step and so in the end I had a program for the
> > > standard Eu interpreter.
> > Not really the answer though, installing two different interpreters, is it?
> 
> Up to now, I have encountered this special problem only once. Since I
> registered Euphoria in April 2002, this means only once in 5+ years --
> pretty much the same what you wrote. And in this rare situation I used
> an appropriate tool to solve the special problem. That was/is fine with
> me.
> What is the answer in your opinion?
> 
> Regards,
>    Juergen
> 
> 
> PS: IMHO it would be very cool if there were a kind of pre-processor,
> that could automagically translate GOTOs into more structured code.
> This would be a nice challenge for you and other "senior programmers",
> no? smile
> (I am curious whether this is actually possible from a theoretical point
> of view.)

It is, but might be pretty inefficient.
I'm assuming goto-ing inside a for loop is not permitted - otherwise extra steps
are needed to re-initialise loop variables and reenter a for loop.

So the point is to jump from inside a few while and if blocks to another point,
also inside a few while and if blocks. So, the problems breas up into:
1/ exiting nested if/while blocks, so as to be in a block containing the target;
2a/ inside this block, jumping forward to start of block containing target;
2b/ jumping to start of block, so as to apply 2a;
2c/ inside this block, jumping backward to start of block containing target;
3/ moving into a while loop;
4a/ moving inside an if block
4b/ moving inside an elsif block
4c/ moving inside an else block

For each goto statement in program, create a flag (I'll call it goto_flag_154),
which will be zero except while the sequence of statements translating the given
goto is being executed. So, at the location of the original goto statement,
you'll have goto_flag_154=1, and on its target goto_flag_154=0.
Also, for each etra while loop created during the process, create a flag called
exit_flag_197.

1a/ to break out of a while loop, use
if goto_flag_154 then exit end if

1b/ to break out of an if statement:
- wrap it inside 
while 1 do...if not goto_flag_154 then exit end if end while

- if there's any exit statement inside that section then
* precede each by }}}
<eucode>exit_flag_197=1}}}
<eucode>
* add after the above end while statement
if exit_flag_197 then exit_flag_197=0 exit end if

- goto 1a/

2a/ move forward inside a while loop using
if not goto_flag_154 then...end if

2b+c/: if inside an if block, exit it first using 1b/ and then 4/
       if inside a while loop, wrap origin and destination into
while 1 do ... if not goto_flag_154 then exit end if end while

and modify in case any exit statement is trapped, as in 1b/

3/ prepend }}}
<eucode>goto_flag_154 or</eucode>
{{{
 to the header of the while loop

4a/ same as 3/
4b/ prepend to the conditional of the main if and all skipped elsif clauses
not goto_flag_154 and

. Use 3/ on the elsif clause you want to
reach into.
4c/ use 4b/ on all if/elsif clauses.

As you have certainly figured out, the preprocessor must remember where evry
block starts and ends, together with its type, and update that data whenever code
is being modified, including as part of the above. Also, you must find a variable
name for goto_flag_154 and exit_flag_197 that will not conflict with any
subsequently declared global symbol.
Implementing inside the interpreter is _way_ simpler. I tried both. 
I didn't release the preprocessor (idEu) because debugging with a 300 line limit
was so much of a hell, at the time. The update proess which I mentioned above was
not working properly.

CChris

new topic     » goto parent     » topic index » view message » categorize

19. Re: Goto (Was Re: Open Source)

Juergen Luethje wrote:
> 
> Me wrote:
> 
> > Pete Lomax wrote:
> > 
> > > Juergen Luethje wrote:
> > > > 
> > > > This whole discussion is not logical for me. Someone asks for intrducing
> > > > GOTO into Euphoria, and other people make suggestions how to limit the
> > > > damage then.
> > > > The first question should be: Why does someone want GOTO, and exactly
> > > > _for what purposes_? I'm pretty sure then we can find more appropriate
> > > > constructs for the desired purposes -- high level constructs for the
> > > > high level language Euphoria.
> > > > 
> > > Since you ask, I would say to translate a working program written in
> > > another
> > > language to Eu.
> > 
> > This is a concrete reason which provides a solid basis for discussing,
> > thanks.
> > 
> > > As I recently said, I am not advocating goto, just not standing
> > > against it. Here is one case you probably already saw:
> > > 
> > > int parse()
> > > {
> > >     Token   tok;
> > > 
> > > reading:
> > >     tok = gettoken();
> > >     if (tok == END)
> > >         return ACCEPT;
> > > shifting:
> > >     if (shift(tok))
> > >         goto reading;
> > > reducing:
> > >     if (reduce(tok))
> > >         goto shifting;
> > >     return ERROR;
> > > }
> > 
> > If I didn't make a mistake, this translates to the following Eu program:
> > }}}
<eucode>
> > procedure foo ()
> >    Token tok
> >    
> >    while 1 do
> >       -- reading
> >       tok = gettoken()
> >       if tok = END then
> >          return ACCEPT
> >       end if
> >       
> >       while 1 do
> >          -- shifting
> >          if shift(tok) then
> >             exit
> >          end if
> >          -- reducing
> >          if not reduce(tok) then
> >             return ERROR
> >          end if
> >       end while
> >    end while
> > end procedure
> > </eucode>
{{{

> 
> Must of course be 'function', not 'procedure'.
> 
> I actually would prefer to write the code this way:
> }}}
<eucode>
> function foo ()
>    Token tok
>    
>    tok = gettoken()
>    while tok != END do
>       while not shift(tok) do
>          if not reduce(tok) then
>             return ERROR
>          end if
>       end while
>       tok = gettoken()
>    end while
>    return ACCEPT
> end function
> </eucode>
{{{

> 
> Now this is short and pretty clear. Without using GOTO, the structure of
> the program (2 nested loops) is directly visible. So the "nature" of the
> program can be understood immediately and intuitively.


Not me. 
So i can assume you'll go with this construct and we'll never get a goto.

Kat
 
> Regards,
>    Juergen

new topic     » goto parent     » topic index » view message » categorize

20. Re: Goto (Was Re: Open Source)

Kat wrote:
> 
> Juergen Luethje wrote:
> > 
> > Me wrote:
> > 
> > > Pete Lomax wrote:
> > > 
> > > > Juergen Luethje wrote:
> > > > > 
> > > > > This whole discussion is not logical for me. Someone asks for
> > > > > intrducing
> > > > > GOTO into Euphoria, and other people make suggestions how to limit the
> > > > > damage then.
> > > > > The first question should be: Why does someone want GOTO, and exactly
> > > > > _for what purposes_? I'm pretty sure then we can find more appropriate
> > > > > constructs for the desired purposes -- high level constructs for the
> > > > > high level language Euphoria.
> > > > > 
> > > > Since you ask, I would say to translate a working program written in
> > > > another
> > > > language to Eu.
> > > 
> > > This is a concrete reason which provides a solid basis for discussing,
> > > thanks.
> > > 
> > > > As I recently said, I am not advocating goto, just not standing
> > > > against it. Here is one case you probably already saw:
> > > > 
> > > > int parse()
> > > > {
> > > >     Token   tok;
> > > > 
> > > > reading:
> > > >     tok = gettoken();
> > > >     if (tok == END)
> > > >         return ACCEPT;
> > > > shifting:
> > > >     if (shift(tok))
> > > >         goto reading;
> > > > reducing:
> > > >     if (reduce(tok))
> > > >         goto shifting;
> > > >     return ERROR;
> > > > }
> > > 
> > > If I didn't make a mistake, this translates to the following Eu program:
> > > }}}
<eucode>
> > > procedure foo ()
> > >    Token tok
> > >    
> > >    while 1 do
> > >       -- reading
> > >       tok = gettoken()
> > >       if tok = END then
> > >          return ACCEPT
> > >       end if
> > >       
> > >       while 1 do
> > >          -- shifting
> > >          if shift(tok) then
> > >             exit
> > >          end if
> > >          -- reducing
> > >          if not reduce(tok) then
> > >             return ERROR
> > >          end if
> > >       end while
> > >    end while
> > > end procedure
> > > </eucode>
{{{

> > 
> > Must of course be 'function', not 'procedure'.
> > 
> > I actually would prefer to write the code this way:
> > }}}
<eucode>
> > function foo ()
> >    Token tok
> >    
> >    tok = gettoken()
> >    while tok != END do
> >       while not shift(tok) do
> >          if not reduce(tok) then
> >             return ERROR
> >          end if
> >       end while
> >       tok = gettoken()
> >    end while
> >    return ACCEPT
> > end function
> > </eucode>
{{{

> > 
> > Now this is short and pretty clear. Without using GOTO, the structure of
> > the program (2 nested loops) is directly visible. So the "nature" of the
> > program can be understood immediately and intuitively.
> 
> 
> Not me. 
> So i can assume you'll go with this construct and we'll never get a goto.
> 
> Kat
>  
> > Regards,
> >    Juergen

Simple examples like this always convert nicely. "hello world" programs almost
always look simple in any language. Then real programming comes in and makes a
difference.

Compiler writers will tell you that they need programs to be written using high
level constructs, because this makes verifying code correctness simply possible.
And a vast class of problems indeed doesn't need goto, so you'll see plenty of
examples taken from that area which "prove" that you can do without goto in even
very complicated algorithms - but well chosen -.
They have an extra point in that less many random branch instructions allow
optimising CPU register use, since some repeated assignments can be dealt with by
using the right register once and moving the now invariant instruction out of a
loop, for greater efficiency.

Additionally, it is true that, in theory, you can almost always do without goto
indeed. The cases you cannot are too close to machine level tweaking to be
handled by anything else than assembly language. This powerful argument is also
used to discourage using goto, since - ALLEGEDLY - too many people use it in
cases a high level construct would do as well, or even better, leading straight
to the lair of the dreaded Spaghetti Ness monster.

Personally, I have hardly ever seen such code. Perhaps because it's a Basic
specific disease and I hardly ever looked at Basic code except for ripping
constants out of them. While I can understand that students may be tempted to use
goto and not learn the necessarily more complex higher level syntax. this
argument loses its value past the classroom door. This spaghetti thing is really
crying for a wolf who is no longer there. And as I said, bad/hard to maintain
code hardly survives anyway, so why care?

Many - certainly not all - programming problems use a finite automaton model and
logic. Such problems are described by a list of:
    if state is this, then do that and change to that state.
transition rules. goto is the natural thing to use then. When things start being
a little complex, translating to loops is hazardous, and you wind up with a ton
of flags which have to be kept in sync. This is a thriving nest of bugs, and
usually not easy to hit.
For this kind of programming task, using goto will avoid a lot of bugs because
there won't be a huge distorsion between the coder's view of the problem and the
code itself. Some code optimisations will be lost. The resulting program will
have a more convoluted flow, but obfuscating further by loops that have no
equivalent in the task description doesn't make it any easier to understand. In
that framework, code using goto will be actually easier to maintain.

As I said in earlier posts, I usually need goto mostly to exit loops and if
blocks. goto inside a select ... case statement would be useful too - after all,
that's how the Eu VM works. I'd consider it more as a useful development tool,
while its use in released code should be kept to a minimum, or to zero with the
addition of more flow control structures/instructions than we currently have.

CChris

new topic     » goto parent     » topic index » view message » categorize

21. Re: Goto (Was Re: Open Source)

CChris wrote:

> Simple examples like this always convert nicely. "hello world" programs almost
> always look simple in any language. Then real programming comes in and makes
> a difference.
>
> etc...
> 
> CChris

Well said CChris.
I'm a firm beleiver that development speed and corelation between
design and code are paramount traits of a quality programming language.

While I do not advocate the use of goto, debating it's validity based on 
'poor programming habit' is an extremely moot point. Good programmers will write
good code
and bad programmers will write bad code, regardless of what tools are available
to them.
I see no reason why it is any of my business if someone else chooses to use it.
I still have the choice if I want to use their code or not.
For the end-user, it's pretty much irrelevant what language is used to
create a program, nevermind what constructs are used in the underlying code.

The issue of goto is more of a debate on coding style than anything to do with
practical programming. In my mind it equates to the same argument as code
formatting.

I do think that the use of goto should be discouraged, but it is not my place to
dictate
how others should write their code.

The real issue is 'does goto belong in Euphoria?'

My thoughts are that we should address the desire for arbitrary jumps as much as
possible
with high level constructs first, before we consider the addition of goto.
I don't feel that goto really fits into the Euphoria language.

In a nutshell, I beleive implementing goto before we explore more appropriate,
higher level constructs, is putting the cart before the horse.


Chris Bensler
Code is Alchemy

new topic     » goto parent     » topic index » view message » categorize

22. Re: Goto (Was Re: Open Source)

Chris Bensler wrote:
> 
> CChris wrote:
> 
> > Simple examples like this always convert nicely. "hello world" programs
> > almost
> > always look simple in any language. Then real programming comes in and makes
> > a difference.
> >
> > etc...
> > 
> > CChris
> 
> Well said CChris.
> I'm a firm beleiver that development speed and corelation between
> design and code are paramount traits of a quality programming language.
> 
> While I do not advocate the use of goto, debating it's validity based on 
> 'poor programming habit' is an extremely moot point. Good programmers will
> write
> good code
> and bad programmers will write bad code, regardless of what tools are
> available
> to them.
> I see no reason why it is any of my business if someone else chooses to use
> it.
> I still have the choice if I want to use their code or not.
> For the end-user, it's pretty much irrelevant what language is used to
> create a program, nevermind what constructs are used in the underlying code.
> 
> The issue of goto is more of a debate on coding style than anything to do with
> practical programming. In my mind it equates to the same argument as code
> formatting.
> 
> I do think that the use of goto should be discouraged, but it is not my place
> to dictate
> how others should write their code.
> 
> The real issue is 'does goto belong in Euphoria?'
> 
> My thoughts are that we should address the desire for arbitrary jumps as much
> as possible
> with high level constructs first, before we consider the addition of goto.
> I don't feel that goto really fits into the Euphoria language.
> 
> In a nutshell, I beleive implementing goto before we explore more appropriate,
> higher level constructs, is putting the cart before the horse.
> 
> 
> Chris Bensler
> Code is Alchemy

I'll try submitting shortly a set of Eu front end files that add a number of
imho needed enhancements to the language. The additions are:
* forward routine calls allowed, using
forward function f(integer z)
n=f(3)
--- some code here
function f
-- usual routine body here

* new scope keyword, to declare variables local to part of a routine/top level
code, possibly shadowing existing symbols;
* nested routines are now supported. For consistency reasons, you can call only
a routine which is a direct descendant of any ancestor of te current routine.
* new loop
loop do
-- some code
until some_condition
end loop

* exif exits an if block;
* inside a oop, next skips the rest of the current iteration and performs any
code prepring the next;
* retry jumps to top of loop, without executing the code that prepares next
iteration;
* all loops can have a label attached to it, like this
for i=1 to n by 2 label "my string" do

* exif/exit/next/retry now have an optional parameter, either
+ a nuber of loop above current one (1 = loop above, 2=loop above the
latter,...)
+ a negative number, to count loop levels backward (-1 = topmost loop, -2 = all
but topmist,...)
+ a string, which must have been defined as a label prior;
+ the name of a for loop index.
* defaulted routine parameters, with ability to default any parameter, not only
the last one(s)

The only mod to backend would be to update be_syncolor.c so that the trace
screen displays the new keywords as such.

I'll submit this to user contributions spùewhere in november. If I ever write
some new code in Eu, I'll probably use and require that new interpreter. I'll
attempt to also implement pass by reference, but this may or may not work. An
earlier implementation I had just does no longer work with multitasking.

CChris

new topic     » goto parent     » topic index » view message » categorize

23. Re: Goto (Was Re: Open Source)

CChris wrote:
> 
> loop do
> -- some code
> until some_condition
> end loop

The "end loop" is redundant, isn't it?

new topic     » goto parent     » topic index » view message » categorize

24. Re: Goto (Was Re: Open Source)

CChris wrote:
> 
> I'll try submitting shortly a set of Eu front end files that add a number of
> imho needed enhancements to the language. The additions are:
> * forward routine calls allowed, using
> }}}
<eucode>
> forward function f(integer z)
> n=f(3)
> --- some code here
> function f
> -- usual routine body here
> </eucode>
{{{


Is prototyping the way to go?
For functional purposes, it's not needed, afaik. It's purely for distinction,
correct?
Would it not be better to have some syntax that is used specifically for each
call to a forward reference?
Such as:
  n = ~f(3)

.. which makes it directly clear what is intended at the point it is used,
rather than the point at which it is defined.

> * new scope keyword, to declare variables local to part of a routine/top level
> code, possibly shadowing existing symbols;
> * nested routines are now supported. For consistency reasons, you can call
> only
> a routine which is a direct descendant of any ancestor of te current routine.
> * new loop
> }}}
<eucode>
> loop do
> -- some code
> until some_condition
> end loop
> </eucode>
{{{


> * exif exits an if block;

Can you give an example of how this would be used?

> * inside a oop, next skips the rest of the current iteration and performs any
> code prepring the next;
> * retry jumps to top of loop, without executing the code that prepares next
> iteration;
> * all loops can have a label attached to it, like this
> }}}
<eucode>
> for i=1 to n by 2 label "my string" do
> </eucode>
{{{

> * exif/exit/next/retry now have an optional parameter, either
> + a nuber of loop above current one (1 = loop above, 2=loop above the
> latter,...)
> + a negative number, to count loop levels backward (-1 = topmost loop, -2 =
> all but topmist,...)

I don't agree with the use of hard-coded exit values.
I beleive this would be extremely problematic.

> + a string, which must have been defined as a label prior;
> + the name of a for loop index.

I think I would personally opt for "exit to label" only.
It covers every case as well as reduces confusion and complexity.

> * defaulted routine parameters, with ability to default any parameter, not
> only
> the last one(s)
> 
> The only mod to backend would be to update be_syncolor.c so that the trace
> screen
> displays the new keywords as such.
> 
> I'll submit this to user contributions spùewhere in november. If I ever write
> some new code in Eu, I'll probably use and require that new interpreter. I'll
> attempt to also implement pass by reference, but this may or may not work. An
> earlier implementation I had just does no longer work with multitasking.
> 
> CChris

Chris Bensler
Code is Alchemy

new topic     » goto parent     » topic index » view message » categorize

25. Re: Goto (Was Re: Open Source)

c.k.lester wrote:
> 
> CChris wrote:
> > 
> > loop do
> > -- some code
> > until some_condition
> > end loop
> 
> The "end loop" is redundant, isn't it?

Sure, but in keeping with all other Euphoria code block syntactic markers.

CChris

new topic     » goto parent     » topic index » view message » categorize

26. Re: Goto (Was Re: Open Source)

CChris wrote:
> 
> c.k.lester wrote:
> > 
> > CChris wrote:
> > > 
> > > loop do
> > > -- some code
> > > until some_condition
> > > end loop
> > 
> > The "end loop" is redundant, isn't it?
> 
> Sure, but in keeping with all other Euphoria code block syntactic markers.
> 
> CChris

why not the following?
until CONDITION do
  BLOCK
end until


new topic     » goto parent     » topic index » view message » categorize

27. Re: Goto (Was Re: Open Source)

Chris Bensler wrote:
> 
> CChris wrote:
> > 
> > I'll try submitting shortly a set of Eu front end files that add a number of
> > imho needed enhancements to the language. The additions are:
> > * forward routine calls allowed, using
> > }}}
<eucode>
> > forward function f(integer z)
> > n=f(3)
> > --- some code here
> > function f
> > -- usual routine body here
> > </eucode>
{{{

> 
> Is prototyping the way to go?
> For functional purposes, it's not needed, afaik. It's purely for distinction,
> correct?
> Would it not be better to have some syntax that is used specifically for each
> call to a forward reference?
> Such as:
>   n = ~f(3)
> 
> .. which makes it directly clear what is intended at the point it is used,
> rather than the point at which it is defined.
> 

~ had been repeatedly suggested to ignore the return value of a function, so I
didn't consider this new operator. A keyword sytax would be awkward, and there
are not too many unused symbols on the keyboard - and they may not be easy to get
on all sorts of keyboards.

The prototyping is necessary, because the interpreter needs to know which among
f(3), f(3,2) or f() are valid call, specially with defaulted arguments.
Additionally, it may seem more palatable to some because you still can't use a
routine or variable before declaring it. Defining can be postponed.

> > * new scope keyword, to declare variables local to part of a routine/top
> > level
> > code, possibly shadowing existing symbols;
> > * nested routines are now supported. For consistency reasons, you can call
> > only
> > a routine which is a direct descendant of any ancestor of te current
> > routine.
> > * new loop
> > }}}
<eucode>
> > loop do
> > -- some code
> > until some_condition
> > end loop
> > </eucode>
{{{

> 
> > * exif exits an if block;
> 
> Can you give an example of how this would be used?
> 

if I_got_here() then
  if some_cond then
    bla()
    if something_went_wrong() then
      exif 2 -- exit the whole thing
    end if
    -- more code
  else
    do_nothing()
  end if
end if


You could label the outer block, for the following variant:

if I_got_here() label "outer block" then
  if some_cond then
    bla()
    if something_went_wrong() then
      exif "outer block"
    end if
    -- more code
  else
    do_nothing()
  end if
end if


For the simplest cases, using numbers is simpler I think, as it avoids te visual
overhead of the label. But, in all generality, labels should be preferred, since
they protect the code against any loop/if block change. That's why I'm supporting
both systems.

> > * inside a oop, next skips the rest of the current iteration and performs
> > any
> > code prepring the next;
> > * retry jumps to top of loop, without executing the code that prepares next
> > iteration;
> > * all loops can have a label attached to it, like this
> > }}}
<eucode>
> > for i=1 to n by 2 label "my string" do
> > </eucode>
{{{

> > * exif/exit/next/retry now have an optional parameter, either
> > + a nuber of loop above current one (1 = loop above, 2=loop above the
> > latter,...)
> > + a negative number, to count loop levels backward (-1 = topmost loop, -2 =
> > all but topmist,...)
> 
> I don't agree with the use of hard-coded exit values.
> I beleive this would be extremely problematic.
> 

Theoretically right, but let's everyone decide by himself...

CChris

> > + a string, which must have been defined as a label prior;
> > + the name of a for loop index.
> 
> I think I would personally opt for "exit to label" only.
> It covers every case as well as reduces confusion and complexity.
> 
> > * defaulted routine parameters, with ability to default any parameter, not
> > only
> > the last one(s)
> > 
> > The only mod to backend would be to update be_syncolor.c so that the trace
> > screen
> > displays the new keywords as such.
> > 
> > I'll submit this to user contributions spùewhere in november. If I ever
> > write
> > some new code in Eu, I'll probably use and require that new interpreter.
> > I'll
> > attempt to also implement pass by reference, but this may or may not work.
> > An
> > earlier implementation I had just does no longer work with multitasking.
> > 
> > CChris
> 
> Chris Bensler
> Code is Alchemy

new topic     » goto parent     » topic index » view message » categorize

28. Re: Goto (Was Re: Open Source)

Chris Bensler wrote:
> 
> CChris wrote:
> > 
> > c.k.lester wrote:
> > > 
> > > CChris wrote:
> > > > 
> > > > loop do
> > > > -- some code
> > > > until some_condition
> > > > end loop
> > > 
> > > The "end loop" is redundant, isn't it?
> > 
> > Sure, but in keeping with all other Euphoria code block syntactic markers.
> > 
> > CChris
> 
> why not the following?
> }}}
<eucode>
> until CONDITION do
>   BLOCK
> end until
> </eucode>
{{{


Because the condition then appears at the top of the loop, while it is tested at
the end only. I bet people will complain of the above being too similar to a
while loop. I thought it more intuitive the other way, but have no serious
objection to the shorter form either.

CChris

CChris

new topic     » goto parent     » topic index » view message » categorize

29. Re: Goto (Was Re: Open Source)

CChris wrote:
> c.k.lester wrote:
> > CChris wrote:
> > > loop do
> > > -- some code
> > > until some_condition
> > > end loop
> > The "end loop" is redundant, isn't it?
> Sure, but in keeping with all other Euphoria code block syntactic markers.

IMHO, we should never choose tradition over efficiency. :)

new topic     » goto parent     » topic index » view message » categorize

30. Re: Goto (Was Re: Open Source)

c.k.lester wrote:
> 
> CChris wrote:
> > c.k.lester wrote:
> > > CChris wrote:
> > > > loop do
> > > > -- some code
> > > > until some_condition
> > > > end loop
> > > The "end loop" is redundant, isn't it?
> > Sure, but in keeping with all other Euphoria code block syntactic markers.
> 
> IMHO, we should never choose tradition over efficiency. :)

But we should choose consistency and the principle of least surprise over
efficiency.

Some languages, such as the BASH shell, put the until clause at the beginning of
the loop.

I don't know how hard it would be with regards to parsing, but I would prefer it
be done as it is done in C:

The current Euphoria while loop,

or

do
-- some statements
while x
end while


For loops which are required to be executed at least once. I disagree with
adding a keyword that only reverses the truth of a decision.

--
A complex system that works is invariably found to have evolved from a simple
system that works.
--John Gall's 15th law of Systemantics.

"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare

j.

new topic     » goto parent     » topic index » view message » categorize

31. Re: Goto (Was Re: Open Source)

c.k.lester wrote:
> 
> CChris wrote:
> > c.k.lester wrote:
> > > CChris wrote:
> > > > loop do
> > > > -- some code
> > > > until some_condition
> > > > end loop
> > > The "end loop" is redundant, isn't it?
> > Sure, but in keeping with all other Euphoria code block syntactic markers.
> 
> IMHO, we should never choose tradition over efficiency. :)

I agree, but then it would be another language...

CChris

new topic     » goto parent     » topic index » view message » categorize

32. Re: Goto (Was Re: Open Source)

Jason Gade wrote:
> 
> c.k.lester wrote:
> > 
> > CChris wrote:
> > > c.k.lester wrote:
> > > > CChris wrote:
> > > > > loop do
> > > > > -- some code
> > > > > until some_condition
> > > > > end loop
> > > > The "end loop" is redundant, isn't it?
> > > Sure, but in keeping with all other Euphoria code block syntactic markers.
> > 
> > IMHO, we should never choose tradition over efficiency. :)
> 
> But we should choose consistency and the principle of least surprise over
> efficiency.
> 

You probably expected it: I simply and completely disagree on this. Efficiency
first, consistency next (as close as possible). Least surprise is another name
for consistency, or is it something else? If I know the docs well and if they are
precise, I never have surprises, or they are called bugs.

> Some languages, such as the BASH shell, put the until clause at the beginning
> of the loop.
> 
> I don't know how hard it would be with regards to parsing, but I would prefer
> it be done as it is done in C:
> 
> The current Euphoria while loop,
> 
> or
> 
> }}}
<eucode>
> do
> -- some statements
> while x
> end while
> </eucode>
{{{

> 
> For loops which are required to be executed at least once. I disagree with
> adding
> a keyword that only reverses the truth of a decision.
> 

It does not do that _only_.
You can always emulate a loop block like this:
while 1 do
.. some code
if not some_cond() then exit end if
end while

How needlessly verbose! What does the "then exit end if" give you?

One thing I'm contemplating to add is an extra "entry" keyword, valid in both
while and loop blocks. If this keyword is present inside the block, the first
iteration of the loop will start there rather than at the top. There are quite a
few cases where you need to write hard to understand - and usually forgotten in
the first place - code to take account of some quantity just not being defined at
the start of first iteration. It would make code quite clearer in some cases. Not
hard to implement I think.

I have nothing fundamentally against the C-like }}}
<eucode>do ... while something
end while</eucode>
{{{
 syntax. However, what makes the more sense? Stating an end
condition at the end of the loop, or the keep-looping condition? As you said,
both are equivalent logically. I still think stating the end condition at the end
of the loop is slightly more intuitive.

Plus: how would you add a label to your construct, since it has no header?
Perhaps the label keyword should always follow do or then, after all, in which
case this difficulty disappears.

CChris

> --
> A complex system that works is invariably found to have evolved from a simple
> system that works.
> --John Gall's 15th law of Systemantics.
> 
> "Premature optimization is the root of all evil in programming."
> --C.A.R. Hoare
> 
> j.

new topic     » goto parent     » topic index » view message » categorize

33. Re: Goto (Was Re: Open Source)

CChris wrote:
> c.k.lester wrote:
> > CChris wrote:
> > > Sure, but in keeping with all other Euphoria code block syntactic markers.
> > IMHO, we should never choose tradition over efficiency. :)
> I agree, but then it would be another language...

I don't see Euphoria as a rigidly bordered language any more, not since it's
gone open source. Euphoria can be another language, if the people so choose.
However, we already have a looping mechanism in while, with the test up top.
The loop...until construct would simply put the test at the end,  meaning it
would always run at least once.

And if Euphoria hasn't needed that since it began, why does it need it now?

new topic     » goto parent     » topic index » view message » categorize

34. Re: Goto (Was Re: Open Source)

c.k.lester wrote:
> 
> CChris wrote:
> > c.k.lester wrote:
> > > CChris wrote:
> > > > Sure, but in keeping with all other Euphoria code block syntactic
> > > > markers.
> > > IMHO, we should never choose tradition over efficiency. :)
> > I agree, but then it would be another language...
> 
> I don't see Euphoria as a rigidly bordered language any more, not since it's
> gone open source. Euphoria can be another language, if the people so choose.
> However, we already have a looping mechanism in while, with the test up top.
> The loop...until construct would simply put the test at the end,  meaning it
> would always run at least once.
> 
> And if Euphoria hasn't needed that since it began, why does it need it now?

Thanks for this pure example of self-realising statement :P

My answer is: because the coder who needed the construct didn't use Eu to write
its program, as Eu had uncomfortable limitations.

The loop ... until ... construct doesn't add much functionality, as it can be
emulated. It's just a convenience and can prevent some bugs from appearing by not
requiring a translation to another loop, usually a while one.

CChris

new topic     » goto parent     » topic index » view message » categorize

35. Re: Goto (Was Re: Open Source)

CChris wrote:
> The loop ... until ... construct doesn't add much functionality, as it can be
> emulated. It's just a convenience and can prevent some bugs from appearing by
> not requiring a translation to another loop, usually a while one.

I'm not against it as long as it is

loop do [label]
...
until condition

new topic     » goto parent     » topic index » view message » categorize

36. Re: Goto (Was Re: Open Source)

c.k.lester wrote:
> 
> CChris wrote:
> > The loop ... until ... construct doesn't add much functionality, as it can
> > be
> > emulated. It's just a convenience and can prevent some bugs from appearing
> > by
> > not requiring a translation to another loop, usually a while one.
> 
> I'm not against it as long as it is
> 
> loop do [label]
> ...
> until condition

I don't mind either.
And after all this is not standard Euphoria, so people who would like to see the
"end something" marker (which is useless) can just stick to the standard thing.

I didn't implement yet the "with indent" directive that would allow to replace
end, do and then by indent changes. One thing at a time...

CChris

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu