Author |
Topic: about GOSUBs (Read 1502 times) |
|
BrianM
New Member
member is offline


Posts: 15
|
 |
Re: about GOSUBs
« Reply #11 on: Aug 2nd, 2016, 4:10pm » |
|
Gosubs are not completely redundant as they can be used inside subroutines and functions. The advantage in using a gosub over using a subroutine or function is that the gosub code "sees" the same variables as the calling sub or function and so no extra global variables are required to share data. The disadvantage is that you cannot use parameters. In certain situations this can result in a simpler code structure.
This is similar to internal and nested subroutines available in other languages.
I have found that in LBB that the labels for the gosub code must be unique throughout the program and not just in the enclosing subroutine or function. This is not the case in Liberty Basic.
Brian Matthews
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: about GOSUBs
« Reply #12 on: Aug 2nd, 2016, 4:51pm » |
|
on Aug 2nd, 2016, 4:10pm, BrianM wrote:| I have found that in LBB that the labels for the gosub code must be unique throughout the program and not just in the enclosing subroutine or function. This is not the case in Liberty Basic. |
|
That is not correct, in general, as the simple test program below demonstrates:
Code: gosub [label1]
call mysub
call anothersub
gosub [label1]
stop
[label1]
print "At [label1] in the main program"
return
sub mysub
gosub [label1]
exit sub
[label1]
print "At [label1] in sub mysub"
return
end sub
sub anothersub
gosub [label1]
exit sub
[label1]
print "At [label1] in sub anothersub"
return
end sub You can probably contrive a situation in which it won't work, for example by placing the destination for the outer GOSUB after rather than before the SUBs, but if you follow the recommendation to place all SUBs and FUNCTIONs at the end of the program that situation won't arise.
Richard.
|
|
|
|
BrianM
New Member
member is offline


Posts: 15
|
 |
Re: about GOSUBs
« Reply #13 on: Aug 2nd, 2016, 5:07pm » |
|
This is my test program that works in LB but not LBB. I can't see an error. Code:
call mysub1
call mysub2
end
sub mysub1
for i = 1 to 5
gosub [internal_sub]
next
exit sub
[internal_sub]
print "internal sub(mysub1)",i
return
end sub
sub mysub2
for i = 1 to 5
gosub [internal_sub]
next
exit sub
[internal_sub]
print "internal sub(mysub2)",i
return
end sub
Brian Matthews
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: about GOSUBs
« Reply #14 on: Aug 2nd, 2016, 5:35pm » |
|
on Aug 2nd, 2016, 5:07pm, BrianM wrote:| This is my test program that works in LB but not LBB. I can't see an error. |
|
That's a quite separate issue, caused by you including an 'illegal' character (an underscore) in your labels. This is what the LB Help File has to say about label names: "The label can be either a traditional line number or a branch label in the format [branchLabel] where the branch label name can be any upper/lowercase letter combination. Spaces and digits are not allowed".
It's not as precise as I would like, but I interpret "any upper/lowercase letter combination" as not permitting the use of an underscore - after all underscores definitely aren't allowed in variable names (except Windows Constants) and it's uncommon for different rules to apply.
If you remove the underscores from your label names (or substitute a character which is legal in a variable name like a dot) the program works as expected:
Code:call mysub1
call mysub2
end
sub mysub1
for i = 1 to 5
gosub [internalsub]
next
exit sub
[internalsub]
print "internal sub(mysub1)",i
return
end sub
sub mysub2
for i = 1 to 5
gosub [internalsub]
next
exit sub
[internalsub]
print "internal sub(mysub2)",i
return
end sub Richard.
|
|
Logged
|
|
|
|
BrianM
New Member
member is offline


Posts: 15
|
 |
Re: about GOSUBs
« Reply #15 on: Aug 2nd, 2016, 8:19pm » |
|
Richard
I often use underscores in other languages and so I used them in LB labels without thinking whether they were allowed or not and as they worked I never checked. So my mistake.
The LB documentation is often at odds with what is actually implemented. The help talks about alphanumeric labels (those in square brackets) and then goes on to say spaces and numbers are not allowed, in which case they are not alphanumeric. The basic code for freeform uses . and digits in labels.
A quick check has shown that the characters _.%&\?{}!# can also be used in labels and there could be others.
I think your approach of using the same syntax for labels and variables is probably the most sensible one.
But to get back to my original point. Despite many people declaring that gosubs are obsolete, they still have their uses.
Brian Matthews
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: about GOSUBs
« Reply #16 on: Aug 2nd, 2016, 8:37pm » |
|
on Aug 2nd, 2016, 8:19pm, BrianM wrote:| The LB documentation is often at odds with what is actually implemented. |
|
You're telling me: having to discover largely by trial-and-error what LB does and doesn't do, rather than being able to rely on the documentation, is one of the main reasons why it took so long to get LBB to the degree of compatibility it currently has.
Quote:| Despite many people declaring that gosubs are obsolete, they still have their uses. |
|
I strongly disagree. I haven't used a GOSUB in a program for around 35 years, and I've not missed them.
Richard.
|
|
Logged
|
|
|
|
BrianM
New Member
member is offline


Posts: 15
|
 |
Re: about GOSUBs
« Reply #17 on: Aug 2nd, 2016, 9:21pm » |
|
Richard
I would hazard a guess that your Basic programming has largely been with BBC Basic which uses dynamic scoping for variables so that a called FN or PROC sees the same variables as the calling FN or PROC (or main) unless local variables or parameters are used. This makes data sharing between FNs and PROCs easy and without the need for special GLOBAL variables or passing large amounts of data via parameters. What I am suggesting is this can be emulated in LB and LBB which use static variable scoping by using GOSUBS inside SUBS and FUNCTIONS. In some cases this can reduce the complexity of the code structure. I do not advocate general use of GOSUBS
Brian Matthews
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: about GOSUBs
« Reply #18 on: Aug 2nd, 2016, 10:13pm » |
|
on Aug 2nd, 2016, 9:21pm, BrianM wrote:| I would hazard a guess that your Basic programming has largely been with BBC Basic which uses dynamic scoping for variables so that a called FN or PROC sees the same variables as the calling FN or PROC |
|
Sadly yes. I work around that shortcoming in two ways: firstly those variables that I really want to be GLOBAL get commented as such at the start of the program, so that at least it's clear to the reader even though it's not enforced by the language. Secondly I use strict naming conventions (local variable names consisting of only lowercase letters whilst globals use mixed case); the Cross Reference utility will then warn me if I inadvertently access a variable which is neither local nor global.
Whilst neither of those strategies compensates for the weak scoping of the language they are better than nothing.
Quote:| This makes data sharing between FNs and PROCs easy and without the need for special GLOBAL variables or passing large amounts of data via parameters. What I am suggesting is this can be emulated in LB and LBB |
|
True, but why would you want to emulate a weakness of a language? One can justify static (lexical) scoping rules that allow an inner block to see the variables declared in an outer block, but not dynamic scoping that allows the same thing to happen at run time even if the functions are physically separated in the code.
I would always explicitly pass as parameters variables that need to be accessed by a sub-function, even if the dynamic scoping allows it to see those same variables.
Richard.
|
|
Logged
|
|
|
|
BrianM
New Member
member is offline


Posts: 15
|
 |
Re: about GOSUBs
« Reply #19 on: Aug 3rd, 2016, 12:53pm » |
|
Richard
I agree totally with your last post.
The dynamic scoping of BBC Basic can cause problems by forgetting to declare a variable as local and inadvertently updating the variable with the same name in the calling PROC or FN. I presume this is the weakness you are referring to.
I am not trying to emulate dynamic scoping but rather the file scoping of the C programming language. LB and LBB only provide global or local variables. What I would like is something in between.
If a large sub or function is refactored into a number of smaller subs and functions then the problem of data sharing arises. As you say this can be achieved by the use of globals (suitably named) or by passing parameters. I prefer the passing of parameters but this does not look right when the same parameter list is used over and over again and with parameters passed BYREF. This cries out for C file scoping or perhaps using OOP classes and class properties. In these instances I consider using gosubs but I realise I am not going to pursuade you that it might be a good idea. To my mind gosubs within subs and functions do give :- Quote:| scoping rules that allow an inner block to see the variables declared in an outer block |
|
Perhaps I should forget LB compatibility and investigate the OOP extensions of LBB.
Brian Matthews
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: about GOSUBs
« Reply #20 on: Aug 3rd, 2016, 10:04pm » |
|
on Aug 3rd, 2016, 12:53pm, BrianM wrote:| I prefer the passing of parameters but this does not look right when the same parameter list is used over and over again and with parameters passed BYREF. |
|
The technique I usually adopt in BBC BASIC is to store the 'shared variables' in a structure. That structure can be made LOCAL (or PRIVATE) to the enclosing function, and can be conveniently passed - as a single parameter - to all those sub-functions that need to share its contents. This seems to be the best of both worlds: no need for the sub-functions to implicitly share variables through lexical scoping, but equally no need to pass multiple parameters by reference each time.
Of course this solution doesn't help in Liberty BASIC, because structures are always global. This is mindbogglingly stupid (almost as stupid as arrays being always global) - are you listening Mr Gundel? 
Quote:| Perhaps I should forget LB compatibility and investigate the OOP extensions of LBB. |
|
As has been discussed here before, it is reasonable to utilise the OOP features of LBB not because you actually want to write 'Object Oriented' code as such, but simply as a workaround for the absence of local arrays and structures.
Richard.
|
|
Logged
|
|
|
|
|