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 #24 - Dec 98

"The only stupid question is the one you don't ask"!

In this issue:

  1. FreeForm for Dummies
  2. Questions and Requests - GOSUB


Questions and Requests - new section for the Newsletter

Some questions in the email list can be simply answerred with a quick reply - others need a deeper explanation. In this section I will be trying to answer the requests/questions that require a longer reply than is practical to put in a simple email. I hope to make this a regular feature of the newsletter. To do so - I obviously need you to post your requests on the LBnews Email list.

And next issue - a guest contributer - a great article - I promise!


1) Freeform for Dummies

What is FreeForm?

FF is a Rapid Application Development System (RADS) using a Graphical User Interface (GUI) to produce Liberty Basic source code for Windows Software Development.

Did you get that? - if not - GOOD! - just forget that I even said it. That little load of buzzwords came to mind because a while back a couple of people suggested that I should write a book about programming. And thats the sort of thing that you must put into books to get them published. The publishers want you to use buzz words and acedemic jargon to give the content credibility.

I think that it just confuses and scares people - and that is why I try very hard to write in simple terms without using any more jargon than absolutely necessary. So lets start again.

What is FreeForm?

FF is a program that allows you to map the appearance of a Window, particularly DIALOG windows - and then generate the skeleton code for the Liberty Basic program to use it. Although you can map any type of window, it is with Dialogs - or windows with several CONTROLS ( Buttons, TextBoxes, etc.) that you will get the most benefit from FF.

mmmmmmhhh - I'm a lot happier with that description.

The full 'FreeForm for Dummies' is enclosed in the attached zip file. It is in Windows Write format - with BMP screen captures, and explains all of the options available with FF.

Please - if you see any errors, omissions, etc. don't forget to post a message on the LBnews email list. All the 'LB * for Dummies' documents are constantly updated and the latest version is made available at our Side-by-Side Software site. Your feedback is necessary for this to happen.


2) Questions and Requests - GOSUB

James Forsyth submitted the following request to the list:

"Brosco, I would like to see a article on subroutines. I do not fully undestand how to use them. I would like to see a program coded with subs and the same program coded without subs if that is possible. Thanks"

Thanks for your request James. I am sure that many LBers are in the same position as you - so let's see if this helps!

GOSUB is a very powerful part of the BASIC programming language - and once you understand it - you will wonder how you ever lived without it. I will use some of the explanation found in the LB Help file:

GOSUB [label]

Description:

GOSUB causes execution to proceed to the program code following the label if it exists, using the form 'GOSUB [label]'. After execution is transferred to the point of the branch label, then each statement will be executed in normal fashion until a RETURN is encountered. When this happens, execution is transferred back to the statement immediately after the GOSUB. The section of code between a GOSUB and its RETURN is known as a 'subroutine.' One purpose of a subroutine is to save memory by having only one copy of code that is used many times throughout a program.

Sample Usage:

print "Do you want to continue?"
gosub [yesOrNo]
if answer$ = "N" then [quit]
print "Would you like to repeat the last sequence?"
gosub [yesOrNo]
if answer$ = "Y" then [repeat]
goto [generateNew]
 
[yesOrNo]
input answer$
answer$ = left$(answer$, 1)
if answer$ = "y" then answer$ = "Y"
if answer$ = "n" then answer$ = "N"
if answer$ = "Y" or answer$ = "N" then return
 
print "Please answer Y or N."
goto [yesOrNo]

In the above example, the label [yesOrNo] and the code that follows is know as a subroutine.

If the GOSUB command wasn't available, this code would need to be repeated after each prompt to the user. The code would look like this:

print "Do you want to continue?"
[yesOrNo1]
input answer$
answer$ = left$(answer$, 1)
if answer$ = "n" or answer$ = "N" then [quit]
if answer$ = "y" then answer$ = "Y"
if answer$ <> "Y" then
print "Please answer Y or N."
goto [yesOrNo1]
end if
 
print "Would you like to repeat the last sequence?"
[yesOrNo2]
input answer$
answer$ = left$(answer$, 1)
if answer$ = "y" or answer$ = "Y" then [repeat]
if answer$ = "n" then answer$ = "N"
if answer$ <> "N" then
print "Please answer Y or N."
goto [yesOrNo2]
end if
goto [generateNew]

You can see how using GOSUB [yesOrNo] saves many lines of code. The subroutine [yesOrNo] could easily be used many other times in such a hypothetical program.

IMPORTANT NOTE. For every GOSUB that is executed - there MUST be a corresponding RETURN. To ensure this, try VERY HARD to avoid the use of any GOTO statements within a subroutine. I would prefer to see the above [yesOrNo] subroutine written like this:

[yesOrNo]
answer$ = ""
while (answer$ <> "Y") and (answer$ <> "N")
input answer$
answer$ = upper$(left$(answer$, 1))
if instr("YN", answer$) = 0 then print "Please answer Y or N."
wend
return

BENEFITS from using GOSUB

  1. The code is only written once - thus saving time.
  2. Without a gosub - there are many more lines of code to test and debug - with gosub - you have just one set of code to test.
  3. The program becomes smaller and more readable.

In newsletter #23 I used a subroutine to validate the user input. I did this because I needed to validate the data in two places in the program:

  1. when the user added a new record

    and

  2. when the user updated an existing record.

Suppose that, in the future, I needed to add some additional data validation to my program. Because its only coded once, I only need to update the code in one place. Without the use of GOSUB, I would need to search through the entire program to ensure that I found every section where data validation was needed. In large programs, this can be quite a headache - and it would not be unusual to forget to add the code to some of the areas.

While I'm on the subject of large programs - there is another important reason for using GOSUBs. If you follow my suggestion of building a program one function at time (Newsletter #22) -

here is a very useful technique:

  1. write the first function
  2. test/debug it until it works
  3. put the code into a subroutine (place a [label] at the start and a RETURN at the end of the code), move it to the end of the program and put a GOSUB [...] where code was originally
  4. test it again to ensure its still OK

repeat this process for each function needed.

By following this process you are placing the working/debugged code at the end of the program. The code you are currently testing and debugging is ALWAYS near the start. In large programs this saves a lot of time. You don't need to scroll up and down through the program to find the parts you are working on.

Here is the way the program from Newsletter #23 would look:

' VCL - Video Cassette Library - LB Newsletter #24
gosub [init.ctrl3d]
 
gosub [create.window]
 
gosub [open.database]
 
[loop] ' Main Message loop
input var$
goto [loop]
'********************** Button Functions *************************
[add.rec]
gosub [validate]
if valid = 0 then [loop] ' input has errors - dont add the record
gosub [perform.add]
goto [loop]
 
[update.rec]
gosub [validate]
if valid = 0 then [loop] ' Input has errors - dont update the record
gosub [perform.update]
goto [loop]
  
[prev.rec]
gosub [perform.prev]
goto [loop]
 
[next.rec]
gosub [perform.next]
goto [loop]
 
[close.w]
gosub [perform.close]
end
' ************************** Subroutines Follow *************
....

IMPORTANT NOTE: In the [add.rec] and [update.rec] code you will see that there are 3 statements:

gosub [validate]
if valid=0 then [loop]
gosub [perform....]

Why didn't I put the first 2 statements into the [perform.add/update] subroutine? The reason is because of the '..... then [loop]'.

Remember, we must exit a subroutine with a RETURN. If we exitted the subroutine with '...... then [loop]' some memory that is allocated when you use a GOSUB would not released. The RETURN command looks after this. The program would eventually crash - with a meaningless error message.

The full program is attached to this newsletter in the zip file -

it is called 'dialog10.bas'

This program is now much closer in structure to the way professional programs are written. In a business environment, programs have bugs to be corrected (just like our programs) plus they also have changing business requirements to attend to - and so programs are constantly being updated to reflect this. Examples:

The person who originally wrote the program may not work for this company any more - or even is he does - he may be busy developing a new application. So programs are often updated/maintained by a separate group of programmers called 'Maintenance Programmers'.

Making changes in your own programs is hard enough - making changes in other people's programs can be a nightmare. So to make this easier, computer departments set standards to the way a program must be structured. Dialog10.bas is much closer to the way a 'Structured Program' would look.

We have the high level functions at the start of the program - this makes it very easy to identify the section of code we need to look at to make changes. For example, suppose that there was a bug in this program that had to be fixed - let's say that new records were not being added correctly. By scanning the functions at the start of the program we can quickly identify the subroutines that need to be checked to find the error. This saves the maintenance programmer from needing to scan the entire program to look for the potential problem areas.

And on a slightly different topic - but related to maintenance programming - is the use of COMMENTS in programs. The amoun of comments that I include in the sample programs produced for this newsletter is about the same amount that I would include in programs written for my own use. I find that by using meaningful names for variables and [labels], the need for comments is minimised. To me, code like: "gosub [init.ctrl3d]" is already sufficiently readable and does not need a comment like:

' **** This function initialises the ctrl3d.dll *****

providing that the code in this subroutine does NOT perform any other function than the one implied by the name. Do not fall into the trap of coding multiple functions within one subroutine.

You may also notice that I use lots of 'white space' (blank lines and indents) to make the programs more readable.

So James, your question about GOSUB has managed to introduce all sorts of new techniques and ideas. I hope this is helpful o you and many other LBers.

Now - do YOU have a request like this one? Post it to the LBNews email list and I will do my best to answer it. By posting the request, you will probably be helping many LBers.


Newsletter compiled and edited by: Brosco and Alyce.

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