Posts: 2,697
Threads: 327
Joined: Apr 2022
Reputation:
217
(08-09-2024, 04:03 PM)bplus Wrote: I am curious on other peoples thoughts on drawing the line between using a GoSub and a full blown Sub.
My rule it should be a full blown Sub if there is any chance the Sub might be used in other apps but when in doubt just go Sub.
GoSubs best for applications very specific for the code you ar working. This issues should be decided before Constants and Shared, that is if we are actually thinking ahead a little
My general use for gosub, tends to be ONLY inside subs/functions, and that's to minimize repetitive code that only occurs inside that sub/function.
Code: (Select All) SUB FOO
SELECT CASE keyhit
CASE left: x = x -1: gosub check_bounds
CASE right: x = x + 1: gosub check_bounds
END SELECT
EXIT FUNCTION
check_bounds:
IF x < 0 then x = _WIDTH -1
IF x >= _WIDTH then x = 0
RETURN
END SUB
Something similar to the above, where that same code might be called multiple times inside the same SUB, and which will never possibly be of any use anywhere else inside the main program as a standalone SUB might be.
Posts: 1,002
Threads: 50
Joined: May 2022
Reputation:
27
The programming style ultimately corresponds to the own experience with programming computers. And how is these?
That have to be the question!
Posts: 597
Threads: 110
Joined: Apr 2022
Reputation:
34
Big fan of datatype sigils (suffixes). Although non-text characters generally annoy me, I very much like to see the data type on any identifier, and I find it much easier to search and locate identifiers when they have suffixes. (Suffixes make "false-positive" find much less likely, if not totally unlikely.)
Case: - all language keywords in UPPERCASE
- all variables in camelCase
- all function name, sub names, and line labels in PascalCase
- constants, completely inconsistent (I tend to lean UPPERCASE, but I'm not in love with it)
GOSUB vs SUB: - I like to see the big picture view of a main program such that I do not have to scroll the screen up/down. So I usually reach for GOSUB as a way to compact main code (or GOSUB subroutines)
- If a subroutine is generic enough that I might use it in some other program, or if I don't want to risk a subroutine modifying global variables, or if the subroutine is for a recursive process, I'll be setting up a SUB subroutine
GOTO: I'm a big fan of GOTO for very particular circumstances. - When a certain condition is TRUE (or FALSE) and we need to skip over the next few lines of code
- A loop in which I go to the Normal starting point, but in some circumstances I want to actually go a little bit before, or a little bit after, the normal starting point
- Endless loop (or one that is essentially endless), I'll reach for GOTO and a (descriptive label) before a DO...LOOP every time
- However, I won't allow spaghetti code (I.e. I don't want to be ping-ponging all over the place)
Posts: 1,002
Threads: 50
Joined: May 2022
Reputation:
27
Quote:- If a subroutine is generic enough that I might use it in some other program, or if I don't want to risk a subroutine modifying global variables, or if the subroutine is for a recursive process, I'll be setting up a SUB subroutine
A Sub or Procedure cannot change variables unless they are declared as Shared in the main program. Or did you mean something else?
Posts: 597
Threads: 110
Joined: Apr 2022
Reputation:
34
08-09-2024, 11:27 PM
(This post was last modified: 08-09-2024, 11:58 PM by CharlieJV.)
(08-09-2024, 11:21 PM)Kernelpanic Wrote: Quote:- If a subroutine is generic enough that I might use it in some other program, or if I don't want to risk a subroutine modifying global variables, or if the subroutine is for a recursive process, I'll be setting up a SUB subroutine
A Sub or Procedure cannot change variables unless they are declared as Shared in the main program. Or did you mean something else?
(Just to try and clarify my usage of "SUB" subroutines vs "GOSUB" subroutines.)
I always make top level variables global. Well, if ever I run into something that bites me in the rear, I'll likely change my habits.
I'll probably never change that habit because of the kind of programming I do (usually does not involve much code.)
(I'm a career OpenText Gupta Team Developer programmer, so there are certain organizational things from that programming environment that kind of stick with me when programming in BASIC.)
OMG, I'm having a rough night: just had to cancel a big mistake with an e-transfer. In the midst of a migraine headache so having a hard time thinking straight.
If a subroutine has no need to use any global variables, then I will choose a SUB subroutine over a GOSUB subroutine. Otherwise, i.e. a subroutine that is very intertwingled with the particular program, I will choose a GOSUB subroutine.
So a GOSUB versus subroutine call sort of tells me which kind of thing I'm dealing with just by how the subroutine is invoked. (Little descriptive breadcrumbs without needing any other descriptive info.)
Now if I had variables that I really wanted to keep private to the main program, I'd likely put my main program in a "main" SUB.
Which is kind of odd considering my loathing of languages that always have a "main" function.
I think it all ties back to how code is organized in OpenText Gupta Team Developer. (Programming with that has been my full-time job since 1995, so it does skew my thinking).
Posts: 2,177
Threads: 222
Joined: Apr 2022
Reputation:
104
I'm a bit different than Charlie when it comes to using GOTO. I almost never use it. Instead, I'll nest a WHILE LOOP inside a DO LOOP and use EXIT WHILE. Works in most of my cases.
One think I WISH WE HAD was IDE coloration of LABELS.
As I get older I try to not use colons to put multiple lines of code on one line; That way, I can SEARCH for ':' to find labels much easier.
I have also done as Charlie and made sub calls and subroutines so the main body of code is easy to read and see what is going on, but the downside is I have to keep jumping back and forth to the subroutines to see the whole code. My trick for that is to open two IDE's, one for the main flow and the other to see the subroutines as I work my way through the main code.
What have we learned from this? We've learned getting old is a pain in the ASCII. I used to keep all of these constructs in my head. Now that space has transitioned into a parking lot for my weekly Alzheimer's group. We meet on... Wed... no, Thur... OH F***!
Pete
Shoot first and shoot people who ask questions, later.
Posts: 2,697
Threads: 327
Joined: Apr 2022
Reputation:
217
Some folks are vehemently against GOTO statements. I tend to find them to be the most elegant, and simple solution in many cases.
Are you nestled 12 loops deep, within countless IF and SELECT and other branching statements, and then suddenly you find yourself done with everything that single branch of conditions can do?
GOTO Finished_Processing
Wooooo.... Now, WTF is any simpler than that to understand? It leaps you out of all those conditions/loops/branches and ... by golly, it takes you... to the beginning of processing! Actually, I would think that anyone who speaks the language could tell you exactly where that GOTO is going to take you -- to the end of the Processing code segment!
GOTO Start <-- Gee willikers, this one is hard to understand
GOTO RedoInput <--- Gosh, I'd never know where this is going to send me, or what its purpose is
GOTO PrintResults <--- Umm... I'm guessing this is where we ask for a lot of user input. Right??
The most important thing with GOTOs is that the LABEL they link to has to be descriptive, and that they don't immediately branch off some friggin place else, like some of the older BAS programs used to. NOBODY can puzzle out that spaghetti crap!
10 GOTO 20
20 GOTO 40
30 GOT0 50
40 GOTO 30
50 GOTO 60
60 ON x GOTO 10, 20, 30, 40, 50
70 GOTO 0
WTF????
Numeric labels are a FAIL with GOTO. A GOTO needs a very descriptive and unique label to help understand and state its purpose.
A GOTO should never directly lead into another GOTO. That's the stupidest thing in the world. Just have the first GOTO go directly where it needs to be, without leaping through a dozen hoops with middle men!
Gotos really aren't bad in use when coding. They're there for a simple, and powerful purpose.
They just really, REALLY, REALLY-REALLY suck bad when they're misused!
Posts: 200
Threads: 5
Joined: Apr 2022
Reputation:
22
08-10-2024, 09:41 AM
(This post was last modified: 08-10-2024, 10:01 AM by JRace.)
I DO like type identifier suffixes, at least on strings. That goes back to the 8-bit days.
I usually UPPERCASE constants. Everything else is lowercase. Years of C programming taught me that.
I will sometimes resort to CamelCase if I'm writing for someone else's eyes, but I loathe ReallyLongCamelCaseNames.
I prefer to see as much of the program on one screen/page as possible, so I tightly control vertical whitespace.
SUBs & GOSUBs have their place and time, but they force the code's reader to break concentration and look elsewhere in the program. If it's just two or three small statements used two or three times in one small part of the code then forget SUBbing them out. Keep them where they are needed.
You will often see multiple statements per line in my programs.
x = x+3
y = y+5
becomes x=x+3: y=y+5, which is MUCH more readable to me.
GOTOs:
I agree with Steve that GOTO has its uses, but I haven't touched it in years. It's usually possible to avoid using GOTO in modern languages, and I guess I consider finding ways to avoid unnecessary branching to be part of the fun of program design. The real interest for me has always been the intellectual exercise of designing the program, not the tedium of typing & deboogering.
At least modern BASIC gives us 'IF (condition) THEN statement', instead the Fortran-inspired 'IF (condition) THEN linenumber' spaghetti cooker of Dartmouth BASIC.
Posts: 2,697
Threads: 327
Joined: Apr 2022
Reputation:
217
One place I find GOTO more than acceptable is when I have a long string of things to account for, and each has an unique process.
Code: (Select All) IF Left$(user$,5) = "Steve" Then
...do stuff
GOTO end_check
END IF
IF Left$(user$,4) = "Jack" Then
...do stuff
GOTO end_check
END IF
IF Left$(user$,2) = "Jo" Then
...do stuff
GOTO end_check
END IF
...57 more unique cases to check and deal with...
end_check:
With the above, we find the first instance that handles the input we need to process, and then we skip all those other checks. If "Steve" just happens to be the first thing we check, we can skip 60 more IF checks that we know aren't going to ever process in that pass. Are there other ways to do it? Sure there are, but are any of them as simple, and easy to implement and understand, without having to wrack one's brain for how to minimize branching flows otherwise?
Posts: 276
Threads: 14
Joined: Apr 2022
Reputation:
27
I tend to be a bit undisciplined with respect to case [Pascal, camel, snake, etc.] in my code. I stick to a convention within a project, but often change that convention between projects.
I use GOSUB in much the same way that Steve does, for minor recurring bits of code within a SUB or FUNCTION. I like it for those situations where I don't want the additional headaches of variable passing or the clutter of DIM SHARED in the main module
I am not adverse to using GOTO when it is warranted, but I do tend to look for ways to avoid it in my code. I like to use it as a debugging/development tool for jumping around blocks that may not yet be fully functional. I don't need the headaches of spaghetti code, but I recognize that it is essentially a major tool of program flow close to the metal so I believe there's no reason to be up tight about it. In general, you won't find it in my code very often.
Given the above, I'm not one to use a lot of labels. If I do, it's usually for DATA block pointers for RESTORE "label" commands. I rarely read DATA without a RESTORE first.
I try to keep my command lines as short as possible and align my following ' comments at a particular tab position. I also typically use some sort of ASCII block comments to separate SUB/FUNCTION blocks. I experiment with various looks quite often.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
|