Welcome to BASIC
from the April 1986 issue of PCM
By Richard A. White
An important question these days is what is BASIC’s place in the world of microcomputing? Over the past few years the IBM PC and its compatibles have arrived, followed by a vast outpouring of software of every description. Each machine comes with a BASIC language interpreter on its DOS disk.
It is likely that only a small percentage of these interpreters have been loaded for the purpose of doing programming. A much larger percentage have been loaded for the purpose of running some existing BASIC program. This only reflects that early microcomputer owners were as interested in the machines themselves as they were in running applications, while more recent purchasers are buying machines to run applications only.
The market shift is also exemplified by the documentation supplied with the machine. When I got my first microcomputer in 1980, its manual was mainly concerned with how to program in BASIC. The Tandy 1000 comes with Desk Mate and its documentation, enough imformation on MS-DOS for the user to get Desk Mate up and running, and virtually no information on the BASICA interpreter that is on the DOS disk. Most of the thousands of folks who purchased Tandy 1000s before Christmas 1985 are probably unaware that they have BASICA on their DOS disk, or even what BASICA is for.
The role of BASIC has obviously diminished, but it is by no means a dead language. It comes with all Tandy machines and is available for developing those special applications for which software cannot be purchased. It is much easier to use for small programs to accomplish specialized tasks that cannot be done in a spreadsheet, for example, than most any other language.
Thumb through a few PCMs and you’ll see most of the programs are written in BASIC, with good reason. It is the language available to everyone. A published BASIC program is potentially usable by any PCM reader, while a program in any other language is usable by only a small percentage of the readership.
Given this situation, we feel it is useful to provide a series of columns on “Beginning BASIC Programming.” Early in PCM ’s history, I did a similar series on Model 100 BASIC. This time we will use BASICA, which comes with the Tandy 1000, 1200, 2000 and 3000. I will focus on a simple subset of the commands available and avoid detailed description of seldom-needed options.
Over the years, BASIC has been criticized by computer scientists and supporters of competing languages. Some of this criticism was justified. But BASICA for the Tandy MS-DOS machines is the result of years of refinement and is now much more powerful than any BASIC available, even five years ago, on any machine. Still, it is an interpreted language. This means BASICA must take each command it comes to in the program and look up a machine language routine to perform that command; this takes time. Borland’s Turbo PASCAL, which has sold over 400,000 copies, is BASICA’s major competitor. Its final product is machine language, where the machine language routines to perform each command are included directly in the program to be executed. This is called a compiled program and, since the computer is not continually looking things up, it is lightning fast.
However, many computer tasks do not need that speed. A data entry program is human paced, for example. And, the way the program is written can have a drastic effect on its speed. I am reminded of a friend who came to me with a program to analyze survey data. It was very slow under BASIC and he wanted a machine language version to speed things up. As I considered how to do this, it occurred to me that I could use arrays in BASIC to model how a machine language program might work. It turned out that the rewritten BASIC program was more than 10 times faster than the first version, and I never had to write a machine language version.
This paid off later. The original program was on a non-MS-DOS machine. We came to an application that was to run on an IBM PC. With minor editing, we were able to bring the BASIC programs over to the PC. If there had been a machine language module it would have needed total rewriting.
The single most valid criticism of BASIC is that it imposes no structure or discipline on the programmer. A program can be written almost any way you want. The simple can be made complex if you do not do some planning first and impose some self-discipline. PASCAL was written partly in reaction to BASIC’s total lack of inherent structure. PASCAL demands specific structuring for the program to work. All variables must be defined at the beginning of the source code or at the beginning of the procedure or function where they are used. All procedures and functions that the main procedure uses must be in front of the main procedure in the source code, or there must be instructions on how PASCAL finds the procedure. How the procedure itself must be constructed is also defined.
BASIC requires none of this. On the other hand, the more structure the programmer can bring to a BASIC program, the better. One way to do this is to develop standard subroutines and put them in standard locations in each program. For example, there are many times when it is handy to get a single character from the keyboard, which may be the starting letter of a menu choice. The program then branches according to what the letter is. The computer may be in lowercase or uppercase. It simplifies the code if it needs to look for only a lowercase or uppercase character, but not both.
The subroutine listed here loops until it gets a character. It checks if the character is lowercase, ASC (I$)>96
. If so, 32 is subtracted from the ASCII value of the character and the resulting number is converted back to character form with I$=CHR$(ASC(I$)-32)
. The program returns to the line that called the subrouting. If the character is not lowercase, no conversion is made and the return is made immediately.
l I$=INKEY$:IF I$=""" THEN 1
ELSE:IF ASC(I$)>96 THEN
IS=CHR$(ASC(IS)-32):RETURN
ELSE RETURN
In this bit of program, or code, the computer gets a user input from the keyboard, tests it, and causes a conversion to be made if the test proves true. True or false, control is returned to the line called the subroutine. Not bad for one line of code. It even makes sense when divided into little pieces. Perhaps the secret to programming is to “divide and conquer.”
Perhaps? Nay, it’s a certainty. If you think of the programs as functional little pieces, you will do a lot better. PASCAL was also written for use in teaching programmers to structure their programs. In fact, you cannot write in PASCAL without adhering to strict structural rules. In BASIC you have a choice of writting free-spirited spaghetti-like programs or relatively structured ones. Reading a “spaghetti” program is like trying to read an upside-down road map in the light of a new moon at midnight. New programmers seldom know where they are going with a program and halfway through may get bogged down figuring where they’ve already been as well. Such is part of the learning process, so don’t lose heart.
Program structure means program organization. Most languages require that variables, files, data structures and other attributes be declared at the beginning. Generous use of remarks is encouraged and specific indentation formats are strongly suggested. Structuring also deals with what should be in subroutines, what should be in the main procedure and how the procedures flow. Much of this is optional in BASIC; some is just good practice in any language.
Clarity should be as important a goal in BASIC as it is in other languages. There are a number of ways to write clear programs. I use the following procedures and find them valuable.
-
Define specific program functions and put the code for each function in its own module with introductory REMs. Assign a specific set of lines to a module. Blocks of 100 lines are convenient and will meet most needs. You will always know a module begins at an even hundred and can go right to the one you want.
-
Minimize looping back. The procedure should flow from start to end and loop only to repeat the routine or a portion of it.
-
Use
IF...THEN...ELSE
to minimize jumping forward. Many times all the code for the choices can be contained after THEN and ELSE on one line so the procedure can continue on the next line. TheINKEY$
example clearly demonstrates this. Some BASICS don’t have ELSE. Apple doesn’t and Apple owners pay extra for its lack. To illustrate, which is clearer to you?
10 IF X=0 THEN PRINT “FALSE” :X
=1 ELSE PRINT “TRUE”
20 END
or
10 IF X=O THEN 30
20 PRINT "TRUE:" GOTO40
30 PRINT “FALSE” :X=1
40 END
- Put all subroutines in one of two places. Frequently called subroutines, which include those that affect program speed, should be at the front of the program. I reserve lines 1 to 99 for these. These should not be more than three or four lines long. Line-number spacing of two is good. Putting these here serves two functions. First, the computer finds them quickly when speed counts. You also save bytes since the number in the
GOSUB
is only one or two bytes long.
Infrequently called routines, particularly program initialization code, should be at the end of the program. Each time a subroutine is called or the computer is sent to a specific line, it starts at the beginning of the program and searches until it finds that line. The fewer lines it passes to find the needed line, the faster the search will be. It follows that speed is compromised if the computer is continually searching over code it has used and will not use again. Clarity comes from having only two places to look for subroutines.
The one exception I make is to place a major subroutine at the end of the module that calls it when only that module uses it.
-
The same reasoning just explained also applies to the ordering of main program modules, provided they are called separately. Those used most frequently are put in front of the occasionally used ones. Ina file program, the input module is used far more than the save-to-disk module and should come to the front. Modules that are used in order should be placed in order in the program.
-
Menus should be placed where they are used in the program. A menu’s text provides valuable information on the branching of the program that follows. If menu choices are numbered from one up in sequence, the the
ON I GOTO
xxx,yyy,zzz orON I GOSUB
xxx,yyy,zzz commands can be used. It is easy to read a listing, see which number corresponds to the code block you want, drop down to theON I...
statement and count across to find the target line number.
Though I have discussed program structuring for purposes of easy trouble-shooting and modification, the structure proposed has program speed firmly in mind as well. Memory use is another consideration. Clarity, memory and speed are like three corners of a triangle — you cannot be at all three points at once. However, choices can be made that shorten the sides of the triangle to get you closer to where you want to be. It takes careful thought and planning at the start so you don’t end up redoing too much.
The advent of cheap memory has distorted the triangle in recent years. There is no longer such a premium placed on memory conservation. Unfortunately, the relaxation of this discipline has led to sloppy programming and large programs that are slow and sometimes buggy. Small is still good.
Don’t be upset when you don’t get what you want the first or second time. Remember, all good commercial programs have version numbers and Version 1.0 is the first one offered for sale, not the first one of the development process. [PCM]
Richard White has a long background with microcomputers and specializes in BASIC programming. He has authored numerous programs and articles. His work has also appeared in PCM’s sister publication, THE RAINBOW.