GoSubs allow you to completely avoid overburdened control structures.
I've seen them, you've seen them, "If" statements that span pages. "If" and "Do" and "Select"s and "For" structures nested way too many levels deep.
Suppose a monster like this starts growing in your code. You add features, make exceptions, etc. etc., the code grows. So, to tame it, you want to take a chunk of it out, put it aside under a label, and leave the label behind.
In most languages, other than BASIC and Assembly, you only have one choice in the kind of label to put it behind. A full blown separate procedure, complete with calling arguments needing to be defined at the call, at the definition, maybe other overhead, etc. etc. The threshold for this being rather high is the reason you see so many overburdened control structures.
Of course this solution is available in BASIC, but BASIC also gives you the GoSub. Simply cut and past the code to the bottom of your sub. Place a "Return" line in front, a label for the Gosub, your pasted code, another "Return", then put "Gosub label" where the code was and you are done. Well, you'll likely change the indentation and comment it more. If it isn't the first GoSub, the first "Return" won't be necessary. It is cheap at runtime too, (I presume this is true for Gambas as well).
So how do you decide which type of GoSub to use? It depends mostly on two criteria:
1) How many local variables are in the code that you will need to define references for?
2) Is it useful as a generally available sub?
Those criteria aren't quite independent either, so most the time the decision is easy.
Here's an example from the GamePad test program I am working on.
'=============================================================================
Public Sub TimerTick(ArgDisplayLB As ListBox, ArgTagNamesCB As CheckBox[])
Dim theOutcome As Integer
Do
theOutcome = myGamePad.GetFancyEvent()
If theOutcome < 0 Then Break
GoSub ShowInDisplayListBox
GoSub HandleGamePadEvent
Loop
Return
'-----------------------------------------------------------------------------
ShowInDisplayListBox:
ArgDisplayLB.Add(myGamePad.EventToString())
'---- Maybe Reduce Event Display Size
If ArgDisplayLB.count > 1000 Then
ArgDisplayLB.Remove(0, 100)
Endif
'---- Position Display At End
ArgDisplayLB.Index = ArgDisplayLB.Count - 1
Return
'-----------------------------------------------------------------------------
HandleGamePadEvent:
Dim n, v, k, e As Integer
n = myGamePad.MyGPE.Number
v = myGamePad.MyGPE.Value
k = myGamePad.MyGPE.Kind
There are many more lines, and a few more gosubs that follow. All too big to fit in the read loop. Yes, in this case there weren't too many parameters to worry about, but keeping it local keeps it neater and the external interface cleaner.
It's really nice to have GoSubs as an option.