1. Goto (Was Re: Open Source)
- Posted by c.k.lester <euphoric at ?kle?ter.com> Oct 19, 2007
- 869 views
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.
2. Re: Goto (Was Re: Open Source)
- Posted by Fernando Bauer <fmbauer at hotmai?.?om> Oct 19, 2007
- 803 views
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
3. Re: Goto (Was Re: Open Source)
- Posted by Pete Lomax <petelomax at blueyonder.?o.uk> Oct 19, 2007
- 813 views
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
4. Re: Goto (Was Re: Open Source)
- Posted by Juergen Luethje <j.lue at ?mx.?e> Oct 23, 2007
- 809 views
- Last edited Oct 24, 2007
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
5. Re: Goto (Was Re: Open Source)
- Posted by Derek Parnell <ddparnell at big?ond.co?> Oct 23, 2007
- 809 views
- Last edited Oct 24, 2007
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
6. Re: Goto (Was Re: Open Source)
- Posted by Matt Lewis <matthewwalkerlewis at g?ail?com> Oct 24, 2007
- 810 views
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
7. Re: Goto (Was Re: Open Source)
- Posted by Al Getz <Xaxo at ?ol.co?> Oct 24, 2007
- 817 views
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."
8. Re: Goto (Was Re: Open Source)
- Posted by Matt Lewis <matthewwalkerlewis at gmai?.?om> Oct 24, 2007
- 818 views
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
9. Re: Goto (Was Re: Open Source)
- Posted by Pete Stoner <stoner.pete at ??ail.com> Oct 24, 2007
- 812 views
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
10. Re: Goto (Was Re: Open Source)
- Posted by Juergen Luethje <j.lue at ?m?.de> Oct 24, 2007
- 812 views
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
11. Re: Goto (Was Re: Open Source)
- Posted by Pete Lomax <petelomax at blueyonder.c??uk> Oct 24, 2007
- 827 views
- Last edited Oct 25, 2007
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
12. Re: Goto (Was Re: Open Source)
- Posted by Juergen Luethje <j.lue at gm??de> Oct 25, 2007
- 824 views
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
13. Re: Goto (Was Re: Open Source)
- Posted by Juergen Luethje <j.lue at g?x.de> Oct 25, 2007
- 858 views
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
14. Re: Goto (Was Re: Open Source)
- Posted by Pete Lomax <petelomax at blu?y?nder.co.uk> Oct 25, 2007
- 876 views
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 > 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 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
15. Re: Goto (Was Re: Open Source)
- Posted by Juergen Luethje <j.lue at ?m?.de> Oct 25, 2007
- 818 views
- Last edited Oct 26, 2007
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 I probably better shouldn't do things like that before breakfast. > > 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 > > 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
16. Re: Goto (Was Re: Open Source)
- Posted by Pete Lomax <petelomax at blueyonder.co.u?> Oct 26, 2007
- 814 views
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 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
17. Re: Goto (Was Re: Open Source)
- Posted by Juergen Luethje <j.lue at g?x?de> Oct 26, 2007
- 833 views
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 > > 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? (I am curious whether this is actually possible from a theoretical point of view.)
18. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at agriculture.gouv.??> Oct 26, 2007
- 823 views
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 > > > > 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? > (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
19. Re: Goto (Was Re: Open Source)
- Posted by Kat <KAT12 at coosahs?ne?> Oct 28, 2007
- 794 views
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
20. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at agricul?ure.gouv.f?> Oct 28, 2007
- 833 views
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
21. Re: Goto (Was Re: Open Source)
- Posted by Chris Bensler <eu at cr?ativeportal.c?> Oct 28, 2007
- 811 views
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
22. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at ?griculture.?ouv.fr> Oct 28, 2007
- 799 views
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
23. Re: Goto (Was Re: Open Source)
- Posted by c.k.lester <euphoric at cklest?r?com> Oct 28, 2007
- 816 views
CChris wrote: > > loop do > -- some code > until some_condition > end loop The "end loop" is redundant, isn't it?
24. Re: Goto (Was Re: Open Source)
- Posted by Chris Bensler <eu at creativeport??.ca> Oct 28, 2007
- 831 views
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
25. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at agriculture?gouv?fr> Oct 29, 2007
- 807 views
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
26. Re: Goto (Was Re: Open Source)
- Posted by Chris Bensler <eu at c?eativeportal?ca> Oct 29, 2007
- 881 views
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
27. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at ag?icult?re.gouv.fr> Oct 29, 2007
- 834 views
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
28. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at agri?ultu?e.gouv.fr> Oct 29, 2007
- 798 views
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
29. Re: Goto (Was Re: Open Source)
- Posted by c.k.lester <euphoric at c?lester.?om> Oct 29, 2007
- 829 views
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. :)
30. Re: Goto (Was Re: Open Source)
- Posted by Jason Gade <jaygade at ya?oo.?om> Oct 29, 2007
- 805 views
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.
31. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at agri?ulture.gou?.fr> Oct 29, 2007
- 797 views
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
32. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at agriculture??ouv.fr> Oct 29, 2007
- 807 views
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.
33. Re: Goto (Was Re: Open Source)
- Posted by c.k.lester <euphoric at ck?e?ter.com> Oct 29, 2007
- 796 views
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?
34. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at agriculture.go?v.fr> Oct 29, 2007
- 789 views
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
35. Re: Goto (Was Re: Open Source)
- Posted by c.k.lester <euphoric at ?kle?ter.com> Oct 29, 2007
- 797 views
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
36. Re: Goto (Was Re: Open Source)
- Posted by CChris <christian.cuvier at a?riculture?gouv.fr> Oct 29, 2007
- 779 views
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