Subject: REVIEW: GFA BASIC v3.5
From: [email-masked] (Jason L. Tibbitts III)

GFA BASIC 3.5 is a fast BASIC interpreter, with advanced commands which
include matrix manipulation and direct access to the Exec, Intuition, Dos,
and Graphics libraries.  The optional compiler generates code which is
comparable in execution speed to a good C compiler.

*** Statement of Interest ***
        I have no commercial links with any part of the GFA organisation.
        I have written several tutorial articles on GFA BASIC in Jeff
        Walker's Just Amiga Monthly (JAM) magazine, the UK's only non-games
        Amiga magazine.  I have never received any incentive, financial or
        otherwise, to write about GFA BASIC; I paid cash for my GFA system.

*** Product Preamble ***
Product: GFA BASIC 3.5 Interpreter
         GFA BASIC 3.5 Compiler

Supplier:       GFA Data Media (UK) Ltd
                Box 121
                Wokingham
                Berkshire
                RG11 1FA
                England

Price:          Interpreter #49.95 Sterling
                Compiler    #29.95    "

Those hashes are pound signs, btw; ASCII doesn't support them.  I have
tried to find the suppliers outside the UK, but have received no answers
yet.  The product is advertised in Amiga World, discounted to around $85
(for the Interpreter, I assume) and one of the advertisements suggests that
the US distributor is Antic.

*** Reviewer Info ***
                        Stewart C. Russell
Paper Mail Address:     140 Capelrig Road
                        Newton Mearns
                        Glasgow G77 6LA
                        Scotland

Telephone:              041-639 5372 (in UK)

E-Mail:                 [email-masked]
        (This account should be active until July, when I graduate.)

                        [email-masked]
        (This is my "professional" account.  I get charged for any
         international mail I receive or send, so use only as a last resort.)

[Ed. note:  Mr. Russel has informed me that he can forward any queries to
Les Player, the MD of GFA Data Media (UK) Ltd.  I prefer not to give
Mr. Player's address publicly.]

AmigaBASIC isn't one of the world's marvels of high speed execution.  It
also get bored with the tedium of running your programs sometimes, and
wanders off into oblivion.

The first version of GFA BASIC I saw (v3.041) was fast, but was so bug
ridden as to be completely useless.  In a way, it was like the first release
of the Amiga's operating system; it had something special, but the bugs
made it less than useful.  And now the bugs are (mostly) gone, people
remember it as it used to be - unstable.

GFA BASIC has been long in development, originally appearing on the Atari
ST around 1986.  There is still the lingering feeling that, although the
authors are clearly excellent programmers, they are still not 100% sure of
the Amiga.

What you get
------------

There are at least 300 commands in GFA BASIC, ranging from bit operations
to a file requester.  Most of the inch-thick manual is given over to command
descriptions, with very small program fragments illustrating command usage.
There is no tutorial in the manual, and the lack of properly commented
examples (they are commented - but in German) is worrying.  The manual
suffers from truly appalling translation in places, which can range from
the faintly amusing to the downright misleading.

The GFA BASIC 3.5 interpreter is some 135 KB in length, allowing it to run
comfortably on a basic A500.  Only one program can be edited at a time, but
multiple interpreters can be run.  When this is done, blocks of text can be
cut from one interpreter and pasted to another.

A shorter run-only interpreter is also supplied, and this may be freely
distributed with your programs.  This program only accepts tokenised GFA
BASIC files, and consequently could never be used for program development.

The Front End
-------------

The single-bitplane editor screen has two rows of ten gadgets along the
top, with a clock and a line number indicator on the right hand side.  These
gadgets allow various file operations (Load, Save, etc) and edit operations
(Block, Find, etc).  These gadgets correspond to function and Shift-function
key combinations.

A couple of these gadgets merit special mention.  The Test gadget tests the
integrity of your program's flow control structures, and warns you of any
problems.  The Direct gadget drops you into a command line, where BASIC
commands are executed as you type.  You should be able to work out what the
Run gadget does.

The GFA editor is rather strange.  It parses the input line when you press
Return, and won't let you continue if there is a syntax error.  It also does
not allow blank lines, insisting on an apostrophe at the least.  You'll hate
it at first, but when you realise that it allows abbreviated input (p for
PRINT, inp for INPUT) and automatically indents loop structures, you'll
begin to like it more.  Only one command is allowed per line, and line
numbers must not be used.  In line comments are allowed though, but these
must be prefixed with an exclamation mark.

Functions & Features
--------------------

GFA BASIC knows about most of the commands in the Intuition, Dos, Exec,
Layers, Diskfont Graphics and Icon libraries, and parses them
appropriately; typing in "a%=allocremember(...)" for example would result
in "a%=AllocRemember(...)" being returned.  (The very pedantic would also
note that a syntax error would be returned too; ellipsis is not a valid
input to AllocRemember()... :-) )

If your favourite routines exist in another library, you can use the FD
file to create the basis for a stub.  I've already used this to create
interfaces for the iff.library (for IFF handling) and the medplayer.library
(for playing MED modules).  In this respect, being able to call these
library functions from an interpreted language makes GFA BASIC a great
prototyping tool.

As with most modern BASICs, GFA supports SELECT...CASE structures, and
ELSEIF clauses in IF structures.  All structures support an EXIT IF clause,
which works similarly to "break" in C.

INC, DEC, ADD, SUB, MUL and DIV manipulate variables far more quickly than
the more usual infix operators.  Bitwise operators exist which are similar
to (when compiled, identical to) 68000 instructions.

Windows and Screens are handled well, with HAM and Halfbrite as accessible
as in any other language.  All the Window/IDCMP flags are available too.

Graphics commands are slightly better than AmigaBASIC's offerings; the DRAW
command contains a full turtle graphics package, based on HPGL.  A slight
nasty is the DISPLAY command; this is a hangover from the Atari, where it's
quite safe to switch off Display DMA.  DISPLAY on the Amiga results in
horrific flickering and all-over nastiness; avoid.

Two useful hangovers from the Atari are ALERT and FILESELECT.  ALERT creates
a small requester similar to the GEM Dialog box, and nothing like as
frightening as an Intuition red Alert().  FILESELECT creates a usable file
selector; it's not as good as the ARP one, but it works well.  ALERT and
FILESELECT are not Requesters, so they don't need a window to be attached
to.

Arrays are used in the way that BASIC originally intended; as matrices.
Matrices can be added, subtracted, multiplied, inverted, transposed, copied
(in whole or part, with optional transposition) and the determinant and
rank obtained.  Matrix housekeeping tasks for storing, recalling and
printing matrices are supplied; a reasonable package.

Arrays can also have members inserted, deleted or moved, so dynamic list
handling is a possibility.  Hardcoded quicksort and shellsort routines
(fast) mean that the old bubble sort routine you've trusted since your PET
days can finally be put out to grass.

Sound handling is OK.  I rarely use it though.

Variable Types
--------------

The standard GFA integer is 32 bits long, unlike AmigaBASIC's sixteen which
corresponds to GFA's Word type.  The byte variable type is unique to GFA
BASIC, being identical to C's unsigned char type.  The Boolean type uses
only one bit per entry if used in an array, or one byte otherwise.

This would be fine if GFA hadn't chosen non-standard suffixes for its
variables.  A table shows the problem -

                                             Suffix
 Variable Type                  Microsoft               GFA
 =============                  =========               ===
 Boolean                        (not supported)         !
 8-bit Integer                  (not supported)         |
 16-bit Integer                 %                       &
 32-bit Integer                 &                       %
 Single Precision FP            !                       (not supported)
 Double Precision FP            #                       #
 String                         $                       $

GFA's mathematical routines use a proprietary double precision format as
the default variable type.  It is very fast (see the benchmarks later on)
but unfortunately does not take advantage of a 68881/68882 coprocessor,
since it was originally developed on the Atari ST.

Pointers are handled quite well for a BASIC, but not with the flexibility
of C.  Memory access is enhanced too; the {...} operator can be used to read
and write different types of variable.  Thus

  rp%={WINDOW(0)+50}    could return the address of a window's Rastport
                        structure, and

  CHAR{attr%+8}="diamond.font"  could put a zero terminated font name into
                                a pre-prepared TextAttr structure.

Although structures aren't directly supported, they can be fudged using
Malloc() and the {..} operator.  This is not C, after all.

(In)Compatibility
-----------------

GFA BASIC is compatible with, well, only GFA BASIC I guess.  ASCII files can
be merged into the editor, and anything that isn't understood gets `==>'
placed in front of it.  Screen and window commands differ greatly from
AmigaBASIC, but file handling and OBJECT (Bob) commands are almost
identical.  Sprites, however, merit a separate command.

Major differences between Amiga and GFA BASIC include -

 - "IF...THEN...END IF" is written "IF...ENDIF" (THEN being optional).

 - "GOSUB name" branches to "PROCEDURE name".  Subroutines can have
   parameters, and can be recursive; SUB...STATIC does not exist.
   Procedures can be folded down to one line by hitting the Help key.

 - "DEF FNname(a,b)" becomes "DEFFN name(a,b)".  Multiline recursive
   functions can be defined using FUNCTION, and can be folded using the
   Help key.  Functions can be voided using "VOID func" or "~func".

 - Menu and Interrupt handling is wildly different, and is unfortunately
   identical with the Atari ST's system, which busy waits on signals.  It is
   possible, however, to interrogate IDCMP directly and Wait() on the
   message ports.

If portability is an issue to you, GFA BASIC is available on the Atari ST
and PC, though the latter is still slightly buggy.  OS/2, Windows 3 and
Unix (386) versions are said to be under development.  GFA BASIC 4 should be
with us before the third quarter of 1991, according to Les Player of GFA
Data Media (UK).

(I know of people who run the program on A3000 machines with no ill
effects, and also on Fatter Agnus B2000s. Runs just fine on my A500 too.)

The Compiler
------------

The interpreter is fast, but if you want real speed you need the optional
compiler.  The compiler and linker run from the CLI, but a Workbench
graphical shell is provided.  Maybe it's just the way my machine is set up,
but the GFA shell seldom works properly for me, and I always use the CLI.

The compiler only reads tokenised files, and produces a standard Metacomco
object file ready for linkage.  The GFA linker "gl" is very minimal, and
reads the GFA library and library index in a proprietary file format.
External functions can be linked into GFA programs, and the compiler manual
details how to do this.  The GFA library is also supplied in Metacomco
format if you wish to use a different linker.

Compilation is quick; all of the benchmark test programs actually compiled
in under two seconds.  Most of the time is spent in the linker, since it has
about 150 KB of library to wade through.  All programs are compiled with
code for Workbench and window opening; producing CLI programs requires the
opening of a CON: (or "*") output file and using stream printing.

A large amount of optimisation is done by the compiler, but a good part of
the manual is given over to optimisations that the programmer can include
for better performance.  An example of this is integer multiplication; if
you stick to 16-bit integers, you can set the compiler to use the 68000
MULS instruction.

Verdict
-------

I bought GFA BASIC 3.5 back in October, and have been using it on a daily
basis since then.  If I prototype something using it, it often interprets
fast enough to do the job.  If not, I compile it, and it's fast enough.  If I
really needed extra speed, I'd link in assembly language subroutines.

GFA BASIC isn't bug free yet; but what large product is?  The interpreter
must be 99.5% solid, and the compiled code has never crashed on me.  I trust
it enough to be writing my undergraduate project with it.

If you get C sick, take a long hard look at GFA BASIC.

Benchmarks
----------
(These are at the end since not everyone might want to read them - SCR)

It's easy to say that GFA BASIC is fast, but exactly how fast can only be
demonstrated by comparison with other languages.  HiSoft (Professional)
BASIC is a popular integrated compiler system, and is broadly compatible
with AmigaBASIC.  AmigaBASIC is packaged with every Amiga, and has the
unique ability to run more slowly on a 16MHz 68020/68882 machine than a
7.1MHz 68000 machine.  DICE is Matt Dillon's C compiler, noted for its rapid
compilation and efficient executables.

All times derived from the internal timer routines in each interpreter or
compiler, and then rounded to the nearest quarter second.  Default compiler
options were used in all cases.  The test machine was a 3MB A500/A590.

(If you ask me very, very nicely, and I happen to be in a good mood at the
time (and not too busy either), I can send you the actual benchmark
sources.  You'll have to give me a pretty good reason for wanting them
though.)

CALC

        The old CALC benchmark; 5000 loops of two multiplications and
        two divisions each.  Tests floating point speed and accuracy.  GFA
        uses its own 64-bit floating point format, while HiSoft and
        AmigaBASIC use single precision in this test.
        (An IEEE Double Precision CALC using Matt Dillon's DICE is given
        for comparison.  Out of the four different math packages, IEEE was
        the only one to leave a residual error (of ~-5E-8).  Most odd.)

                GFA     GFA
        Interpreted     Compiled        HiSoft    AmigaBASIC    DICE
        ============================================================

Run Time       5.0        3.0            3.25        16.75      6.5
(seconds)

Compile Time   -         13.5            5.0          -        11.0
(seconds)

Code Size      -         11184          19208         -         7592
(bytes)

I/O TEST

        A small (and not very stringent) test of my own devising.  `Write'
        writes out the integers 1-10000 to a file in RAM:.  `Read' reads
        them back again.  `Print' tests text output by printing 1000 lines
        of 56 characters to the Workbench screen.
        (The RAM: used here is not Commodore's, but The Other Guys'
        Recoverable RAM Disk running FFS.)

                GFA     GFA
        Interpreted     Compiled        HiSoft          AmigaBASIC
        ==========================================================

Run Time
(seconds)

   Write      14.25      12.0           161.0              42.75
    Read       7.75       7.0            20.25             49.75
   Print      37.5       37.25           78.75            149.75

Compile Time   -         14.0             4.5               -
(seconds)

Code Size      -         14496           23096              -
(bytes)

PCW

        A suite of benchmarks used many years ago by PCW Magazine to test
        machine performance when running BASIC.

 PCW1 - FOR k=1 TO 10000:NEXT k, with k floating point
 PCW2 - 10000 GOTOs and 10000 floating point additions
 PCW3 - Floating Point divide, multiply, add, subtract; all 10000 times
 PCW4 - Same as PCW3, but with explicit constants
 PCW5 - PCW4 plus 10000 GOSUBs
 PCW6 - PCW5 plus 10000 "FOR l=1 TO 5:NEXT l"
 PCW7 - PCW6 with an array access in the FOR...NEXT loop
 PCW8 - 10000 additions, exponentiations, LOG()s and SIN()s

                GFA     GFA
        Interpreted     Compiled        HiSoft          AmigaBASIC
        ==========================================================

Run Time
(seconds)

  PCW1         0.75       0.75           1.25               4.0
  PCW2         2.75       0.5            2.5               21.5
  PCW3         7.75       3.0            5.0               43.0
  PCW4         7.5        1.25           5.5               48.0
  PCW5         8.0        1.25           7.25              53.5
  PCW6        13.25       4.0           14.25              90.75
  PCW7        21.5        6.5           23.75             140.75
  PCW8        34.25      29.5           20.75             179.75

 Average      12.0        5.75          10.0               72.75

Compile Time   -         16.0            6.5                -
(seconds)

Code Size      -         15272           22944              -
(bytes)

SIEVE

        The Sieve of Eratosthenes with 5 loops of 7000 short integers each.
        (The DICE benchmark is a slightly different program to the BASIC
        ones, which used GOTO liberally.  The result is the same, though.)

                GFA     GFA
        Interpreted     Compiled        HiSoft    AmigaBASIC    DICE
        ============================================================

Run Time      53.5        3.5            40.75      258.75      1.75
(seconds)

Compile Time   -         17.0             4.5         -        11.0
(seconds)

Code Size      -         11256           19256        -         5732
(bytes)

 %*%* end *%*%

--
|Stewart C. Russell       | University of Strathclyde, Glasgow, Scotland, UK|
[email-masked] |        (opinions my own, not theirs)            |
|                Also known as [email-masked]                   |
|       "Beauty is truth, truth beauty" - Keats                             |
|       "You lying get!" - The Living Carpets, Vic Reeves Big Night Out     |