Q L   H A C K E R ' S   J O U R N A L
      ===========================================
           Supporting  All  QL  Programmers
      ===========================================
         #24                        May 1996
      
    The QL Hacker's Journal (QHJ) is published by Tim
Swenson as a service to the QL Community.  The QHJ is
freely distributable.  Past issues are available on disk,
via e-mail, or via the Anon-FTP server, garbo.uwasa.fi. 
The QHJ is always on the look out for article submissions.

   QL Hacker's Journal
     c/o Tim Swenson
     5615 Botkins Rd 
     Huber Heights, OH 45424 USA
     (513) 233-2178
     swensontc@mail.serve.com
     http://www.serve.com/swensont/
     swensont@dgis.dtic.dla.mil


EDITORS' FORUMN

   As time goes by I'm finding myself doing less and less
programming.  My recent foray into distributing QL and
Z88 freeware has kept me busy collecting QL freeware.  Now I
will have the pleasure of trying some of this software out, 
which always takes some time.  I'm still working on getting
QFAX going (after having it for almost a year).  For some
reason QFAX did not talk well to my modem.  I've been
meaning to sit down and figure out the problem, but it has
become one of those get-around-to-it's.

   The only programming I have been doing in some work in
Perl.  Perl is great for some Sys Admin work in Unix and
I've written a few CGI-BIN scripts in Perl.  I'm hoping to
do Perl work full time.

   A port of Perl to the QL may happen and I hope it does. 
Perl is a great language for quick programs.  It's got the
speed of development of SuperBasic but with the power of C,
awk, and SED.   

   In my browsing of the Web I've run across a web site
dedicated to programming.  Besides carring information about
a number of different languages, they also have a section on
"classic" papers.  I downloaded the following papers:

  - What is "Object-Oriented-Programming"?
        by Bjarne Stroustrup
  -  Recommended C Style and Coding Standards
  -  How to Steal Code or Inventing The Wheel Only Once
        by Henry Spencer

   The papers are stored in Adobe Acrobat (.pdf) format and
need an Adobe viewer to view or print out.

   I started reading Bjarne's paper on OOP but have yet to
sit down and go through it all.  It dicusses OOP by starting
with procedural programming, then dicusses data hiding, data
abstractions, and them moves on to OOP.  It looks like this
may actually be the article I've been looking for, that
really discusses OOP in relation to procedural programming.

   I've always found other OOP articles that start of
discussing OOP by defining the OOP terms but not relating
them back to procedural programming.  I need to see OOP in
relation to something that I already know.

   If you want to visit the site, it's at:
      http://www.strangecreations.com/strange/

   Using an older form of browsing, I was looking through my
local library and ran across a book by P. J. Plauger.  Mr.
Plauger used to own Whitesmiths, a C compiler vendor, and
has contributed to "Computer Language" and "C Users Journal"
magazines.  The book is called "Progamming on Purpose III"
and is a collection of "Programming on Purpose" columns he
wrote for "Computer Language."  The topics all deal with
software technology, while the other two books deal with
software design and software people.

   The articles have some good things to say.  They cover a
wide variety of topics and are good idea generators.  Some
of the better articles covered technical writing,
maintaining code, text editors, and user interface issues. 
I'm hoping that the library has the other two books as I am
sure that they are worth the read.

   I'd like to end with one final note; when I started the
QHJ I had hoped that most of the articles would come from
you, the readers, but I was not so lucky.  As it is taking
me longer and longer to produce each issue, I would like to
make a request to some of you might take pity of me in my
plight and pen a few words for this one-man zine.


SOME NOTES ON ARCHIVE
   by Bill Cable

[ This came to me as a letter and not an article - ED]

   I am heavy into really relational databases now.  The
place I work uses Oracle.  They have tables in their
database with 50 million records or rows are they like to
call them.  I finally get to compare ARCHIVE (a quasi
relational database) with the real thing.  One this that is
striking is how the syntax of ARCHIVE like insert, select,
order and so forth are actually the same terms used in SQL
compliant relational databases.  As far as I can tell
anything you can do in a relational database you can also
do in ARCHIVE.  In a relational database it can often be
done directly while in ARCHIVE you will have to write
procedures to do it and often a simple SQL statement can
require a lot of procedures to duplicate.  Still, taking
ARCHIVE and its language you can do about anything you
want.  It may take too long to be practical but you can
still do it.

[ SQL is only a language used to query a relational
database.  ARCHIVE is a relational database and most
resembles dBase (II/III/IV).  When doing queries, both
ARCHIVE and dBase suffer when compared to SQL - ED] 

   In your last QHJ you discuss ARCHIVE a little bit.  It
is a very nice language to use and it is very tight (not
many bugs).  As you mention the _prg files are text files
but the indentations seen in the ARCHIVE editor are not
there.  There is an easy way to get such a listing.  In
ARCHIVE you can list a program using the LLIST command.  It
normally lists to the printer with the indentations shown. 
If you want to send the listing to a file use the SPOOLON
command which will redirect LLIST, LPRINT, and such to a
file or to the screen.  That way you can use LPRINT and
control output from LPRINT to screen, printer, or file.

   So if you have some procedures loaded in ARCHIVE: llist
 will send indented listing to the printer.

   spoolon "ram1_proc_txt"
   llist
   spooloff

   will send indented listing to ram1_proc_txt.  Be sure to
always turn spoolon off or the file is still open and you
can't access it if you haven't quit ARCHIVE yet.

   Spooloff always sets output back to the printer.  You
can spooloff even if you haven't done spoolon without an
error.  A spoolon screen will send output to the
screen instead.

   Unfortunately there is no way for ARCHIVE to ready text
files as when you might want to parse text and turn it into
a database.  If can, of course, read text files in the
standard export format.

   You are right in that ARCHIVE can load indented _prg
files.  One of the more powerful features of ARCHIVE is that
you can have an ARCHIVE procedure write a procedure to disk
and then merge it and use it.  That is one way Ihave my
ARCHIVE programs do things you can't simply precode.


PASSING PARAMATERS

   When I was learning Pascal, one of the hurdles I had to
get over was the concept of paramater passing.  Paramaters
are used when passing data to procedures and functions. 
Paramaters some in two type; "call by value" and "call by
reference."  When you pass operation to a procedure, you
are "calling" that procedure.

   When using procedures and functions, you need to know of
you are calling by reference or value.  Each has different
effects on your program and not knowing the effects can
cause what is called "side effects."

   Call by Value - This means that the value of the
paramater is passed to the procedure.  The procedure only
gets a copy of the data and what ever it does to the data,
it does not affect the original variable.  C defaults to
call by value.  SuperBasic defaults to call by value only
when you use numbers.

   Call by Reference - This means that the variable itself
(or a reference to it) is passed to the procedure.  If the
procdure changes the value of the variable, it is changed
through out the whole program.  C uses pointers to get
procedures to do call by reference.  Superbasic defaults to
call by reference when using variables.

   When programing in C, you know when you are calling by
value or reference.  It is an important part of the
langauge and taught early when learning C.  In SuperBasic
it is not very apparent and not really discussed.  In fact,
I've been programming in SuperBasic for over 10 years now
and I did not know if it used call by reference or value. 
So I decided to play with SuperBasic, read the manual, and
figure this out.

   Below is a simple procedure that takes a variable as a
paramater and increases it by one.  We'll call the
procedure inc for increment.

10 DEFine PROCedure inc ( x )
20   LET x = x + 1
30   PRINT x
40 END DEFine

   When you call the procedure with a literal:

100 inc 20    or    100  inc (20)

   SuperBasic can only use call by value, since there is no
variable to use in a call by reference.

   When you call it with a variable:

      100 inc var

   SuperBasic uses call by reference.  This means that when
you call the prodecure, the value of VAR will increase by
1.  In a way this procedure is working like a function
called like this:

      100 var = inc (var)

   Of course, when you use a function you must use a RETURN
statement.

   If you do not know that SuperBasic uses call by
reference in this instance, then the value of VAR will
increase when you do not want it to.  This is often called
a "side effect" of a procedure.

   If you want to call the procedure with a call by value,
you must tell SuperBasic this.  You can do this by putting
parentheses around your variable, like this:

      100 inc (var)

   Now the procedure inc will get its own copy of VAR to
play with and the real variable VAR will not change.

   The same works with functions.  Since functions need
parentheses around variables used in a call, a single set of
parentheses is used for a call by Reference and a double set
of parentheses is used for a call by Value.


RECENT FREEWARE - CLIPS

   CLIPS is an expert system developed by NASA in 1986.  It
has been ported to the QL by Emiliano Barbaini of Italy. 
CLIPS is an interpretive language like BASIC or Lisp.  Like
Lisp or Prolog, CLIPS is designed for use in artificial
intelligence.

   CLIPS has three ways to represent knowledge:  Rules,
Generic Functions, and Object Oriented Programming (OOP). 
CLIPS supports the 5 features of OOP: classes, message
handlers, abstraction, inheritance, and polymorphism.  Or so
the manual says.

   When I read through the first part of the manual, it
introduced CLIPS by talking about facts and rules.  Facts
are just "words" you tell CLIPS and rules are actions it
takes based on the facts.  Facts are what ever you define
them to be.  Here some examples:

   (assert (bob))
   (assert (animal-is duck))
   (assert (animal-is bob))
   
   Each fact is stored as a literal in CLIPS and no check in
done on it.

   Rules are really IF..THEN statements.  Rules say that if
a given fact exists, then perform some function.  Here is an example

   (defrule animal
     (animal-is duck)
   =>
     (assert (sound-is quack)))

   If the fact (animal-is duck) exists (has been asserted)
then the fact (sound-is quack) will be asserted.  You can
have multiple facts in a rule, the same as using AND in an
IF statement, by listing the facts before the =>.  The same
goes for having mulitple actions in the rule, by listing
them before ending the rule with a closing ).

   CLIPS terminology is a bit different and takes some
getting used to.  CLIPS uses the term field to define a
single element in a fact.  In (assert (bob)), bob is a
field.  In (assert (bob dave)), both bob and dave are
fields.  CLIPS supports the following types of fields:
float, integer, symbol, string, external address, fact
address, instance address, and instance name.

   The manual that comes with CLIPS is really a tutorial. 
The reference manual as not passed to me.  As someone new
to CLIPS it is probably better to have a tutorial instead
of the reference manual, it's makes it easier to learn the
language.

   I have not gone too far into the manual, nor do I know
how far I will go.  I don't see CLIPS used for much everyday
computing on the QL, but it does have the potential for
letting a QLer explore the non-everyday areas of computer
science.

   To get an idea of what one can do with CLIPS, the
Proceeding from the first three CLIPS Users Conference are
included at the back of the manual.  Some of the area
covered are:  "Three CLIPS-based Expert Systems for Solving
Engineering Problems", "Using CLIPS in a Distributed System
- the Network Control Center (NCC) Expert System", "Space
Shuttle Systems Monitoring: Real-Time Telemetry Processing
Using CLIPS", "A CLIPS Expert System for Maximizing
Alfalfa", "MOM - A Meteorological Data Checking Expert
System in CLIPS", and "Using a CLIPS Expert System to
Automatically Manage TCP/IP Networks".  It looks like CLIPS
can be used for a variety of applications.  

   CLIPS is a 500K executable and requires an expanded QL. 
I have a Gold Card on my QL and it works fine.  I have not
tested it on a 640K QL.  CLIPS is available via QHJ
Freeware (same address as the QHJ).  Send a disk and return
postage and it is yours.  The FTP site maya.dei.unipd.it
seems to be down, so Emiliano did not put it there.  If a
request is made, it can be put on ftp.nvg.unit.no in the QL
subdirectory.


HOUSE OF CODING STYLE

   I was recently doing some CGI-BIN programming in Perl. 
Since I was new to CGI-BIN programming, I did what every
other programmer does when he is new to something, he
borrows somebody elses code to see how it is done.  I
borrowed come Perl CGI-BIN code from our local CGI-BIN
expert at work.

   When writing my code I tried to stay close to the style
that he was writing in.  I did notice that he has a style
that is very different than mine.  He likes to put any long
sections of code in a subroutine.  Where as I do not like to
break up these sections in to subroutines.  My code looks
kind of like this:

    --------------
    --------------
    --------------
    IF ....... THEN .....
       ------------
       ------------
       ------------
       ------------
       IF ...... THEN ......
          -----------
	  -----------
	  -----------
	  -----------
    ELSE
      ------------
      ------------
      ------------
      ------------
    END IF
    -------------
    -------------
            
   Where as his code looks like this:
   
    --------------
    --------------
    --------------
    IF ....... THEN .....
       Call Subroutine1
    ELSE
       Call Subroutine2
    END IF
    -------------
    -------------
    
   where the code in the IF-THEN-ELSE constructs were moved
to two subroutines.

   Now none of these subroutines were going to be called
from more than one place in the code.  I prefer to write
subroutines only when they save writing the same code in
different part of the program.  To me subroutines are
designed to save the amount of code you are writing.

   My friends idea of subroutines is to make the main part
of your code shorter and easier to read.  This is fine if
the sections of code that you are going to move into a
subroutine are fairly long.

   I prefer to not use a subroutine unless I need to write
the same code many places.  For me the subroutines break the
flow of the structure of the program.  I view it sort of
like parsing a tree.  Just as with a left- or right-handed
rule, you keep moving down a tree until you come to a leaf
node and then you back up and take the next branch, coding
flows out like a tree structure going down all of the
IF-THEN statements until an end is reached and then brought
back up the tree with and END IF statement.  One never
parses a tree by individual levels of depth at a time.

   I wanted to bring this up because it shows two distinct
coding styles and why they are done that way, and maybe it
will get you thinking about your personal coding style and
how you feel about it versus others.

          
RECENT FREEWARE - REXX

   The REXX language was derived from a batch language on
the IBM System/370 called EXEC 2.  It has since become a
standard language for OS/2 with implementations on other
platforms, including the Amiga.  A version of REXX has been
ported to the QL.

   REXX is a procedural language like BASIC, C, Pascal, etc.
and its code has the same look as these languages.  REXX
seems to have the same constructs for writing a program,
such as conditional statements, looping statements, input,
output, etc., as the above languages, it just does it a
little differently.

   A beginning REXX program is like this:
   
      pull a
      b=a*a
      c=1/a
      d=3+a
      e=2**(a-1)
      say 'Results are:' a b c d e
      
   Pull is equivalent to INPUT and say is equivalent to
PRINT.  The assignment statements are the same format as
BASIC.

   REXX supports untyped data in the same way that Perl
does.  A variable can hold either string or a number.  The
following program demonstrates how this can work:

      a = 'A String'
      b = '123'
      c = '456'
      d = a ":" (b||c)*3
      say d
      
   The results will be:   "A String: 370368".  The function
|| concatenates the two strings, which is a number so it can
be multiplied by three.  This is then added with a variable
holding a string and a string constant to get the final result.

   REXX has a variety of loops and conditional loops.  Here
are a few:

      do 10               (repeat 10 times)
         say "hello"
      end

      do c= 1 to 20     ( FOR C = 1 TO 20 ) 
         say c
      end
      
      do until var = 10
         .......
      end
      
      do while error = 0
         .......
      end
      	         
   As you can see REXX is a fairly verbose language and is
fairly easy to read (unlike the terseness of C or FORTH). 
Most of the example programs are things that can be done in
other languages, it's just a matter of figuring out how to
do them in REXX.

    The version of REXX for the QL is a 500K executable, so
it will require an expanded machine.  I don't know what the
lower limits are to run REXX.  I have tested it on a QL with
a Gold Card and it runs just fine.

    REXX is an interpretive language, like BASIC, but this
implementation is not an interactive interpreter.  If you
execute REXX with no arguements, it will essentually do
nothing.  To run a REXX program, you have to exec REXX with
the arguement of the program you want to run.  Of course,
this means you need to have TKII.

   To exec REXX with the example animal_rexx program
included, you would do this:

      exec rexx_exe;"animal_rexx"
   
   This will execute REXX and load in the REXX program
animal_rexx. 
    
   The QL version of REXX comes with a simple tutorial for
beginners and a longer fuller document that does into
greater detail about REXX.  Since REXX is popular for OS/2
and Amiga, there are a number of sources on the Internet.

   There really is not much else to say about REXX.  If you
are looking for another language to play around with, here
is a good one.  If you are looking to learn REXX to use on
other platforms, this version of REXX should do the job.  At
the very least it give the QL programmer one more option.
   


    Source: geocities.com/svenqhj