Liberty Basic is develeopped by Carl Gundel
Original Newsletter compiled by Alyce Watson and Brosco
Translation to HTML: Raymond Roumeas

The Liberty Basic Newsletter - Issue #46 - AUG 99

"Knowledge is a gift we receive from others." - Michael T. Rankin

In this issue:

  1. Block Structured Code

    AND

  2. Development of Large Programs with LB

    by Herman

In future issues:


We have a real treat in this newsletter! These two articles contain the most clearly written explanation of program design and flow that I have seen! THANKS Herman!!!

If you find the articles in this newsletter useful or informative, please send a note to the author:

Herman: aerosof-@agt.net http://www.agt.net/public/aerosoft.net


1) Block Structured Code

OK, here is a little bitty on block structured code:

The big idea is to write code such that every logical 'paragraph' of code has only one entry point and one exit point. Just like a text book, you start reading at the top of the page and finish at the bottom of the page. Every paragraph of text corresponds to a functional block of code and may be indented from the left margin, for legibility (usually 3 or 4 spaces).

Furthermore, if a paragraph of code has to be read/executed by the processor conditionally or repeatedly, then the logical instruction controlling this action will surround the paragraph with brackets or some other easily recognizable construct.

eg.:

a = 0
while a <= 5
do something...
do something more...
...
a = a + 1
wend

alternatively the loop can be written like this:

for a = 0 to 4 step 1
do something...
do something more...
...
next a

The general idea is to avoid the use of the GOTO command if at all possible, since GOTO, which directly translates to a 'JUMP to address' instruction, usually destroys the block structure.

Another way to put it, is to draw a flow chart of the program that you want to write. The convention is that a chart flows from top to bottom and from left to right. Moving in the other direction(s) require the use of arrow heads to indicate the flow explicitly. If code is properly block structured, there will be no occurrences of crossed lines on the chart. A set of crossed lines is known as a knot. Knots should be avoided, since the resulting code is hard to understand.

Note that the whole purpose of block structured and object oriented code is to improve the maintainability of the code. The idea is to make it easier for the poor sod who has to modify your code after you left the company for greener pastures. It has no effect whatsoever on the processor. The processor can't care less what the code looks like, it will merrily plod its way through whatever mess you dish up for it!

A side effect of structured code is that the code typically has fewer bugs, since it is easier to step through all possible code paths. Bugs always reside in code that was not tested...

In the above example, how does one exit the loop prematurely when something happened and you don't want repeat 6 times?

There are 2 ways: Either include the additional condition in the control statement

eg.:

while (a < 5) and (b > 0)
...
wend

 or you increment the control variable past the final condition:

for a = 0 to 5 step 1
if b = 0 then
a = 6
end if
...
next a

Don't use GOTO to get out of a loop. Some compilers don't like that and may fail, while it also destroys the block structure, since it provides a second exit point to the block.

Cheers,

Herman http://www.agt.net/public/aerosoft.net aerosof-@agt.net


2) Development of Large Programs with LB

General

What is a large program? To my mind, it is any program that won't fit on a single screen. That may sound tough, but programs have a habit of growing...

Program growth is due to the peculiar nature of the human mind. Our brains are adapted for pattern recognition. Vision and sound being very important for the survival of a simeon (simeon = big ape = us!). When we don't fully understand a problem, we tend to have a simple picture of it, which means that we underestimate it. Then, when we try to solve the problem, the solution grows and grows until it is several times larger/complex than we anticipated.

This program growth often detroys the original concept of the program, causing it to become a complete muddle, with the result that one has to give up and start afresh. I'm sure that has happened to everybody. Rewriting a program is a very expensive process, since one invariably end up making some of the same mistakes all over again.

Good program design can avoid this requirement to rewrite a program, and can save one a tremendous amount of time (time=money) in the long run.

Therefore, it is prudent to treat any program you set out to write as a large program and to apply proper software engineering principles to it right from the start.

Basic Problems

The big problem with BASIC is the scope of variables. All variables are global in nature. That is, once defined, they can be accessed from anywhere in a program. This makes it easy for bugs to spread, since an error in one part of the program can affect something in another unrelated area of the program.

The second most serious problem is automatic type conversion. If you define a variable as a number in one place and use it as a string somewhere else, there will be no error messages, but the program may behave mighty strangely.

The third problem is more one of logistics than a BASIC problem. When a program becomes very large, having a single file becomes unwieldy. One way around this is to split the file into a number of sub files and concatenate them together before testing in LB, using a DOS batch file. This method however involves the use of another programmers editor and maybe a pre-processor, which is another topic.

Anti Bugging

The only thing we can do is to apply a lot of self discipline, establish a coding standard and adhere to it, come hell or high water.

This coding standard should attempt to achieve two things:

  1. Define all variables before they are used in a central spot, for easy reference and
  2. Establish a naming convention so you can spot misuse of variables, since the LB interpreter isn't going to help you with it.

These are your best anti bugging measures. Other anti bugging measures usually boils down to testing the range of an input value before using it, but LB will in fact help you with that, so it is not as important as the control of variable scope and conversions.

Declarations

Say we are developing a program called widget. I would start the program with a list of all the variables used in the program and as the program grows, I'll keep adding to this list. This provides me with a central point of Here is an example of a widget process control program declaration block:

'********************************************************************
'File: widget.bas
'Description: A widget manufacturing controller
'Copyright 1999, Widget Corporation, Calgary, Alberta, Canada
'Version Date Author Description of Change
'--------------------------------------------------------------------
'1.0 1/1/99 Herman First release
'
'********************************************************************
 
'Declarations
widget_name = "" 'widget name string
widget_serial_num = 0 'current widget serial number
widget_count = 0 'total number of widgets produced
MAXIMUM_WIDGETS = 100 'max number of widgets in a batch
 

Note the the file header. It identifies the file, whodunnit, when and claims copyright - very important, since in the USA, copyright of literary works is not automatically in effect and that may be your biggest market. So in the odd event that somebody would steal your program, you would want to be able to sue him.

Every variable is declared with a default starting value. This ensures that your program will always start up sensibly.

All variable names are always written in lower case, while all constants are always written in upper case, keeping things clear.

A constant is a value that will never change. We give it a name, to improve the readability of the program. It also ensures that if we want to change the constant, we only need to make a single change to the declaration, to make it take effect throughout the program, wherever it is used.

As a general rule, the only constants that may be used without declaring them as above, are the values 0, 1 and -1 (and even that exception is sometimes frowned upon!).

Procedures

Procedures/subroutines/methods are all different names for the same thing, an independent piece of code, structured such that it can be called, executed and will return to where it was called from upon completion. (Well, it doesn't quite return to where it was called from, it returns to the next line of code, else the program will be stuck in a loop!).

Here is an example of a procedure:

'********************************************************************
'Name: wgt_counter
'Description: Counts the number of widgets produced
'Inputs: widget_serial_num
' widget_count
'Outputs: widget_serial_num
' widget_count
'********************************************************************
[wgt_counter]
'increment the widget numbers
widget_serial_num = widget_serial_num + 1
widget_count = widget_count + 1
return

This is of course a trivial example, but note the use of the procedure header, to tell us the name of the procedure, what it does, which (input) variables are used to control this procedure and which variables are modified (output) by this procedure.

If the procedure made use of temporary variables, then they would be noted only as outputs, since their input values don't matter.

Likewise, if a variable was only used to control the procedure but was not changed at all, it would only be listed as an input.

Thats all folks,

Have fun,

Herman http://www.AerospaceSoftware.com

aerosof-@agt.net


Newsletter compiled and edited by: Brosco and Alyce.

Comments, requests or corrections: Hit 'REPLY' now!

mailto:brosc-@orac.net.au

or

mailto:awatso-@mail.wctc.net