     Subject: GFA Tutorial, Month One
          By: James Collett (Professor)
 A Member Of: VIRTUAL INFINITY
       Email: s6005146@oxpoly.ac.uk (or s6005146@brookes.ac.uk)
     Address: Room N4, L.S.C.Collage, Wheatley, Oxford, OX9 1HX
 Mono accnt.: bcc


 Introduction To Syntax And Structure
 ====================================
    In the same way 'human' or natural languages have syntax & structure, 
 computer  languages  do too;  and natural language  syntax  &  structure 
 provide a good analogy for computer languages:
    Syntax is far more than just saying sentences must contain words  and 
 sentences  must  start with capital letters.   It is a complete  set  of 
 rules,  in theory unambiguous,  which can be used to determine whether a 
 sentence  is valid or not.   For example "The built a was tamer  fortune 
 blaze  by lazy." contains words and starts with a capital but would  not 
 be considered a valid sentence!   An example of simple syntax rule would 
 be sentences may consist of 'determiner + adjective + noun':  "The brown 
 fox."
    In a similar way that syntax varies from natural language to  natural 
 language (e.g.  English and French), syntax also varies between computer 
 languages (e.g.  GFA Basic and C++).  If we want a particular program to 
 work, we must ensure the syntax is correct.

    In  the natural language called English,  structure is the  way  that 
 sentences  are fitted together into paragraphs,  and  paragraphs  fitted 
 together with a heading at the top/etc to form documents, letters, etc.
    (Both  syntax  and structure will be discussed in  more  detail  this 
 month.)


 Variables
 =========
    Throughout this tutorial I will try to indicate instructions with  an 
 asterisk (*) to distinguish them from information.

*   From low res, load GFA Basic and press <escape> for direct mode:
    A  very  important aspect in programming is being able to  store  and 
 manipulate  numbers and text.   Places where data is stored  are  called 
 variables but can be thought of as 'draws',  where each draw has a label 
 and a contents.  You can think of GFA Basic having an infinite number of 
 draws  (it`s not quite,  but it`s a hell of a lot!) and when  you  first 
 load the language all these draws are unlabelled and empty.
    To label a draw, for example age, and put an age in it type:

* age%=19

    To label a new draw, for example surname, and put a name in it type:

* surname$="Professor"

    Note that integer (whole number) variables (or 'numerical draws') are 
 identified with a percentage sign and string variables (or 'text draws') 
 are identified with a 'dollar sign',  which is also called string.  I.e. 
 you  would  pronounce  these two variables 'age  percent'  and  'surname 
 string'.
    Note also that strings must be enclosed in double quotes ("), this is 
 not part of the string but indicates where it starts and finishes.
    Two simple commands used to manipulate variables are PRINT and INPUT, 
 note that commands do not have to be entered into GFA in  capitals,  but 
 throughout this tutorial I will try to put them in capitals to  identify 
 that they are commands.
    PRINT  is used to output to the screen,  to find out the contents  of 
 the variables (or 'draws') type:

* PRINT age%
* PRINT surname$

    INPUT is used to input, from the keyboard, a value (number) or string 
 into a variable.  Try:

* INPUT age%
* INPUT new_value%

    GFA should prompt for a number in each case.   After  entering,  type 
 the following, followed by your name at the prompt:

* INPUT surname$

    Note  that when you put your age into age% the previous contents  are 
 completely destroyed; similarly for surname$.  Check this out by typing:

* PRINT age%
* PRINT surname$
* PRINT new_value%

    PRINT  can  also be used directly with values and strings  (text)  as 
 well as with variables ('draw' labels).
    Typing  long  commands  every time can be  very  laborious  and  most 
 commands have abbreviations or short hand versions.  The abbreviation of 
 PRINT is simply ?.  Try some of the following, using both PRINT and ?:

* ? 7
* ? 7-2
* ? age%+14
* ? "Hi there!!"
* ? "Hi there "+surname$+"!!"
* ? age%+new_value%+2

    As well as using plus (+) to return results to screen, it can also be 
 used to store results as variables.  Try this:

* new_value%=age%+3
* ? new_value%

* age%=age%+1
* PRINT age%

* surname$="Hello "+surname$
* ? surname$

    Note  that + has a different purpose depending on whether being  used 
 with strings or numbers.   If you try and use it with a mixture of  both 
 then  you will get an error - i.e.  GFA syntax rules have  been  broken!  
 Instead you must use a semicolon (;) as follows:

* ? surname$;" is ";age%;" years old"
* ? surname$;" will be ";age%+1;" next year"

    You can also use minus (-) to subtract,  asterisk (*) to multiply and 
 slash  (/) to divide numbers,  although obviously not  strings!   So  in 
 summary:

        Strings = Use  +  to 'add' strings, to screen or a variable

        Integers = Use  + - * /  to manipulate, to screen or a variable

        Both = Use  ;  to 'mix' strings and integers, to screen only


    Before  we write our first program,  note what happens if you try  to 
 put a string in an integer variable (or integer 'draw'), and vise-versa:

* surname$=19
* age%="Professor"

    Note  also what happens if you try to put a real number (number  with 
 decimal point) into an integer:

* new_value%=-6.54321
* PRINT new_value%


 Our First Program
 =================
    Another note just before we write our first GFA program:  if you have 
 just started programming (maybe today!) I hope you can appreciate,  when 
 you  start  looking  at any sources,  you will come  across  things  you 
 haven`t learned yet and have to take as true or trust the programmer.
    I  think  it  is important to show some demo sources  as  quickly  as 
 possible, thus there maybe one or two lines you`ll just have to trust me 
 on for the minute!

*   Press <escape> to return to the editor and Merge VARIAB_1.LST:
    Before  we  Run (execute) the set of instructions  lets  manually  go 
 through  them  (or  'dry-run' them).   First of all a  message  will  be 
 displayed  asking for a name and then INPUT surname$ from the  keyboard. 
 After  getting  age% (presumably in years),  it is multiplied by  12  to 
 convert into months.   The program then greets the person,  and  informs 
 them of their age (now in months!) before ending.   Note that the  first 
 two output lines end with a semicolon but the last output line  doesn`t; 
 if  no  semicolon  is  present  on the end of  a  PRINT  then  GFA  will 
 automatically start a new line (i.e.  LF+CR), if you wish to continue on 
 the same line then you must include a semicolon.

*   Run  the program by either pressing the appropriate function  key  or 
 clicking on the appropriate menu button.   Enter a name and age of  your 
 choice.   If you don`t trust the output (why not?!?) then, after ending, 
 goto the direct mode,  check the result by multiplying the input age  by 
 12 and return to the editor.   Note that the 'run screen',  at the point 
 when execution stopped, appears as the 'backdrop' on direct mode.
*   Re-run the program a few times,  try to predict what you would expect 
 to happen if you input a number for the name or string for the age.  Try 
 also inputing negative numbers or real (decimal) numbers as the age.
    This program is very simple,  but not bad for a first effort!   Let`s 
 try improving things:

*   From the editor Merge VARIAB_2.LST:
    DO NOT RUN THIS - IT WILL NOT WORK!   Note that Merge [which loads an 
 ASCII  source] doesn`t wipe the previous contents.   The  advantage  (or 
 disadvantage!)  of  Load [which loads a 'tokenised' source] is  it  does 
 wipe the previous contents and starts from scratch.   The reason we have 
 to use Merge,  as already discussed, is to make this tutorial compatible 
 with all versions of GFA.

*   From the editor select New to start from scratch, confirm your action 
 and now Merge VARIAB_2.LST:
    I`ve added to this source an initial clear screen,  then scraped  the 
 PRINTs  and  included user-defined prompts with  the  INPUTs.   The  GFA 
 default  prompt is a question mark (?).   Note a comma is  necessary  to 
 separate the optional prompt and variable.   Next is the fastest method, 
 in GFA, to multiply a variable by a value: MUL var,n is about 30% faster 
 than  var=var*n.   There are similar commands to ADD,  SUB and DIV  (all 
 will be dealt with in detail later).
    Moving  to  the  output,  after  the CHR$  you`ll  notice  I`ve  used 
 semicolons instead of plus`s to allow 'mixing' of strings and numbers in 
 a single PRINT statement.   CHR$,  again to be discussed later,  returns 
 (displays) the character of a given ASCII value.  For example to display 
 an "A", which has ASCII 65, type the following in the direct mode:

* ? CHR$(65)
* ? CHR$(7)

    ASCII  10 is LF and leaves a gap on screen.   ASCII 7 (above) is  BEL 
 and sounds the ST`s bell.
    I personally do not like the standard GFA END command,  which  brings 
 up the horrible alert box, and prefer to "finish off" myself by beeping, 
 waiting  for a key press (INP(2)) and returning directly to the  editor. 
 It`s  a matter of personal preference and you may wish to  beep,  flash, 
 print  "Program Terminated" or a whole host of other things to  indicate 
 your  own programs have reached their normal ends.   As well as END  and 
 EDIT,  there  is  also a STOP command which displays an  alert  box  and 
 returns  to  direct  mode,  STOP does also allow  you  to  continue  (if 
 possible - i.e. stopped in middle) which is occasionally useful.
    Note  in  GFA  3 VOID can be abbreviated to ~.   Thus  I  finish  the 
 majority of my GFA 3 programs with:

  PRINT CHR$(7);
  ~INP(2)
  EDIT

    VOID  (discussed  later)  is mainly  used  with  numerical  functions 
 (discussed  later) to mean you wish to execute or perform a  calculation 
 but not hold the returned result.   Sounds strange but very useful,  for 
 example wait for key press but not care which key is pressed.


 Comments And Annotation
 =======================
*   From the editor select New, confirm and Merge COMMENTS.LST:    
    It is often useful, especially with more complex pieces of source, to 
 add  comments  (or remarks) and to annotate  lines.   GFA  provides  the 
 single quota (') for an entire line comment and explanation mark (!) for 
 annotation on,  and after,  a line to be executed.   The text after  the 
 marker will be ignored during execution and can break every syntax  rule 
 in the book!   The convention,  however, is to high-light with asterisks 
 but this depends on your personal preference.


 Variable Types 
 ==============
    As  well  as being able to store and manipulate  strings  (text)  and 
 integers  (whole numbers),  GFA can also (hopefully  obviously!)  handle 
 real  numbers.   In the same way integers and strings  are  respectfully 
 identified with a percentage sign and string (dollar) sign, real numbers 
 are identified with ... no sign!  In summary:

        var$ = string (text) variable, contents marked with quotes (") 
                when assigned to variable

        var% = 32 bit integer variable, range approx -2 billion to +2 
                billion
        
        var = real number, range VERY BIG and VERY ACCURATE

    The advantage of using integer over real, where real is not required, 
 is that of speed - integers are faster that real numbers,  but can  only 
 be  used  if no decimal is needed (e.g.  a counter,  discussed  in  more 
 detail this month).
    GFA  3  also offers 16 bit integer (word) and 8  bit  integer  (byte) 
 variables,  which  are  even  FASTER than a standard  integer  but  with 
 reduced ranges,  as follows.  During this tutorial I shall stick with 32 
 bit integers (long-words) so it is GFA 2 compatible:

        var& = 16 bit integer variable, range -32768 to +32767

        var| = 8 bit integer variable, range only 0 to 255


 Boolean Expressions - Introduction To Decision Making
 =====================================================
    Another important concept in programming is that of  branching,  i.e. 
 coming  to a 'junction' and either going one way or the other - no  buts 
 or maybies!
    A boolean expression is one that is either TRUE or FALSE, for example 
 either age% is 99 or it`s not 99, either surname$ is "smith" or it`s not 
 "smith" - no buts or maybies.   Considering numbers for the  moment,  as 
 well as testing if a variable or value is identical to another,  you can 
 also test:

        >   greater than
        <   less than
        >=  greater than or equal to
        <=  less that or equal to
        <>  greater or less than (i.e. not equal to)

*   Goto direct mode and type CLS to clear screen if required:
    In GFA,  TRUE has the value (or 'is represented by') -1 and FALSE has 
 the value 0.   Try some of the following and try to predict the returned 
 result (note they don`t have to be entered in capitals):

* ? TRUE                    *  PRINT 7>7
* ? FALSE                   *  ? 7>=7
* ? 2=2                     *  ? (3+1)=(2*2)
* ? 2=5                     *  ? 9<=(3+4)
* ? 2<>5                    *  ? (9<=(3+4))=FALSE
* ? 2<5

    (As  well as testing if a string is identical to another,  there  are 
 other 'string tests', to be discussed in detail next month.)
    In GFA, to branch a way dependant on the 'truth' of an expression, we 
 use IF ... ENDIF and IF .. ELSE .. ENDIF.

*   Return to the editor and have a look at BRANCH_1.LST and BRANCH_2.LST 
 (don`t forget to New before you Merge!)

    As well as simple tests (e.g. <> or >=), combinations of tests can be 
 made using the logic gates:  AND,  XOR (exclusive or), OR (and/xor) plus 
 NOT;  for example age%<99 AND NOT(surname$="smith").   I am not going to 
 cover  the  complete set of 'truths' for all gates  (called  the  'truth 
 tables')  because  they are even more boring than this  tutorial  (which 
 does  improve  next  month!) and are  fairly  straight  forward  anyway.  
*However,  I  have included a sample source,  BRANCH_3.LST,  and a  truth 
 table source, TRUTABLE.LST, to have a look at.
    You  can  use  the  latter if you need the  table  for  a  particular 
 expression, and it is set up for '(NOT P) AND Q' where P and Q represent 
 simple  tests such as age%<99 or surname$="smith".   After covering  FOR 
 and  NEXT  (this  month) you`ll be able to add  or  remove  simple  test 
 representatives as required.

    Note  in  GFA  3 an ELSE and IF can compress  onto  one  line  (shown 
 right),  thus meaning the second ENDIF and second indent are not needed.  
 During  this  tutorial I shall stick with the GFA  2  compatible  method 
 (shown left):

  ELSE
    IF value%<10                    ELSE IF value%<10
      PRINT "Number ~~~~              PRINT "Number ~~~~
    ELSE                            ELSE
      PRINT "Number ~~~~              PRINT "Number ~~~~
    ENDIF                           ENDIF 
  ENDIF


 Looping - Introduction And FOR ... NEXT Loop
 ============================================
    It is often necessary in programs to repeat a particular part a fixed 
 number of times,  repeat while a condition (boolean expression) is  TRUE 
 or  even repeat until one is TRUE.   One way of doing this could  be  to 
 laboriously  enter  the  part of the  source  500  times!   The  serious 
 solution is to use a loop,  i.e.  to tell GFA to 'loop' around the  part 
 either  a  fixed  number of times or in  collaboration  with  a  boolean 
 condition.   GFA  Basic  actually  offers no fewer  than  four  'looping 
 mechanisms' which allow solutions to be found to any problem where it is 
 necessary (or might be necessary) to repeat part of a program:

    The first and simplest loop,  called the FOR ...  NEXT loop,  uses  a 
 counter to repeat the part a fixed number of times - which could be once 
 or a million times.
*   From a 'clean' editor Merge, look at and Run FORNXT_1.LST:
    The loop can be thought of as building a 'table', in this case from 1 
 to  5 (the maximum count),  and each time the loop is executed the  next 
 slot  in  the table is 'ticked off'.   This isn`t quite  how  it  works, 
 inside the processor,  but a good way to think for a simple loop.   Note 
 the value of the counter when you leave the loop, after final execution.
*   Look at and Run FORNXT_2.LST, preferably in low res:
    It  may  be necessary to use a far more complex  count  mechanism  or 
 'STEP' than just 1, 2, 3.  For example 0.2, 0.4, 0.6 (STEP 0.2) or -0.5, 
 -1.0, -1.5 (STEP -0.5).  This source is a perfect demonstration of this, 
 which uses the PLOT command to draw a circle point by point using sine & 
 cosine  waves  [note this mathematical source can be replaced  with  one 
 line;  sine,  cosine,  PLOT  and  graphics will be discussed  in  detail 
 starting next month].  Note also that speed and angle (theta) need to be 
 real,  the  radius(`s) and origin only need to be round to whole  number 
 though.
*   Try  experimenting  with  the parameters  (or  'control  variables'), 
 now discussed in general:    


 Parameters
 ==========
    [Going off at a tangent for a few minutes (and nothing directly to do 
 with looping!) a brief word about parameters.]
    Parameters  (also  called  operands)  can  be  best  thought  of   as 
 'switches' or,  as I said before,  'control variables'.  In the same way 
 your  TV/monitor  has a stack of knobs on it  (no  innuendoes  please!), 
 anything from a single line or routine upto a procedure (discussed  this 
 month) or complete program can have 'knobs'.   For example the parameter 
 of the line PRINT "Hello" is "Hello" and the parameters of ADD c%,4  are 
 c% and 4.
    If,  in  a routine or program,  you have a size/etc that is  constant 
 (e.g.  4)  then  you  could put 4 everywhere you need it  or  you  could 
 declare size% as 4 and put that everywhere.   If you needed to change it 
 for some reason,  is it easier to change one size% or to search  through 
 the  entire  source and change all 4`s,  hoping you don`t miss  any  and 
 don`t change any 4`s which aren`t the size??
    Listing  all  variable parameters together,  towards the top  of  the 
 program, saves you writing a complex user interface in your utilities at 
 all  and  in  final programs until the actual  'guts'  are  written  and 
 tested.  (I never put proper user interfaces on my utilities - no need!)
    The  use  of  (constant)  parameters in  programs  will  become  more 
 apparent with the use of more complex sources.
*   Experiment with FORNXT_2.LST`s parameters.


 Looping - Continued
 ===================
*   From a 'clean' editor Merge, look at and Run FORNXT_3.LST:
    Returning  to  the  FOR ...  NEXT loop,  GFA  also  offers  a  DOWNTO 
 facility,  which  is the equivalent to STEP -1 and cannot be  used  with 
 other STEPs.  Therefore in summary:

        If you need STEP -1 then use DOWNTO,
        If you need STEP 1 then use TO (without a STEP, 1 is default),
    And if you need any other STEP then use TO with a STEP

 ...  obviously  making  sure you get the mincount and  maxcount  in  the 
 correct order whichever version you use!
    Note the value of the counter when you leave the DOWNTO  loop,  after 
 final execution.

*   Look  back at TRUTABLE.LST,  mentioned above in Boolean  Expressions.  
 Figure  out  how  the  nested (i.e.  one  inside  another)  loops  work, 
 remembering  the  values of TRUE and FALSE (and not  forgetting  to  New 
 before Merging.)


    The  next two loops are the REPEAT ...  UNTIL loop and the WHILE  ... 
 WEND  (endwhile)  loop,   which  respectfully  REPEAT  UNTIL  a  boolean 
 condition is TRUE and repeat WHILE one is TRUE (i.e.  until it`s FALSE).  
 These are excellent for any situation where you`re waiting for something 
 to  happen  or  waiting for something to  stop  happening,  for  example 
 waiting for a valid input:
*   Look at and Run WHILE.LST:
    Typical use of a WHILE loop to repeat input until the variable  stops 
 being invalid.  (Note LEN returns the length of a string, functions will 
 be discussed next month.)
*   New, Merge, look at and Run REPEAT_1.LST:
    Note  this  collects  the key  press  (test%)  from  INP(2),  another 
 function,  instead of VOIDing or 'ignoring' it as seen in cases so  far.  
 This loop REPEATs UNTIL test% is ASCII 120, i.e. "x".
    The main difference between REPEAT ...  UNTIL and WHILE ...  WEND is, 
 as can be seen, the positioning of the boolean test to determine whether 
 to go around the loop again (or at all).   In the REPEAT ... UNTIL loop, 
 as  the test is at the end you will always go around the loop  once;  if 
 this isn`t wanted then the loop must be nested inside (placed inside) an 
 IF ...  ENDIF.   In the WHILE ... WEND loop, as the test is at the start 
 the loop will never be executed if it tests FALSE when you first hit the 
 loop;  for example,  in WHILE.LST, you enter a valid name/age first time 
 before the loop.


    The final 'loop mechanism' which GFA offers, and many other languages 
 don`t,  is  the  DO ...  LOOP loop.   The primary use of this is  as  an 
 infinite loop,  i.e.  once you get in it`s impossible to get out without 
 taking  fatal  measures!   Sounds strange but useful  for  both  testing 
 unfinished programs and final programs with no exit (e.g. game or demo).
*   After Merging, look at and Run DOLOOP_1.LST:
    Once Run, don`t press reset!  The way to break out of any GFA program 
 that  appears  to  have  crashed or gone into an  infinite  loop  is  to 
 simultaneously  hold  down CTRL,  ALT and SHIFT.  (If this fails  for  a 
 crashed  GFA program then do reset!) [Note this break facility does  not 
 work with the compiler (discussed later).]
    In GFA 3 you can also use DO ...  LOOP as a REPEAT ... UNTIL, a WHILE 
 ... WEND, or even a combination of these two:
    Unfortunately  this is GFA 3 only.   If you`re using version  3  then 
 LOAD DOLOOP_2.GFA,  otherwise LOAD DOLOOP_1.BAS.  Note when you Load you 
 don`t have to New first. Load and Save are the conventional way to store 
 and re-call files, Merge and SaveA are conventionally used for appending 
 (merging) and for 'inter-compatibility'.   To GFA 2 users:  DOLOOP_1.BAS 
 is the same as DOLOOP_1.LST,  but I couldn`t not let you try Load!   And 
 if  you want to see what your missing you`ll just have to get a copy  of 
 GFA 3!
    To   users   with  GFA  3:   DOLOOP_2.GFA  uses  two   boolean   test 
 representatives,  P and Q, to show a combination of REPEAT ... UNTIL and 
 WHILE  ...  WEND.   Note,  if doing this combination,  the tests can  be 
 identical or can be different.   In this example, 'P' determines whether 
 the loop is executed the first time and 'P AND NOT(Q)' is the determiner 
 after that.


 Building Other Loop Combinations
 ================================
    GFA  Basic also has an EXIT IF command which can be attached  to  any 
 loop,  including an 'infinite' DO ... LOOP in GFA 2.  It is bad practice 
 to use this and should be avoided whenever possible, but allows an 'EXIT 
 IF boolean condition' to be added to DO ... LOOPs and FOR ... NEXTs plus 
 extra control to be added to REPEAT ... UNTILs and WHILE ... WENDs.
*   Merge, look at and Run FORNXT_4.LST:
    After  placing  120  (ASCII  of "x") into  key%  and  displaying  the 
 instructions,  this  source goes into a STEPped -1 FOR  ...  NEXT  loop, 
 which  counts  down the number of attempts left to hit  the  right  key, 
 using EXIT to 'jump' out the loop should key% be pressed before attempt% 
 runs out.   If the loop is left 'properly' then attempt% will have  'run 
 out' (i.e.  become 0);  otherwise,  by pressing the EXIT key%,  attempt% 
 will be left 'hanging'.
    This source shows one way of combining a FOR ...  NEXT and REPEAT ... 
 UNTIL.
*   Merge, look at and Run REPEAT_2.LST:
    This does exactly the same job as the previous, but by using a REPEAT 
 UNTIL  and  combining  attributes from FOR  ...  NEXT,  it  handles  the 
 attempt% counter better.

    There are *several* methods, even in GFA 2 and without an EXIT IF, to 
 combine all three mechanisms into one basic loop should it be necessary.


 Introduction To Arrays
 ======================
    Moving  on,  an array is simply a table of variables all of the  same 
 type (e.g. all strings or all reals). 
*   Goto direct mode and type CLS to clear screen if required:
    'Paper  tables'  or  'manual tables'  (e.g.  timetable)  can  be  one 
 dimensional  (i.e.  just  have  one column or one row) and  can  be  two 
 dimensional (i.e. have both rows and columns).  In the same way, for the 
 moment, computerised arrays can be one dimensional or two dimensional.
    To  create  a  new  one dimension (one  column)  array  with  6  rows 
 (numbered 0 to 5) type the following (remembering commands don`t need to 
 be entered in capitals):

* DIM value%(5)

    To  display  the contents of the first 'box' on the table  ('box'  0) 
 simply type the following, the value 0 should be returned:

* PRINT value%(0)

    [[NOTE  that some versions,  as far as I know GFA 3 only,  return  an 
 "array  index  to large" error.   If this has happened to you  it`s  not 
 because of my tutorial but a minor bug with Direct mode.  To fix the bug 
 simply return to the editor, New to clear, type 'DIM correct%(0)' in the 
 editor,  Run this line,  return to direct mode,  re-type 'DIM value%(5)' 
 and continue from there.   Please remember even a language as superb  as 
 GFA can only be 99% perfect!]]

    Note the contents of all 'boxes' in a new array are initially 0.   To 
 change  the  contents  of the sixth 'box' ('box'  5),  use  one  of  the 
 following just like 'normal' variables:

* value%(5)=22
* INPUT value%(5)

    Array  elements  (or  array 'boxes') can be treated  just  any  other 
 variables.  Try some of the following, predict what`s happening:

* value%(0)=3
* value%(1)=8
* ? value%(0)<value%(1)

* INPUT value%(2)
* ? value%(1)+value%(2)
* ? value%(0)*value%(2)

    Note, as with variables, when you put a new value into an element the 
 previous  contents are destroyed.   Note also that GFA  starts  counting 
 rows (and columns) from 0.   Therefore if you had a one dimension  array 
 with its last element labelled 9, it has 10 elements in total.

    To create a new two dimension array with 3 rows (numbered 0 to 2) and 
 3 columns (0 to 2, thus 9 elements total) type:

* DIM text$(2,2)

    Once again this can be treated as a stack of string  variables.   Try 
 the following,  once making the comparison between column 0,  row 0  and 
 column 2, row 1 TRUE and once making the result FALSE:

* text$(0,0)="professor"
* INPUT text$(2,1)
* ? text$(0,0)=text$(2,1)

    Note what happens if you try to access an element ('box') outside the 
 defined table`s range or size:

* ? text$(3,4)

    (The use and application of arrays will become apparent this month.)
    Computerised arrays,  unlike 'manual tables',  are not restricted  to 
 the  2-D  nature of paper and can have three,  four,  a  dosen  or  more 
 dimensions if necessary.  Here is an example of a 4-D array,  which is 3 
 by 2 by 4 by 3:

* DIM array(2,1,3,2)

    This meaningless,  'applicationless' array could be used to store and 
 manipulate 72 (i.e. 3*2*4*3) real numbers.


 Applications Of Arrays (One)
 ============================
    Arrays  are potentially useful whenever you have lists or  tables  of 
 variables of the same type.
*   Return  to  the editor.   Merge and look at  ARRAY_1.LST,  a  trivial 
 example  of  array application.   By this stage you should  be  able  to 
 follow  an understand a GFA source of this complexity  without  Running, 
 using only comments and annotation as aid.
*   After 'dry-running' (i.e.  manually going through the source), Run it 
 for real.  Experiment with the program parameters and source.

    (I shall be returning to array application again this month.)


 Procedures
 ==========
    Often in programs,  it is useful or necessary to use the same routine 
 several  times,  at different points.   Procedures not only allow  this, 
 without needing multiple or repeated copies of routines,  but also allow 
 programmers  to  manage  and structure their  sources  during  creation, 
 testing and implementation.
    A  procedure  is a set of  collective  instructions,  which  normally 
 perform  a single simple task,  to which you give a label.   Humans  use 
 'procedures'  as  well  as computer languages,  and  such  'human  brain 
 procedures'  might  be  called (labelled) "getting  up  in  a  morning", 
 "making  a  cup of tea" or "reacting to a fire alarm" - i.e.  a  set  of 
 instructions which perform a single task.   In the same way that  'human 
 procedures' can be executed (or 'called'),  a GFA program can call (i.e. 
 execute) a procedure.

*   Procedure  syntax varies slightly between GFA 2 and  GFA  3.   Either 
 Load PROCED_1.BAS or PROCED_1.GFA, depending on your version (noting you 
 don`t have to New), and look at the source:
    The main program calls (i.e.  runs) a procedure to get all the drinks 
 and  then another procedure to display the  drinks.   Get_all_drinks  in 
 turn repeatedly calls a procedure to get a single drink,  which  RETURNs 
 to  get_all_drinks,  and that RETURNs to the main program after all  the 
 drinks have been entered.   After the last procedure,  i.e. show_drinks, 
 has  finished execution it RETURNs to the main program,  from which  you 
 finish.
    In both GFA 2 and 3,  all procedures are listed,  in any order, after 
 the end of the main program and are conventionally separated with  gaps.  
 The syntactical difference is in the calling:  in GFA 3 you just use the 
 procedure label, but in GFA 2 this must be preceded by an 'at' sign (@).
    Procedures  not only make sources easier to follow,  but  also  allow 
 programs  to be broken down into sections which allows easy testing  and 
 debugging.

    As well as using procedures to do *very* specific tasks,  it is  also 
 possible to write more 'general' procedures or procedures which still do 
 one task but offer some freedom in specification.   This is achieved  by 
 'giving' the procedure a set of specification when you call it,  whether 
 from  the main program or another procedure;  or what`s  called  passing 
 parameters  [i.e.  procedure  'control values' - slightly  different  to 
 program 'control values'].
*   The following source in based on FORNXT_2.LST, if necessary look back 
 at this source first.
*   Preferably  in  low res,  either Load  PROCED_2.BAS  or  PROCED_2.GFA 
 depending on your GFA version, and look at the source before Running it:
    This   uses  procedure  oval  to  draw  a  single  ellipse   to   any 
 specification (i.e.  to any origin & radius`s), as seen in FORNXT_2.LST.  
 It  is called oval so as not to conflict with GFA`s own ELLIPSE  command 
 (to be discussed later along with sine, cosine and PLOT).
    (Local and global variables will be discussed in a moment).  The main 
 program  initially fixes the speed,  and then repeatedly calls  oval  in 
 order to draw the face.

    The angle (theta) is *only* used in oval and not used anywhere  else.  
 It  is often useful to indicate such variables as LOCAL to a  procedure, 
 as oppose to the default: global to the *entire* program (i.e. both main 
 program and all procedures).


 Local And Global Variables - A Proper Explanation
 =================================================
    LOCALising  variables  also  allows several programmers  to  work  on 
 different parts of the same application or program - the LOCAL variables 
 used in one procedure won`t interfere with variables used anywhere else.

*   From the editor Load PROCED_3, but don`t Run it yet:
    You  can  also LOCAL an already global variable,  in which  case  the 
 variable  will take one (LOCAL) value  inside the procedure and  another 
 (global)  value  in the rest of the program.   This is quite  a  complex 
 concept if you`ve never done it before,  so I shall go through this demo 
 source (dry-run it) step by step:
    First of all variable1,  an integer, is assigned the value 5.  Before 
 calling  procedure one you are informed of this.   Procedure one  (after 
 the main program) then declares variable1 LOCAL,  i.e.  its value inside 
 this procedure does not effect its value anywhere else.  It is important 
 to note all LOCAL variables,  when declared,  initially take the value 0 
 until  assigned  another  value,  in this case  3.   After  leaving  the 
 procedure  and  RETURNing to 'the top',  variable1 re-takes  its  global 
 value,  in  this  case 5.   You are informed of this (and the  value  of 
 variable2 - dealt with in a moment) before the program finishes.
*   Run the program and check this does happen.

*   'Activate' the call to two, but don`t Run it yet:
    Procedure  two also uses variable1,  but the global variable1 with  a 
 value  of 5.   Its value is incremented to 6,  you are informed of  this 
 both  before  leaving  this  procedure and when  RETURNed  to  the  main 
 program.
*   Re-Run the program and check procedure two.

*   'Activate' the call to three, once again dry-run before doing it 'for 
 real':
    As well as passing values to procedures, variables can also be passed 
 to  procedures;  in  this case a new variable2,  which also must  be  an 
 integer.   Note variable2 is local to this procedure, and if used in the 
 rest of the program would maintain its global value on RETURNing.
*   Re-Run and check the final procedure.
    
    Thus  if  you were to pass variable1 from the call,  and  get  passed 
 variable1  (instead of variable2) in the procedure,  changing  variable1 
 locally in the procedure does not effect the global value.
*   Check this by modifying procedure three accordingly.

    Note  also  that  parameter  passing  and  localising  is  not   just 
 restricted to integer variables and values,  reals and strings can  also 
 be passed and localised in the same way.


 Applications Of Arrays (Two)
 ============================
    1-D  and  2-D arrays can easily be  'visualised',  if  necessary,  by 
 thinking of them as 'paper tables'.   The following example of array use 
 shows  a  good  way of 'visualising' a 4-D  array  for  this  particular 
 application.
    Imagine you`re the owner of two hotels in London, one coded 'hotel 0' 
 and other coded 'hotel 1'.   Each hotel has 5 floors (grounds, first ... 
 fourth)  and each floor has 16 rooms (1 to 8 down the left corridor  and 
 rooms  9  to 16 down the right corridor).   Thus you have 160  rooms  in 
 total (i.e. 2 hotels * 5 floors * 2 corridors * 8 rooms).
    A  very  simple  hotel  management system  (that  can`t  even  handle 
 advanced bookings!)  may need the following three arrays:

  DIM surname$(1,4,1,7)
  DIM arrive_date$(1,4,1,7)
  DIM leave_date$(1,4,1,7)

    Note I would treat the arrival and departure dates,  for a particular 
 person in a particular room,  as strings and of the form "ddmmyy".   For 
 example  12th May would be "120593".   (Note extraction  of  information 
 from strings and string <--> integer conversion is covered later.)
    The first procedure you would need is one to book somebody in.  After 
 a few months, with people constantly booking, and leaving, this database 
 will  become 'untidy' or 'patchy'.   The book_in procedure will have  to 
 search  through UNTIL it finds an empty room (OR finds both  hotels  are 
 full).   After inputing and somehow validating both name and dates,  the 
 procedure  can allocate the room to the person,  and also possibly  work 
 out their bill.
    The  other main procedure you would need is one to 'vacate the  room' 
 in the database after the person has paid and is ready to leave.  If you 
 didn`t know the room number and only knew the surname, the program would 
 have to search through UNTIL it found a match for surname$().

    The procedures would then need linking using either a  command-driven 
 or  menu-driven  system.   This  simple demo of  'visualising'  a  multi 
 dimensional  array (for which I haven`t written a source) is *FAR*  from 
 complete as a hotel system and leaves many problems such as how to  deal 
 with advanced bookings or how to deal with several people with the  same 
 surname.


 And Finally
 ===========
    I have deliberately set this month`s tutorial at an elementary  level 
 to  give anyone a nice,  gentle introduction to GFA.   I hope you  found 
 some of it (if not most of it!) too easy.   Although I won`t actually be 
 putting GFA through its paces until months 3 and 4,  I do intend to move 
 onto more advanced stuff next month (including my game,  LightMaze!) and 
 hopefully make the tutorial less 'wordy'.
    I am not going to include a summary list of everything you should  be 
 able  to do after going through this tutorial;  but have  included  both 
 source and compiled, executable versions of a simple exam grade program, 
 which includes most of what you should be able to do.
*   Load,  look at and Run EXAMMARK.   Experiment with the source and add 
 an expansion of your choice for next month`s tutorial.


 ---END---
