Break to a specific statement label

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
charvista
Addict
Addict
Posts: 949
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Break to a specific statement label

Post by charvista »

In some circumstances, a Break (to quit a loop) may be done to a specific place in the program, not always just after the End loop statement (Next, Wend).
My idea is to add a label after the Break. Here a structural example:

Code: Select all

Procedure myProc(x)
    For i=1 To 50
        If i=x
            Break 1, SpecialExit
        EndIf
        ...
    Next
    ....
    ProcedureReturn 0
    
    SpecialExit:
    ProcedureReturn -1
EndProcedure
And because Break already has one optional parameter (Level), the label is the second parameter (also optional).
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Break to a specific statement label

Post by luis »

Hi, I don't want to rain on your... request, but really I have to write this:

Code: Select all

Procedure myProc(x)
    For i=1 To 50
        If i=x
            Goto SpecialExit ; look, we already have a cleanest way to do so
        EndIf
        ...
    Next
    ....
    ProcedureReturn 0
   
    SpecialExit:
    ProcedureReturn -1
EndProcedure

Break has certainly its place in coding (it is a goto to clear implicit exit label, and it's easy to understand when you look at your code later).

Break N is still a goto under disguise, but a very ugly one to see and mantain, compared to a real goto where the label is explicit. It's really there only to enable people with goto-complex to say "see, I haven't used a goto but a nice structured construct!" and lie to themselves.

Break 1, SpecialExit would be ugly beyond words compared to a clear goto, with no advantages, not considering the meaningless syntax (break 1 level, but not necessarily a level mind you, break to where I want to, like... a goto you see ?)

:wink:
"Have you tried turning it off and on again ?"
A little PureBasic review
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: Break to a specific statement label

Post by xorc1zt »

If you want to go somewhere, goto is the best way to get there. -- Kenneth Thompson
User avatar
STARGÅTE
Addict
Addict
Posts: 2227
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Break to a specific statement label

Post by STARGÅTE »

Use a fake loop:

Code: Select all

Procedure myProc(x)
	Repeat
		For i=1 To 50
			If i=x
				Break 2
			EndIf
			...
		Next
		....
		ProcedureReturn 0
	Until #True
	ProcedureReturn -1
EndProcedure

PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Break to a specific statement label

Post by luis »

STARGÅTE wrote:Use a fake loop:

Code: Select all

Procedure myProc(x)
	Repeat
		For i=1 To 50
			If i=x
				Break 2
			EndIf
			...
		Next
		....
		ProcedureReturn 0
	Until #True
	ProcedureReturn -1
EndProcedure

See what I mean ? It can hurt your retina permanently.
A loop with no reason to be there and a goto disguised under a "Break skip_tot_levels_in_a_(come_on)_structured_way".
Plus you have to concentrate and count on your fingers to understand where it will land.
This thing instead of a goto ?
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
charvista
Addict
Addict
Posts: 949
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Re: Break to a specific statement label

Post by charvista »

Hahaha, I see it indeed, that a Break 6, Label could have been very difficult to decypher later!
And yes Luis, we have already spoken together before about the fact that GOTO did not cause problems in a FOR-NEXT loop. Only in a Select/Case, a GOTO can crash the program.

I have made a new experiment and it shows us that GOTO to a statement label outside the loop does in fact a BREAK because the second Next i gives an error (which is a bit unexpected, because the loop was normally not finished yet)

Code: Select all

For i=1 To 50
    If i=4
        Goto Special
    EndIf
Next i
Debug "End program"
End
Special:
Debug x
Next i
So, now I think that a Break with a branch is not necessary because of this discovering....
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Break to a specific statement label

Post by luis »

Yes I remember we talked in the other thread :)

Well it shouldn't be unexpected because FORs and NEXTs need to be balanced, so a for with two nexts really is no basic anymore and the compiler simply cannot translate that. I'm not saying it's not possible to generate working code for that by try to imagine looking through a source with unbalanced loops. :shock:

Goto is like a "jolly" statement giving you the freedom to skip code as you like, you simply have to use it in a prudent way and when it's really making your code cleaner and easy to read and maintain (I firmly believe it can in many situations especially in languages like C and PureBasic).

What we would really need to make the GOTO more easy to use in PB are local labels, IMHO.
http://www.purebasic.fr/english/viewtop ... 65#p326365
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: Break to a specific statement label

Post by Lord »

charvista wrote:...

Code: Select all

For i=1 To 50
    If i=4
        Goto Special
    EndIf
Next i
Debug "End program"
End
Special:
Debug x
Next i
...
Something like this should work:

Code: Select all

For i= 1 To 10
  If i & 1
  Goto Special
EndIf
  Debug i
 ResumeNext: 
Next i

Debug "Jump to End"
Goto Finish

Special:
Debug Str(i)+": Doing something special here"
Goto ResumeNext

Finish:
Debug "End"

End
Image
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Break to a specific statement label

Post by Little John »

Lord wrote:Something like this should work:

Code: Select all

For i= 1 To 10
  If i & 1
  Goto Special
EndIf
  Debug i
 ResumeNext: 
Next i

Debug "Jump to End"
Goto Finish

Special:
Debug Str(i)+": Doing something special here"
Goto ResumeNext

Finish:
Debug "End"

End
This is a good example of abuse of Goto. Using Goto here does not give any advantage, but unnecessarily produces bad readable "spaghetti code". Code like this exactly is the reason why Goto got a bad reputation.
The following code does the same, without using any Goto:

Code: Select all

For i = 1 To 10
   If i & 1
      Debug Str(i) + ": Doing something special here"
   Else   
      Debug i
   EndIf
Next i

Debug "End"
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Break to a specific statement label

Post by Tenaja »

Every code construct can be performed without a Goto. Little John is right, though, that is the perfect example of when NOT to use goto.

However, depending upon the application or the needs, a Goto can help eliminate redundant code. When memory use is an issue (never in PB, though) this is common:

Code: Select all

For x = 1 To 100
	; perform my actions
	
	; Test external action
	If ExternalAction = #True : Goto ExitProc : EndIf
	
	; Perform more actions
Next
;more code here...

ExitProc:

Return RediculouslyLongReturnCalculationHere
This is perfectly legal in most languages, even C. In fact, this is the perfect example of why the Goto was left in C--back in the 70's, memory was too limited to repeat the long return calculation or set and test a flag. (Remember, the game Pitfall! for Atari was written in 4k of code space...while it was hand coded asm rather than compiled code, back in those days, even compiled code had to be small.)

However, these are different times. In PB, this is the more "generally accepted" way to do it:

Code: Select all

For x = 1 To 100
	; perform my actions
	
	; Test external action
	If ExternalAction = #True : MyExternalActionFlag = #True : Break : EndIf
	
	; Perform more actions
Next

If Not MyExternalActionFlag
	;more code here...
EndIf
Return RediculouslyLongReturnCalculationHere
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Break to a specific statement label

Post by Demivec »

I just have some comments but no real solutions.

Ideally something like 'break to a label' would be done with a 2 pass compiler to avoid counting the levels by hand. I don't think other solutions will work very well without seeming kludgy (is that a word?).

Another approach would be subroutines local to a procedure. Perhaps with a 'gosub local_label' frollowed by a 'local_return'. This also has had some problems as this was discussed in the past. Some of the problems involve how parameters are handled on the stack and whether the sub-routine had its own local parameters.

Each of these options seem like attempts to deal with a past limitation of memory and sometimes execution speed. Not as vital these days but still frequently important. There are also the issues when dealing with exception handling.

I would prefer the option of local subroutines but either one would actually be an improvement.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Break to a specific statement label

Post by luis »

As I already wrote some times but it never hurt to repeat it, IMO the perfect example why GOTO should be used in PB programs is another.

It's the ability of leave a procedure while keeping a single exit point where you do the cleanup of the resources allocated along the body of the procedure up to the point of a failure that is forcing you to leave.
All this resulting in clean code readable from top to bottom with the assumption that no error will happen, in a way similar to languages supporting exceptions handling, without nested IF RETURNVALUE using dubious vars to keep tracks of the current error state or multiple breaks or fake loops or other atrocities.

Someone else already explained it with some code so I don't have to do it myself:
http://www.cprogramming.com/tutorial/goto.html

And using some macros you can even make it similar (cosmetically) to proper exception handling and so pleasing to see and easy to understand and follow.

All the advantages lost by avoiding this approach are probably the first and major reason why so much code written by PB coders has faulty, incomplete or totally missing error checking. Because when the complexity of a single procedure grows it become tedious work, adds distracting redundant noise when reading back code, it is extremely error prone, and it is difficult to write.

Another good use is to leave deep nested structured code, as explained also in the K&R, but it comes a distant second IMO.

Some excerpt from "Structured programming with goto statements", a 1974 article from Knuth.
I suggest its reading to everyone using PB, it's very nice and thought provoking.

Before starting to laugh, consider PB at its core it's certainly not a language of the second millenium, but more of the '70s.
Such checks on the validity of
data are very important, especially in soft-
ware, and it seems to be the one class of go
to's that still is considered ugly but neces-
sary by today's leading reformers.
[...]
Sometimes it is necessary to exit from
several levels of control, cutting across code
that may even have been written by other
programmers; and the most graceful way to
do this is a direct approach with a go to or
its equivalent. Then the intermediate levels
of the program can be written under the
assumption that nothing will go wrong.
Sound familiar ?
Event Indicators
The best such language feature I know has
recently been proposed by C. T. Zahn.
[...]
The essential novelty
in his approach is to introduce a new quan-
tity into programming languages, called an
event indicator (not to be confused with
concepts from PL/I or SIMSC~IPT). My
current preference is to write his event-
driven construct in the following two general
forms.
[...code follows...]
It is important to emphasize that the first
line of the construct merely declares the
event indicator names, and that event
indicators are not conditions which are being
tested continually; (event) statements are
simply transfers of control which the com-
piler can treat very efficiently. Thus, in
Example 5e the statement "leaf replaced"
is essentially a go to which jumps out of
the loop.
[...]
Of course, event indicators are not the only
decent alternatives to go to statements
that have been proposed. Many authors
have suggested language features which
provide roughly equivalent facilities, but
which are expressed in terms of exit, jump-
out, break, or leave statements. Kosaraju
has proved that such statements are
sufficient to express all programs without
go to's and without any extra computation,
but only if an exit from arbitrarily many
levels of control is permitted.
Until then, Break 37 or goto.

I'll leave to you to guess how those "event indicators" evolved in many contemporary languages.
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: Break to a specific statement label

Post by Lord »

Little John wrote:
Lord wrote:Something like this should work:

Code: Select all

For i= 1 To 10
  If i & 1
  Goto Special
EndIf
  Debug i
 ResumeNext: 
Next i

Debug "Jump to End"
Goto Finish

Special:
Debug Str(i)+": Doing something special here"
Goto ResumeNext

Finish:
Debug "End"

End
This is a good example of abuse of Goto. Using Goto here does not give any advantage, but unnecessarily produces bad readable "spaghetti code". Code like this exactly is the reason why Goto got a bad reputation.
The following code does the same, without using any Goto:

Code: Select all

For i = 1 To 10
   If i & 1
      Debug Str(i) + ": Doing something special here"
   Else   
      Debug i
   EndIf
Next i

Debug "End"
My example wasn't meant as an example for "good programming habit".
I just wanted to show a way to avoid an extra "NEXT" ouside the loop.

But I have to say, that I love GOTO. It's BASIC.
Image
User avatar
Ajm
Enthusiast
Enthusiast
Posts: 242
Joined: Fri Apr 25, 2003 9:27 pm
Location: Kent, UK

Re: Break to a specific statement label

Post by Ajm »

Hi all,

My two pennies worth on the use of Goto......

Coming from a background of using Informix 4gl (Still coding in this for a living). I always use Goto statements to avoid using too many nested IF statements.

Hypothetical code:-

Code: Select all


begin function
Do some database manipulation (Inserts, Updates etc...)
set a return code from the above statement
If the return code shows it was unsuccessful then
goto lab_exit
end if

do more database related stuff, calculations or anything else
check return code
If the return code shows it was unsuccessful then
goto lab_exit
end if

label lab_exit:

return the return code to the calling function
end function
 
I personally find this makes much easier to follow code and I only ever use Goto to jump forward to an exit point never to jump backwards.
Regards

Andy

Image
Registered PB & PureVision User
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Break to a specific statement label

Post by Little John »

Lord wrote:I just wanted to show a way to avoid an extra "NEXT" ouside the loop.
And I just wanted to show a way to avoid the abuse of Goto. :lol:
Post Reply