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.

---------------------------------------------------------
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:

Payroll tax changes
Introduction of a Goods and Services Tax
Zip code changed from a 5 to a 7 digit code.
Millenium bug check
etc., etc., etc.

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 amount
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

to 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 written by: Brosco.
 Comments, requests or corrections mailto:brosco@orac.net.au

 Translated from Australian to English by an American:
 Alyce Watson -  Chief Editor.  Thanks Alyce.

--------------------------------------------------------------
 