Reprinted with permission from the Liberty BASIC Yahoo Group, March 9, 2003 In response to a discussion about program structure, Foon (Larry Crimmins) shared the following explanation.
The MAINLINE and Structured Programming
Just to add a little bit (no binary pun intended):
Traditionally (and there IS value in some programming traditions), you never use a GOTO in a high-level language, like any but the most elementary BASICs. It's considered a sign of sloppy coding. There is always a way to recode to avoid them. One of the most helpful things to learn is how to format your code so as to enforce and constantly remind you (and anyone who may later edit your code) not to jump out of structured blocks of code by a backdoor. It's also helpful to get a few common terms for parts of programs burned into your cortex.
In any program, there is, conceptually and literally, a "MAINLINE". This is the primary block of code which runs the damned thing. ;) Depending upon the interpreter or compiler, the mainline may, technically, include SUBROUTINES and/or FUNCTIONS; these may differ however in which variables they may inherit from the mainline. The mainline does NOT typically include SUBPROGRAMS ("SUBs"), or "chained code" or other "MODULES" (if allowed).
A GOSUB leads to a "SUBROUTINE". Subroutines should be considered separate entities, even though they are technically part of the mainline since they inherit all "MAINLINE" variables. Subroutines end with (are exited via) a "RETURN" statement. "GOTO"s may be used within a subroutine, but never to exit it.
Note that there is a negative effect on optimization when labels are used indiscriminately: when a compiler is trying to compact and optimize code, and it finds a label in the middle of a block it could otherwise replace with faster and smaller code, it MUST preserve the label and separate the block into two parts (around the label), thereby limiting the optimization which can be done. Picture this happening in a program with a "line label" before each line! This is a severe impediment to optimization. Because of this, programmers should learn to use labels only when absolutely necessary.
A "CALL" generally leads to a "SUBPROGRAM". These are blocks of code which typically only inherit explicitly shared variables and passed variables/values. In most BASICs, these end with an "END SUB". Never try to exit a subprogram except by falling through to the END SUB (or encountering (if allowed) a conditional END SUB within the subprogram - still considered sloppy programming). A subprogram might only be called once during execution, but is encapsulated due to its unique handling of certain variables, files, or algorithms. This is done typically for reuse (with little or no change) in other programs.
"FUNCTIONS" are used in many different ways depending on the interpreter or compiler. Generally however, they inherit all mainline variables, and are merely called implicitly by name rather than via a CALL statement. Functions are generally small blocks of code which fulfill a.. er... function... (returning a value into an algorithm)... which is needed repetitively through the program. If you only need it once, then just "embed" the code where it's needed. The exception is with a particularly valuable function which you are reusing from another program, although even then it could be embedded. Never exit a function except via its logical end point; perhaps an END FUNCTION statement, which, like END SUB, can be in multiple places in the function (sloppy programming again).
Editor's note: In Liberty BASIC, Functions do not inherit all mainline variables. Except for certain reserved variables that are visible in all parts of the program, variables used within functions are local to the function.
"MODULES" are separate files containing a subprogram or a function, and perhaps some variable declarations and sharing statements. They are "CHAIN"ed (or, loaded during runtime). Liberty BASIC doesn't currently support multi-module programming, I don't believe. But just to get the terminology straight, in case you run into it again, the module containing the "mainline" is generally called the "ROOT" or "ROOT MODULE".
When dealing with "modules", just think of them as "overlaid segments" of code. These are just blocks of code from files which overlay a portion of memory (during execution) to make the most efficient use of memory space. When an overlay replaces the mainline, rather than some other memory block, it's called a "ROOT OVERLAY". (Sounds like we're getting into dentistry, huh? :) These days, however, it's not likely that the typical LB user will frequently encounter such practices, since memory is used in such a profligate and wasteful manner. Nevertheless, it's useful to know that a "good program" cleans up reserved memory behind itself and doesn't sloppily leave code or data blocks scattered all over the place. heh
Another $0.02 from,
Reprinted with permission from the Liberty BASIC Yahoo Group, April 6, 2003 In response to a discussion about manging the printer, Foon (Larry Crimmins) shared the following explanation.
COMMUNICATING WITH THE PRINTER
Just a general comment about dealing with devices (and logical devices) especially printers:
When you have a possible hardware glitch (ESPECIALLY printer related) in a particular app or compiler, try to do a simplified version of the same thing from DOS. Yes, I said *DOS*, remember that? (It gives the informed user much greater control than an obfuscatory OS like Windoze. ;) If you can "copy con (DeviceLabel)" (prn or lpt1: or lpt2: or whatever), and you can type ctrl-chars, like ^L (chr$(12)), then you can use this feature of the copy command to send raw data to a device. Always end with a ^Z, of course.
If you have no idea what I'm talking about, drop to DOS (duh! get a command line), and type "copy /?". That will give you the syntax of the "copy con" command among all other copy parms. Everything you type, including control chars will be sent to whatever you specify as the device. This could also be a filename. But not much will happen until you end the lines of text and embedded ctrl-chars with a ^Z (control-Z) (chr$(26)).
Also, if a supported printer command works in one compiler (or interpreter) and not in another, make sure that the printer has been properly and completely installed for both languages. I know that, in Windoze, people tend to take for granted that a printer, once installed in Windoze, will work the same in all applications. Not necessarily. Some apps, especially compilers or word processors, really need the device to be specified *in great detail* in their own options settings. Just make sure you've done this to the fullness of whatever the application will allow (advanced settings, etc). Else, you might find one app using the printer correctly and another using it in a very clunky manner. heh ;)
Here's a quick and dirty example: Perhaps the version of QuickBasic you're using is old enough to DEFAULT to a continuous-feed (i.e. fan-fold) paper source, rather than the awkward cut-sheet feed that modern printers use. In that case, the application of a FF (Form-Feed) ^L (chr$(12)) character will behave differently, depending on how the printer is set up. Y'see, a form-feed, in continuous-feed paper days, meant to go to the end of the *defined* page-length minus the number of lines printed so far, and accounting for any header or footer lines. This is *a bit* different from how it's handled on a cut-sheet feeder like modern printers.
All I'm saying is that you need to verify *every single possible* variable when you're dealing with a printer from different sources (applications) if you expect similar results. Printer setups should be considered an art form, IMHO. hahahah
Sorry to be so terse here, but it's getting late for me and I'm just trying to throw in a potentially helpful comment. :)
Luck and stuff,