CHAPTER ONE: INTRODUCTION
©1982, John E. Miller
This means you can read it but not save soft copies or publish in any form
or re-distribute without my permission. Thanks, John
The History section traces the development of programming and
operating systems.
The BASIC Commands section introduces a working set of BASIC
commands: NEW, DEL, LIST, RUN, SAVE, OLD, RENAME, and BYE.
The BASIC Statements section introduces eight simplified BASIC
statements: INPUT, LET, PRINT, GOTO, IF, FOR, NEXT, and END.
This will be sufficient to write programs in Chapters Two, Three, and
Four.
The eight statements are then covered in detail in Chapters Five and
Six.
The BASIC Syntax section shows how what was described by specific
examples in the BASIC command and statement sections can be
summarized graphically.
These type of diagrams are then used throughout the book to describe
the form of BASIC expressions and statements.
History
The history of computation goes back at least to the Babylonians.
The history of mechanical computation started, however, in 1642 with
a young man, Blaise Pascal (Figure 1-1), who invented the first
adding machine (Figure 1-2) to relieve the burden of computation of
his father's accounting work.
Before the year 1800, children were employed in textile mill weaving
processes to monotonously push levers which lifted combinations of
threads to form patterns in the fabric.
In 1804 Joseph Marie Jacquard (Figure 1-3), once himself a drawboy,
invented an automatic loom (Figure 1-4) that wove patterns according
to a series of prepared cards strung together on a belted conveyance.
The loom could read each card by mechanically sensing the presence of
a hole or no-hole corresponding to each warp thread.
The selected threads would be raised and the shuttle run across.
Then the next card on the belt was positioned, etc.
This way, complex patterns could be mass produced without assistance.
The operator merely selected the pattern and set up the loom.
This is now considered a significant step in the development of automatically
controlled calculation.
Around 1822, an Englishman, Charles Babbage worked fanatically to
build his 'analytical engine', a machine that could perform sequences
of operations under automatic (programmed) control like the Jacquard
loom.
His design included a 'store' for holding both the data and
intermediate results of computations, and a 'mill', for performing
the instructions as read from the cards.
Babbage's cohort, Ada Augusta (Figure 1-5) helped by deducing that
his machine would need not only arithmetic operations, but also an
instruction that could skip over succeeding instructions or go back
to a preceding instruction according to the negative, zero, or
positive result of the last operation performed.
Babbage never succeeded in building his engine, however, due to lack
of funding and his inability to freeze the design (Figure 1-6) so
that his millwright could go to work.
Rather, he pursued design after design for each component of the
machine, seeking simplicity.
After his death, his son and Munro Company constructed a working
model from his plans.
Babbage's original motivation was to improve the accuracy of
tables of logarithms. World War II intensified the demand
for performing complex mathematical calculations for preparing
ballistics tables.
Several groups worked to design a machine that could store the
instructions in the same memory as was used previously only for data.
This design idea is referred to as the 'stored program' concept.
(It is not clear that any one person should receive credit for this
concept).
Memory was designed to consist of a series of numbered locations or
'addresses', so that the machine could progress from one to the next
for its instructions just as the Jacquard loom read pattern cards.
As Ada Augusta had written, the program could choose to skip over
certain instructions, or go back and repeat a set of instructions
based on some condition that arose during the actual computation.
The first stored program machine, EDSAC, became operational in 1949
at Cambridge University in England.
A program consisted of a list of numbers to be stored in the
machine's memory in contiguous (sequential) locations.
The machine would interpret part of the number as an 'operation code'
and the other part as an 'operand'.
An operand would be either an 'address' of data to be used in the
operation, or the data itself.
For example, operation code #1 might mean to add the contents of a specified
memory cell to the totalling register; operation code #2 might mean to store
the contents of the totalling register in a specified memory cell.
Operation code #3 might be to load the totalling register with a
particular number contained in the second half of the instruction.
A program, then, would look something like:
OPCODE | OPERAND
-------|---------
3 | 0
1 | 1728
1 | 1729
2 | 1730
The above hypothetical program zeros the accumulating register, adds
the numbers in memory locations 1728 and 1729 into it, and then
stores the result in memory location 1730.
Each of the early designs had its own way of doing this, a different
set of operation codes, a different way of addressing memory.
The name given to this program specification/coding scheme was
'machine language'.
Machine language programs were very tedious to prepare and even worse
to modify.
Therefore, A program was written with 'mnemonic' (memory aiding)
codes rather than numeric operation codes and addresses.
Each operation code had a unique mnemonic, and each memory location
was given a symbolic name (like "A" or "Q").
The above machine language program might have looked like the
following on some engineer's note pad in 1949:
MNEMONIC | SYMBOLIC
OP CODE | OPERAND
---------|---------
ZAP |
ADD | A
ADD | B
STO | C
These symbolic programs were turned over to clerks whose job it was
to assemble a machine language program and to load it into the
memory of the computer by flipping an absurd number of switches, etc.
This clerical process was soon seen to be mechanical in its own way.
Thus, the first significant development in programming languages was
the invention of programs for the translation from assembly
(symbolic) language to machine language.
This meant that the clerical translation could be done by the
computer itself.
Since the computer could store numbers into its own memory, it could
also load the program!
This was a revolutionary idea.
A program that reads assembly language instructions and produces
machine language instructions for a particular computer is yet today
called an 'assembler'.
While assembly language programming was a great improvement over
machine language, a programmer was still spending more time writing
instructions for the computer than solving the problem at hand; the
little program above simply makes C take on the value of A plus B.
In practice, a programmer would first write an expression
algebraically (C=A+B), then write a sequence of assembly instructions
to perform the required operations.
A hierarchy of programmers was formed, the upper level programmers
were mathematicians writing algebraic expressions, while the lower
level workers wrote the corresponding assembly programs.
(A person who did such translations was called a 'compiler').
The assembly language written by the compilers could then be
assembled by the computer.
As before, it was soon realized that the translation from an
algebraic expression to assembly instructions, no matter how complex,
was mechanical.
A program was written that could read an algebraic expression as its
input and produce the sequence of assembly instructions required to
evaluate the expression as its output.
People no longer needed to compile programs.
This new type of translating program became known as a 'compiler'.
While an assembler produces only one machine language instruction for
each assembly instruction, a compiler will produce several
instructions for each expression in the original 'source program'.
This many-to-one translation was extended to include 'statements' for
inputting and printing data, as well as for altering the sequential
execution of the program.
The important idea is that the effect of the machine language
program, when executed, is the same as the effect expected by the
higher-level language programmer.
A goal of the pioneers in this area was that, for each kind of computer,
a compiler could be
written that would translate a
general language into that machine's language.
It was hoped that the same high-level program could be used on
any machine with the same results.
The degree to which this goal has been realized is beyond the scope
of this story, but it continues to be a driving force in language
design today.
The next significant development does not relate directly to language
development, but to the general operation of a computer 'system'.
Consider the steps originally necessary to develop a program.
Each statement of the program was punched onto a hollerith card.
The compiler program, which was also stored on cards or paper tape in
machine language form, was loaded into the computer's memory followed
by the program to be compiled.
If the compiler discovered typographic errors (mismatched
parentheses, misspelled keywords, etc.) it would reject the source
program and not produce the 'object program' (machine language).
The source program would be corrected and the compiler re-loaded for
another try.
If the compilation was successful, the object program would be
punched onto cards or paper tape; then the operator would load the
object program for testing, which would disclose various errors in
either the computation technique, or the displaying of the results.
This entire process would be laboriously repeated until the program
was 'debugged'.
The compiler deck or tape was literally worn out due to its incessant
reuse.
A development in computer hardware presented a solution to this
madness.
A new medium, magnetic disks and tapes, provided a residence for
frequently-used programs as well as for data.
A compiler could be summoned from the rapidly spinning disk whenever
needed, and as frequently as needed without concern for wearing it
out.
The object program could be stored on the disk temporarily until
testing was completed, then it could be punched out for 'off-line'
storage.
Other useful programs and
small data files were stored on disks and tapes.
Thus, the first program 'libraries' were formed.
To help in controlling the computer, yet another program was written
solely for the purpose of accepting commands from the operator and
fetching a particular 'system program' for use.
Such programs were given names like 'monitor', 'supervisor', or 'host
operating system'.
All library programs ran from the system relinquished control of the
computer to the supervisory program when they completed their task.
The primary input device of the day was a card reader.
A job consisted of a deck of cards containing sequences of commands,
programs, and/or data representing one user's request.
The system would do one job, then go on to the next deck of cards in
the card reader.
Such systems are called 'batch' systems.
As disk technology improved,
the capacities of disk drives grew.
Operating systems were expanded to provide librarian
service for storing object programs on disks and tapes.
This made the work of developing programs and systems of programs
much easier in addition to increasing the
potential workload of operational
systems.
In time, the speed of newer generation computers became so great that
the computer sat idle a great portion of the time while it waited for
its input and output devices, which are limited by mechanical
inertia.
To make use of this time and to make the computer directly available
to a greater number of users, the design of computers was extended to
allow for 'partitioning' of its memory so that it could work on
several programs concurrently (not simultaneously).
Each user would communicate via a 'terminal' having a 'keyboard' and
'display'.
The operating system became a 'timesharing' system, meaning that the
supervisor would give each process a tiny 'slice' of time say
one-hundreth of a second.
Since the computer could do tens of thousands of instructions during
that time, each user has the illusion that the computer is working
solely for them, while in fact it is handling all of their requests.
The performance of the system as a whole is maintained by a priority
system which prevents any user from hogging time.
If a request is made for more computation that can be completed in
one slice, the work is spread out over a number of slices.
The 'response time' will become greater if many users all make
substantial requests, overloading the system.
Otherwise, individuals are not aware that they are sharing the
computing resource.
One of the pioneering institutions in timesharing was Dartmouth
College.
There, BASIC (Beginner's All-purpose Symbolic Instruction Code) was
designed to take advantage of this new user-machine relationship by
providing an interactive way to write and test programs.
With it, a programmer can experiment with increasingly complex
versions of a program.
BASIC provides a line-by-line program 'editor' so that a programmer
can easily change any statement in the program at any time.
The BASIC editor checks each statement for grammatic correctness.
This way, the programmer gets immediate feedback, rather than having
to wait till run-time to find out that some trivial typographic error
was made.
BASIC is intentionally simple so that students and teachers can learn
the fundamentals of programming without being bogged down by the
details of more a sophisticated language.
Another innovation of BASIC is that it does not translate a program
into machine language, but rather 'interprets' its source code
directly.
When BASIC interprets LET C=A+B, the current value of "A" is added
with the current value of "B" and the result is stored in "C".
This is the effect that we expect without generating machine language
instructions for the computer to execute.
BASIC can begin interpreting a program immediately upon request,
whereas a program in another language may need several seconds or
minutes to be compiled before execution.
A program written in an interpreted language will run slower than the
same program written in a compiled language.
An interpreter is a computer program itself which stands between the
machine and the program, whereas a compiled program is executed
directly by the circuitry of the machine.
But BASIC programs tend to be smaller and do simpler computations
than industrial or commercial application programs.
BASIC was invented primarily for students, who change their program
many times before getting it correct.
In such an environment, interpretation is less time-expensive than
compilation.
BASIC handles the fetching and storing of source programs so that a
user does not have to learn the in's and out's of a 'host' operating
system.
In this sense, BASIC is a sub-operating system which is somewhat
standard from one machine to the next.
In the 70's, the micro-electronic revolution reduced the cost of a
computer to a level that each user could have a personal computer.
Although BASIC was designed in a time-sharing environment, it was
also a good candidate for a programming language for the
micro-computer, because of its simplicity.
BASIC is now used both on large time-share systems and on home
computers.
Summary: If necessity was ever the mother of invention, programming
languages are surely among her children.
The evolution of programming and operating systems has been one of
shedding the burden of tedious human tasks.
BASIC Commands
Before using BASIC on a time-sharing system you must identify
yourself and enter your assigned password.
If you have a personal computer, you simply need to turn it on and
load the supervisory program.
Each host operating system has a way to specify that you want to use
the BASIC subsystem, usually typing "BASIC" followed by the RETURN or
ENTER key.
Once under control of BASIC (referred to as "Being in BASIC"), you
will be aware of two distinct states or modes.
One state is for creating a program, the other is for running a
program.
When you first get into BASIC, your 'workspace' is empty.
(The workspace is an area of the computer's memory reserved for the
text of one source program).
The first thing you will do is to tell BASIC whether you wish to
create a new program or to recall a previously written one.
To create a new program, type "NEW", followed by the name that you
wish to give the program, for example:
NEW adder
Every command you give is followed by the RETURN key.
BASIC does nothing till the RETURN key is depressed.
This allows you to rub out a typographic error on the line you are
entering before hitting RETURN.
A new program is entered into the workspace by typing it line by
line.
Each line must have a line number that gives its
placement in the program.
A programmer usually starts a BASIC program with line 10 or 100, and
numbers the lines of the program by 10's:
10 REM This program adds two numbers
20 INPUT A,B
30 LET C = A + B
40 PRINT C
50 END
Leaving unused line-numbers allows afterthoughts, omissions, and
changes to be inserted between previously entered lines:
35 PRINT "The sum is:"
This presents a potential hazard.
If you accidentally type the wrong line-number, the statement entered
may overlay some other statement or be inserted at the wrong place in
the program.
No warning can be given, since this is BASIC's way of letting you
change your program.
You are the boss.
It will obey you blindly, so be careful!
Similarly, a line may be deleted by simply typing just the line
number itself, or by explicitly typing "DEL" followed on the same
line with the line number of the line to be deleted:
DEL 35
A segment of the workspace may be deleted.
For example, "DEL 10-30" deletes lines 10 through 30, however many
lines that may be.
A line may be corrected or changed by simply retyping it, and BASIC
will see to it that the new line overlays the old.
The contents of the workspace may be reviewed at any time with the
LIST command.
"LIST", followed by the RETURN key, will list all the lines of the
workspace.
The list may be limited to a portion of the program by saying
"LIST m-n", where m and n are the first and last lines to be listed.
Many systems put the date and the time on the listing.
This dates a particular listing generated on a printing terminal so
that successive listings may be arranged in the order they were made.
LIST
ADDER 13-SEP-1981 4:21
10 REM This program adds two numbers
20 INPUT A,B
30 LET C = A + B
40 PRINT C
50 END
Ready
To have the program interpreted you type "RUN" and watch what
happens:
ADDER 12-DEC-1981 5:52
?
BASIC displays its characteristic time-date-workspace-name heading
and the program commences.
The INPUT statement on line 20 causes the "?" to appear.
Now, you enter two numbers and hit RETURN:
? 2,2
4
Ready
The INPUT Statement accepted two numbers from the keyboard.
The LET statement added the two numbers.
The PRINT statement sent the result to the display.
The END statement sent control back to you, indicated by the "Ready"
sent to the display.
When you are satisfied with a program you may keep it for another
time by saying "SAVE".
The workspace will still contain the program, but BASIC will have
made a copy of it in your 'filespace'.
Your filespace may contain an indefinite number of programs, while
the workspace contains only one at a time.
You may clear the workspace for another program by saying "NEW", or
you may recall some other program from your filespace by saying
"OLD".
In either case, the command is followed by the name of the program
you want to create or recall.
If you attempt to call up and old program, BASIC will check a
directory (list of file names) for the program and load the program
into the workspace.
If it fails to find the program, you will be informed.
(Most BASIC's do not provide a way to list the names of all the
programs in your filespace, rather this is a service provided by your
operating system.
Consult your system's user's guide).
The workspace may then be LISTed, modified by inserting or deleting
lines, and/or RUN.
"REPLACE" (REP for short) commands BASIC to file the modified
contents of the workspace as the most recent version of the program
in the filespace.
A program in the file space may be UNSAVEd on some BASICs, while on
other systems you must delete or purge the files with an operating
system command.
Managing different versions of a program may be necessary during its
development.
You may create another program from an old one by renaming the
workspace and saving the program under the new name, just as if you
had typed the whole thing from scratch!
The following example calls up a copy of ADDER, changes three lines
of the program, names it MEAN, and saves the program under the new
name.
OLD adder
Ready
10 REM arithmetic mean of two numbers
20 INPUT A,B
30 LET C = (A+B)/2
35 PRINT "The mean is"
RENAME mean
Ready
SAVE
Ready
This feature can be very useful when testing a program or when making
variations on a theme.
ADDER is left unchanged by this process.
The name of a program has no effect on it, but it should be
meaningful so that you can remember it easily.
To leave BASIC, simply type "EXIT" or "BYE"; and you will find
yourself back at the operating system level.
Summary: BASIC provides an interactive computing environment.
The general pattern of this interaction is:
- Summon BASIC
- Say NEW or OLD
- Edit the workspace
- RUN the program for testing purposes
- If you are not satisfied, go back to step 3.
- SAVE the workspace
- Say BYE or go back to step 2.
In Chapter Six, we will see that the above could be characterized as
a "Repeat Until Satisfied" process.
BASIC Statements
First let's state the things about BASIC statements that were
implicitly suggested in the previous section:
INPUT accepts a number from the keyboard, converts it into a value
and stores the value in the memory cell represented by the name of
the variable in the INPUT statement.
The INPUT statement displays a "?" and waits for a number and the
RETURN key.
We shall see that the INPUT statement can also accept alphabetic
data.
PRINT converts the value of the variable named in the PRINT statement
into a base ten number and displays it.
The PRINT statement may also be used to display messages and
alphabetic type data.
(BASIC was invented before video terminals were commonplace.
Perhaps DISPLAY or OUTPUT would be a better key word today, but such
a change would have to be agreed upon by a standards committee).
LET evaluates an 'arithmetic expression' and assigns the resulting
value to the variable on the left of the "=" sign.
The LET statement is more restrictive than the algebraic equation you
may have studied in mathematics.
The LET statement is always a single variable, then an equal sign,
then either a number, or a variable, or an expression involving
several variables.
Remember, there is always just one variable on the left of the equal
sign.
It is not a statement of equality, but a command to change the value
of a variable to the value of the expression at the time the LET
occurs in the context of the program.
The full implication of this will become more apparent as we see how
useful this can be.
END is always the last statement of the program.
There can be only one END in a program and it will have the highest
line number.
The END statement transfers control from the current program to the
BASIC command monitor.
The program is, effectively, terminated and you are given a 'Ready'
prompt for your next command.
REM annotates the program listing.
It is used in a program to embed remarks which may be helpful to the
programmer and others.
Variables are names used to represent the value stored in a cell of
memory.
The value of a variable may be changed by a program instruction.
Its current value may be used in an expression at any time.
Operators must be explicitly written in the arithmetic expressions.
The symbols used are shown in Figure 1-9.
Parentheses may be used to form 'sub-expressions' which are to be
evaluated before performing other operations in the whole expression.
The above concepts work together to form programs.
Consider as our first such example a program to convert Fahrenheit to
Celsius:
NEW CELSIUS
Ready
10 INPUT F
20 LET C = 5*(F-32)/9
30 PRINT C
40 END
RUN
CELSIUS 3-SEP-1981 1:45
? 70
21.1111
Ready
This program was written primarily to demonstrate the use of
parentheses, as in the program to average two numbers.
Let's run it for a different reason:
RUN
CELSIUS 23-NOV-1981 3:38
? 100,000,000
37.7778
This time it appears that we tried to convert one-hundred million
degrees Fahrenheit into Celsius but got only 37.7778 degrees rather
than 37,777,778.
The problem is that a comma is used to separate numbers in BASIC
input.
A number can never contain a comma.
Unfortunately, most BASICs let a mistake like the above go unnoticed,
so be careful.
Now let's consider the program on its own merit.
If someone else RAN it without LISTing it, s/he would not know
whether the program converts from F to C or C to F.
This is remedied by displaying a 'prompt' before the input is
solicited:
5 PRINT "Enter degrees Fahrenheit"
RUN
CELSIUS 3-SEP-1981 1:48
Enter degrees Fahrenheit
? 32
0
Ready
(Your BASIC may use literal apostrophes rather than quote marks to
enclose a string.) The program could produce a sentence of like "32
degrees Fahrenheit would be 0 degrees Celsius", but we shall defer
such till Chapter 5.
This next example illustrates the reason the "=" in the LET statement
is called the "assignment operator".
Line 10 takes the constant value 1 and defines the value of variable I.
Line 30 could be pronounced: "Form the value of I+1 and store the
result back in I".
The effect of this is to 'increment' "I" by one.
The GOTO 20 statement sends control back to the statement on line 20.
NEW COUNTING
Ready
10 LET I = 1
20 PRINT I
30 LET I = I + 1
40 GOTO 20
50 END
RUN
COUNTING 3-SEP-1981 8:14
1
2
3
4
... (forever!)
The program continually goes back to line 20.
There is nothing to stop it.
The END on line 50 will never be reached because of this 'closed
loop'.
You will have to interrupt the program from the keyboard by typing
CTRL-C, or using the BREAK button, or some other button(s) germane to
your system.
(When a sample program in this book was interrupted, the message
"PROGRAM INTERUPTUS!" appears at the end of the RUN).
THIS IS NOT GOOD PROGRAMMING PRACTICE IN GENERAL AND IS DONE HERE
TO KEEP SOME ILUSTRATIVE PROGRAMS SIMPLER.
A PROGRAM WHICH IS TO BE USED BY OTHERS SHOULD NEVER END THIS WAY...
A GOTO is an 'unconditional branch'.
To open the loop, a conditional statement can be used in place of the
GOTO:
40 IF I < 100 THEN 20
If the condition "I < 100" is true, the branch will be performed.
The COUNTING program will now count only to 100 when run.
The less-than sign, "<", is called a relational operator.
Other relational operators include ">" and "=".
There is never any confusion between the assignment operator "=" and
the relational operator "=" because they are used in different
contexts.
The variable "I" in COUNTING served as a 'counter'.
The same principle can be employed to 'accumulate' a sum of numbers:
NEW SUMMING
Ready
10 LET S = 0
20 INPUT X
30 LET S = S + X
40 PRINT S
50 GOTO 20
RUN
SUMMING 3-SEP-1981 5:08
? 17
17
? 15
32
? 19
51
? -51
0
... (forever!)
The above program contains another closed loop.
One way to terminate the loop would be to test the input value:
25 IF X = 0 THEN 60
60 PRINT S
DEL 40
RUN
SUMMING 3-SEP-1981 5:11
? 99
? 101
? 5
? 0
205
Ready
Now, SUMMING quietly accepts numbers until a zero is input, then it
displays the total.
SUMMING is, effectively, an adding machine!
Now consider a rewrite of the COUNTING program using two new
statements, FOR and NEXT, to control the loop:
NEW COUNTING
Ready
10 FOR I = 1 TO 5
20 PRINT I
30 NEXT I
40 END
RUN
COUNTING 3-SEP-1981 8:32
1
2
3
4
5
Ready
"PRINT I" was sandwiched between the FOR and NEXT statements to
repeat it five times.
The variable used in the FOR/NEXT statements is available for
reference within the loop.
This sample program simply prints it out as the loop happens.
This version of COUNTING is more aesthetically pleasing and more
readable than our original.
The PRINT statement was indented slightly to help show that it is
between the FOR and NEXT.
The indentation does not affect the meaning of the statement, it just
helps us when reading the program in the future.
Some versions of BASIC do not preserve indentation, in which case it is
pointless to put it in.
Any number of statements may be sandwiched between the FOR and NEXT.
The statements so sandwiched are said to be the 'body of the loop'.
As an example, consider the following program that produces a
conversion table for Celsius and Fahrenheit:
NEW FAHR
Ready
10 FOR C = 0 TO 100
20 LET F = 9*C/5 + 32
30 PRINT C,F
40 NEXT C
50 END
Run the above on your computer and see what it does!
Exercises:
- Compute the sum of the numbers from 1 to 100.
- Compute the product of the numbers from one to thirty.
- Write a program that will sum the numbers from M to N.
- Write a program that will form the product of the numbers from M to N.
- Write a program that will produce the sequence: 1, 2, 3, 5, 8, 13, 21,...
where each number is the sum of the two previous numbers.
Have the program INPUT two numbers to start the sequence.
Writing a Simple Program
{REWORD}
At this point you may want to begin your detailed study of BASIC with
the next section.
On the other hand, you may want to follow this story of how a
non-trivial program can be written using the few statements just
introduced.
When the author was a young boy, a bank was built one block from his
home.
When the bank opened, he opened a savings account with the
encouragement of his parents.
When he went to the bank to make his second deposit, the teller took
his passbook away for a seemingly long time and returned to accept
his deposit.
Upon looking at his new balance, he found that it was more than the
total of his two deposits and that an entry had been made for
something called "interest".
The young boy appreciated the interest the bank paid him, especially
since he forgot about the money for months at a time, but he did not
understand anyone's explanations of why the bank did this.
A genuine explanation of why a bank does this is another story.
However, the principle at work is quite appropriate: How did the
teller compute the interest?
Interest for one period (a year, quarter or month) is computed on the
current balance of an account, and that interest is added to the
account balance.
Then the interest for the next period is computed.
Since the balance has grown, the interest will be even more even
though no new money has been deposited!
The balance will grow at an increasing rate!
This phenomenon is called "compound interest".
In the 1950's this evidently took a great deal of time for bank
tellers to compute, so let's construct a program to compute the
compound interest for a given balance, interest rate, and number of
periods.
To begin, we name the workspace:
NEW bank
The program needs to have the balance of the account, which we shall
call "P", for "principal":
10 INPUT P
Note that "B" would work just as well, but the symbol "P" has been
used traditionally for this purpose.
Next, the program needs the interest rate:
20 INPUT I
Finally, we input the number of periods to be compounded:
30 INPUT N
Note that the interest rate is for one of the periods.
If the interest is compounded monthly, then the interest rate should
be the monthly interest rate.
Also note that the order chosen to input the numbers is arbitrary and
that to make the program useable by a stranger, the inputs should be
prompted.
Next, we need to compute the amount of interest for one period from
the current balance and the interest rate:
40 LET Q = P * I
Then we need to add the interest to the balance of the account:
50 LET P = P + Q
and subtract one from the number of periods passed:
60 LET N = N - 1
Then, if N is greater than zero, we repeat the above process to
compound the interest:
70 IF N > 0 THEN 40
When the number of periods are exhausted (N is zero), the IF does not
branch back to line 40, rather, the program continues on to line 80
where the balance is displayed:
80 PRINT P
After the PRINT comes the END of the program:
90 END
We have written a program that looks like it will do what we set out
to do so we say RUN and give it some input:
RUN
BANK 3-SEP-1981 9:01
? 100
? 0.04
? 10
148.024
The displayed number means that if $100 is deposited at 4% for ten
periods, the balance will be $148.024.
The bank will round off the four tenths of a cent, of course.
This also shows why one must be careful in making computations with
money since this rounding would (probably) be done each time the
interest is compounded, rather than just at the end.
Many BASIC programmers neglect this.
In the "real world" much more attention is given to the accuracy of
computation than is usually suggested in an introductory course.
For now, please accept the fact that more sophisticated arithmetic is
necessary in actual business applications where every penny must be
preserved (accounted for).
As you will see, appropriate measures can be taken to insure any
practical level of accuracy.
Let's go back to our computation of the new balance.
It was computed in two steps, first the amount of interest, then the
new balance.
The use of variable "Q" was only temporary, and can be dispensed with
by substituting "P*I" directly for "Q" in line 50 and deleting line
40:
50 LET P = P + P*I
DEL 40
If you run the resulting program, you will find that it works just as
well as the first.
Let's further observe that "P + P*I" can be factored, using the
distributive law of algebra into: P*(1+I) with out changing its
value:
50 LET P = P*(1 + I)
We RUN this and find that it works just the same.
Then we realize that what we have been doing is to keep multiplying P
by (1+I), N times.
The ending balance is the value of P, times (1+I), times (1+I)...
N times.
Calling upon the exponentiation operator, "^", the whole program
becomes
10 INPUT P
20 INPUT I
30 INPUT N
40 PRINT P*(1+I)^N
50 END
DEL 60-90
The proof of the pudding is in the eating, and sure enough, it works
just as well!
If "55 PRINT P" were added to the original BANK program, the balance
of the savings account would be displayed each time the interest is
compounded.
The final version of BANK cannot be amended to produce this output,
because the amount is computed on one line, while the original BANK
has a loop.
That loop is now hidden inside the exponentiation operator!
Consider BANK to be our first complete program.
The program in Figure 1-10 shows how other programs in this book will
be presented.
Each program is accompanied by a specification or description in
English.
Summary: Often times, writing a program is a matter of recording a
series of operations that you are familiar with but have never
organized so carefully.
Exercises:
- Write BANK, using FOR/NEXT instead of IF-THEN loop.
- Experiment with values of I: 0, 0.04, 0.10, 1.0, 2.0.
- Write a program like SUMMING that accepts an initial deposit, and
then goes into a loop asking for the number of months that have
passed and a deposit amount.
When a deposit of $0 is detected, the program should tell you the
balance of the account.
- Write a program that prints out the population, P, of a colony
with an annual growth rate, R, over N years.
- What would be the value of $24 invested at 6% annual interest for
352 years? (1626-1982).
- Write a program that calculates the balance of a savings account
after n periods have passed, where a fixed amount is deposited each
period.
Test the program by having it print the balance each period and then
hand check the computations.
- Given the population of a town or city, compute how many people
will have heard a news story each hour after the story breaks using
the assumption that each hour the number of new people hearing the
news is a percentage of the number of people not yet having heard the
news.
The program should accept the population and the percentage as input.
- Radioactive decay is the process whereby a given percentage of
radioactive material per unit of time pops like corn, leaving the
remainder radio-active.
Write a program that accepts a percentage and counts periods of time
until 50% of the original amount is remaining.
The length of time is called the half-life.
- Modify BANK so that it accepts an annual interest rate and whether
the interest is to be compounded annually, monthly, or daily.
(This would save the user from having to input 0.00833333, the
monthly rate for 10% annual interest compounded monthly.)
- A hypothetical Xerox copier reduces the size of a copy by x%.
What size will a dollar bill be after 10 copy-copies?
How many copies must be made before it is half of its original size?
- Change Maker: Write a program which reads a number from the
keyboard and considers it to be the price of an item, from 1 to 99
cents.
The program should print, on separate lines, the name of each coin
given in change for a dollar.
For example, if the number 58 is read, the program prints
quarter
dime
nickel
penny
penny
Modify the change-maker program to take into consideration that a
clerk is given 1 roll of each coin to start with.
When all of a coin is used up, change should be made using smaller
coins, where possible.
When the program runs out of pennies, it should terminate.
BASIC Syntax
We must have some way to show the legal forms of expressions and
statements in BASIC.
The method chosen for this book is simple.
This section summarizes what we learned in the previous two sections
as a demonstration of the method of showing forms.
Syntax diagrams consist of square and rounded boxes connected by
lines.
A rounded box indicates a character or group of characters used as a
symbol in BASIC, such as parentheses or key words (PRINT, INPUT,
etc).
Each diagram has a starting point on the left.
Arrows lead the way through the diagram to a single ending point on
the right.
Each and every path through the diagram is grammatically correct and
has an unambiguous meaning.
When a diagram is introduced, it is first described verbally, then
restrictions are given along with the meaning of the form.
Figure 1-11 gives the characters called letters.
Figure 1-12 gives all the digits.
Note that the letter "O" is different from the digit zero "0".
The two are dangerously close to each other on the standard keyboard.
Beginners are t00 unsuspecting t0 see the difference after making the
mistake, and then can n0t figure 0ut why their pr0gram d0esn't w0rk!
Th0se experienced in reading mixed O0o's see them standing 0ut in the
wr0ng c0ntext.
The same hazard exists with the letter "l" and the digit "1".
Letters and digits combine with other characters to form BASIC
'tokens', such as keywords, names of variables, and numbers.
In the remainder of this book, BASIC keywords (INPUT, LET, PRINT,...)
are in upper case letters.
Names of variables are in lower case.
This was intended to help you see what part of a statement is part of
the programming language and what is part of the problem.
You may be limited to upper case on your system, but the programs in
this book will work just as well.
Most all syntax diagrams also contain square boxes.
A square box contains the name of another syntax diagram.
The square box may be replaced by any of the possible forms given by
the diagram it names.
Figure 1-13 contains a square box referring to the syntax diagram for
digits.
The lines in the diagram show an arbitrary sequence of digits because
each time we come around to the square box we may chose any digit
from the digit syntax diagram.
We have defined a new form and have named it 'digits'.
The form name 'digits' is now available for use in later diagrams.
This may seem like a lot of work to go through just to define a
sequence of digits.
Syntax diagrams can cover an entire language by building up forms
from previously defined forms.
Figure 1-14 shows that a 'variable' is represented by a single
letter.
Figure 1-15 shows that a 'number', as used in this chapter, has two
possible forms.
The simplest form is a sequence of digits.
A number can also be a sequence of digits followed by a period
(decimal point), followed by another sequence of digits.
This means that 10560 and 1.92 are numbers and that .1 and 5.
are not considered proper numbers.
The latter two forms may be acceptable on your system but should be
politely written as 0.1 and 5.
Figure 1-16 shows that a 'line number' looks just like a sequence of
digits.
Each 'line' in BASIC consists of a line number followed by one or
more blanks followed by a 'statement' of some kind.
Note that 'line' ends with a RETURN or ENTER keystroke.
Figure 1-17 shows the form of a statement.
Note that the diagram shows the form of a statement, not the meaning.
We could say that each statement begins with a key word, but not much
more could be said about a general pattern.
The diagram for 'expression' is developed in Chapter 2.
We can see in the statement diagram three distinct uses of the equals
sign (LET X = 5, FOR I = 1 TO 5, and IF X = 0 THEN...).
Figure 1-18 defines 'line number' as a sequence of digits.
Line numbers appear only at the first of a line or after GOTO or
THEN, in our simplified BASIC language.
The use of a blank space to separate tokens where necessary to
improve readability is not shown in the diagrams.
Figure 1-19 shows that a 'program name' is any sequence of letters,
limited in length (see the user's guide for your system).
Most BASICs allow digits in the program name, see Exercise #5.
Figure 1-20 shows that a 'range' may consist of nothing, a single
line number, a line number followed by a dash, or line number dash
line number.
A line number followed by just a dash refers to the range of lines
starting with that line number through the END of the program.
LIST without any range means to list the whole workspace, whereas DEL
without any range does nothing, for safety's sake.
Figure 1-21 shows the various commands that were introduced in
Section 1.2.
You should trace over the diagram, quizzing yourself on the meaning
of each path through the diagram.
Figure 1-22 shows that a REM statement may be any sequence of
characters whatsoever.
Since programs are usually as terse as some poetry, remarks help us
to follow the motivation of the programmer.
Too many inappropriate remarks may distract from the story line.
A blank REM statement may be used simply to make the program listing
more readable.
The REMark statement may be used to narrate the program logic in
natural language.
REMs can contain tables of information about variables in the BASIC
program.
This helps later when someone (yourself included) has to make sense
of it so that it can be extended or modified.
All programs should have REMarks at the beginning giving the
program's author and purpose, the date(s) it was written, references
to any literature behind the concept of the program, etc:
REM DATA-BASE MANAGEMENT PROGRAM
REM
REM AUTHOR: Flash Coder
REM
REM Copyright November 1988
Such a group of remarks are called the "program legend".
Your remarks should be short and to the point.
For example:
REM count how many empty boxes there are
can be simply:
REM count empty boxes
without any loss of information while increasing clarity.
The REM is only for annotating the program listing.
The information will not appear on the display when the program is
RUN, only when it is LISTed.
If you want to display a message, you must use a PRINT statement.
What you say in a REMark has no effect on the program.
A remark is essentially invisible to the interpreter/compiler.
Exercises:
- Design a pleasing pattern of remarks that will characterize
programs you will write in the future.
- Write a set of syntax diagrams for the Old Testament.
- Draw a syntax diagram for a Library of Congress call number.
- Draw a set of syntax diagrams for a subset of a natural language
of your choice (English, German, Latin).
- Most systems allow program names that contain digits as well as
letters.
Draw a syntax diagram for 'name' from a specification you will find
in your BASIC user's guide.