|Previous Page > Index of General Forth Information > Go Forth and Multiply.|
Go Forth and Multiply from Personal Computer World.
Go Forth and Multiply From Personal Computer World December 1981, page 126.
Basic has done for micro-computing what Henry Ford did for the motor car that is, made it easily and cheaply available to large number of people. There comes a point in the education of many micro-users, however. where an urge is felt to branch out into other languages; this step gets more feasible by the month as compilers and interpreters become available for languages hitherto unavailable on micros. Pascal, Lisp, C, PL/T, APL, Forth, COBOL, the list goes on.
Some users will opt for a language with more sophisticated control structures and more readable code, such as Pascal or COBOL others for the speed and economy of Assembler. Standing at this fork in the road between higher and lower level languages many people have overlooked a less distinct third path, the language Forth,
Developed in the middle 1960s for instrument control application, it was initially only available on mainframe and minicomputers from Forth Inc, a company set up by it's invent is Charles H Moore and his early collaborators. The name came from Fourth generation computer language; unfortunately the Third generation IBM 1130 on which it was developed only allowed Five character identifiers.
The news spread and it developed a devoted 'underground' following among groups who have propagated the language by writing and distributing Forth systems for micros among themselves. Now Forth is beginning to appear 'off the shelf' for many machines and seems destined to join the shortest of popular micro languages.
The attraction of Forth's 'middle road' for micro applications is that it combines speed and memory economy comparable to Assembler with a novel modular program structure which, once mastered, allows much more rapid program development than many high level languages, alone machine code. The price paid is that the source code is not as readable as Pascal or even Basic and that many facilities taken for granted such as strings, arrays and floating point arithmetic are not initially provided (though they can be added at will once you become
Mike Curtis explains the features of Forth which make it an ideal language for small systems.
Go Forth and Multiply From Personal Computer World December 1981, page 127.
fluent). How this happens will only become clear after a little discussion of Forth's unique structure, which is so different from sequentially executed languages like Basic and Pascal that it will provoke quite a major mental reshuffle. In particular you will have abandon any concept of what constitutes a 'program' derived from Basic. At the heart of Forth is a 'dictionary' of around 100 'words' held in memory while the system is active Fifty or so of these words define machine code routines which are linked and executed when the word is invoked; the remainder are defined in terms of these words. Words have names, like ALLOT, ECHO or +. This concept of defining words using previous definitions is crucial to the operation of Forth and is (this is a crude simile) similar to writing a Pascal program as a cascade of nested procedures. The Activity the programmer in a Forth system consists of defining new words which perform functions required in his final application. Once defined these new words are compiled into the dictionary and become Just as much a part of Forth as the 'core' words. They can be tested immediately in direct mode, at the keyboard. The programmer then defines 'higher level' words in terms of these words and so forth (ouch!) until his final 'program' typically consists of a single word. When this word is executed, one of Forth's interpreters looks at its dictionary entry which contains pointers to the words by which it was defined. These in turn contain pointers to the words by which they are defined and so on down to the level of the machine code 'core' words. Each word is 'executed' as it is found so that Forth is neither interpreted nor compiled in the traditional sense, it is both. Thus, Forth enforces the 'top-down' development of programs beloved of structured programming proponents The source listing of a Forth program consists of a series of definitions of new words (all of which are independently executable) leading up to the final application. These blocks of code could be loaded from disk or tape during development together with he Forth 'core', but for crucially memory conserving applications, such as industrial control, anything not needed in the run (which includes the compiler and unused dictionary entries) may be stripped away leaving a minimal necessary system for the job; this may be burned into ROM and can typically occupy as little as 800 bytes.
A great beauty of Forth is then its extendibility or con-tractability. The user extends the language himself in the directions which he requires, or pares the system down to target on a specific application. Having written a Forth program, it is likely that many words created will go on to be used in future programs.
Forth is more than just another programming language, it an be an operating system, incorporating its own compiler, interpreter, assembler, text editor and a rudimentary file management system; in short it provides a complete environment for the writing, testing and using of programs. Basic, of course, also provides such an environment, though not so comprehensive, but Forth has a number of distinct advantages over Basic.
The speed of execution of a Forth program is very much faster than an equivalent Basic program, of the order of ten IMPS as fast. A 16-bit machine should execute a Forth program at virtually the same speed as ordinary machine code, and an 8-bit machine should only be slightly slower, A good compiled Basic may be as quick in some applications but it a always possible to use the assembler option and write Forth definitions directly in machine code where speed is really important. The amount of memory required by a Forth application s also usually much less than with other systems; as with Basic, the entire Forth system is resident in memory the time; on most systems, however, this only requires 6.8k, and that includes the space for the compiled programs. A little more space is required for disc 110 buffers, or pseudo-disk in 4 cassette-based system, but this means that a really good Forth system can he fitted into 16k!. Compare tam with the 48k at least for a decent Pascal system.
Forth is by the very nature modular, interactive and structured; there is no equivalent to a GOTO statement and it is almost impossible to think of an occasion where one could be used, The modular and interactive nature of Forth is particularly useful and important as it means that a program can be developed in small sections which can be separately compiled end tested before using them in larger modules. In practice this leads to a much quicker program development time and fewer bugs. Experience has shown that one should be able to at least halve this time compared to Basic.
The final advantage of Forth, and the one that many feel is the most important, is that the Forth system itself is written in Forth, There are usually only a few bytes that are outside the dictionary, so that the programs that you write, or the words that you define are treated in exactly the same way as the words that are already there. When Forth is searching for a word in the dictionary it starts with the most recent definitions, which gives you the option of redefining any of the system words, or defining your own control structures. A Forth program is, in effect, better thought of as an extension of the system to provide commands and facilities suitable to your application.
This does lead us to one of the disadvantages of Forth, it can be very easy to crash and this is one of the penalties of having the system so open to the user. Some of the more sophisticated systems do have some protection built in, and It is always possible to add your own, but a certain amount of fragility is a natural consequence of the nature of Forth, It is usually easy enough to recover from such a crash without too much damage being done, but if it is bad enough to need a complete reload and you are using 300 baud cassettes...!
The other main disadvantage of Forth, at least as far as beginners are concerned, is its extensive use of stacks and postfix (reverse polish) notation. The difficulty that many people have with this is usually more imagined than real; though there is no doubt that a language like Basic is easier to learn initially, anyone who understands the basic principles of programming should be able to master Forth without much difficulty.
A stack is best thought of as a pile of objects, a common analogy being that of a pile of plates or trays in a canteen. Objects can only be added to the top of the stack, and the only object that can (safely) be removed is the top one. The objects on the Forth stack are 16-bit numbers and the stack provides a convenient place for temporary storage, since the user doesn't have to concern himself with where the numbers are stored, only with the order in which they are stored. Placing a number on the stack is known as PUSHING and removing it is known as PULLING - see Figure 1 for an example.
Part of the documentation for a Forth word should be its effect on the stack, eg, + (n1 n2....sum) indicating that the Forth word '+' expects to find two numbers n1 and n2 on the stack. n2 is on top and the effect of that word is to pull the two numbers from the stack and to push their sum back on.
Postfix notation fits in very naturally with stacks: it involves writing an operator after its operands, so we write 2 3 + instead of 2+3 in ordinary infix notation, or B C + A * instead of A*(B+C). Each operand is pushed onto the stack as it comes, each operator pulls its operands from the stack and pushes its result back on.
It is now possible to have a look at some Forth: if the following sequence is entered at the keyboard: 4 5 (return) OK (OK is the Forth response, output on the same line before the carriage return is echoed) will result in the two numbers 4 and 5 being pushed on the stack, then the + pulls them off, adds them and pushes the sum back on. To see what is on the stack we use the Forth word '.' which prints the top number so:
. (return) 9 OK.Try this
HEX F 2 * . (return) 1E OK
(Warning: everything will be done in HEX from now on until you enter DECIMAL)
Some Forth words do nothing but manipulate items on the stack, eg.
DUP (n1....n1 n1) duplicates the top item on the stack;
SWAP (n1 n2....n2 n1) swaps the top two Items around;
OVER (n1 n2....nl n2 n1)copies the second Item onto the top;
ROT (n1 n2 n3....n2 n3 n1) rotates the third item onto the top;
DROP (nl....) drops the top item.
The major difference between Forth and languages like Basic lies in its use of a dictionary and Indirect Threaded Code (ITC) Direct Threaded Code (DTC) means that a program consists of a list of addresses of pre-written routines, in ITC a program consists of a list of addresses of addresses of routines Provided that the pre-written routines are sensibly chosen so that every programming need can be met by some combination of them, then both methods produce particularly programs because
Go Forth and Multiply From Personal Computer World December 1981, page 128.
the routines act like a high-level instruction set for the processor, and are themselves written in machine code. You thus get a combination of high-level programs running at very nearly the speed machine code, with the advantage over normal compiled languages that each routine, no matter how complicated, reduces to a two byte address, so the programs do not use n much memory. The advantages of ITC over DTC are not clear, and beyond the scope of this article, but it makes it easier to treat the programs as routines that can be included other programs. Forth has, in fact, been implemented in DTC, but the use of ITC is now almost universal.
A Forth dictionary entry contains the following information:
- A name field, which contains the name of the routine (here is very little restriction on the choice of name) and a few other details, such as the length of the name.
- A link field which contains a two-byte pointer to the preceding entry, used when the dictionary is being searched.
- A code field which contains a two-byte pointer to actual machine code which could be the next part of the entry (a code definition), or to a routine that interprets the rest of the entry.
- A parameter field which may contain machine code, addresses of other dictionary entries, variable values, or other information depending on the type of entry.
Writing a Forth program involves the creation of a new dictionary entry, whose parameters are the addresses of the other words that go to make up the new word. There are a number of different ways of doing this, the most common being the COLON definition; the Forth word ':' having been defined to create a new dictionary entry. The word ';' is used to terminate a definition, eg, to convert a temperature in Centigrade to Fahrenheit we must multiply by 9, divide 5 and add 32. We can define a word 'DEGC='; thus:
: DEGC= 9 * 5 / 32 + . ." DEGF" ;
Note the use of spaces; Forth uses spaces as a delimiter so there must be at least one space between every word. The '." ' prints the character string following up to the next " . Note also that there must be a number on the stack before the word is executed since the '*' requires two numbers to be on the stack. The word 'DEGC=' has now been added to the dictionary and may be used in just the same way as any other word; either in subsequent definitions or directly interpreted from the terminal thus.
10 DEGC= (return) 50 DEGF OKor 12 DEGC= (return) 53 DEGF OK
from which you may gather that Forth uses integer (fixed point) arithmetic. There is no standard method of dealing with floating point numbers in Forth, though a number of routines have been published. Many people think that this another disadvantage of Forth, but in practice most Forth programmers don't find it much of a restriction; there are a number of useful words available for integer arithmetic, an example being /MOD (n1 n2....rem quot) which leaves on the stack both the remainder and quotient after a division. Forth also has words for dealing with double length (32-bit) numbers and, at the expense of a little more thought, these give faster, more accurate results than floating point arithmetic.
Variables are not so widely used in Forth programs, since the stack is used for temporary storage; any that are needed must first be defined as dictionary entries, thus:
0 VARIABLE X (return) OK
which defines a word X as a, variable whose parameter field is two bytes long and may be used to store any 16-bit value. When the word 'X' is executed its effect is to leave the address of this parameter field on the stack, values may be stored and retrieved using the words '!' (Pronounced store) and '@' (pronounced fetch). X @ will place the value stored in X onto the stack. While X ! will place the current top of the stack into X.
Other types of variable are possible, but it is up to the programmer to allot enough space in the dictionary (using the word ALLOT) and to write the words necessary to access their values. For example a simple one-dimensional array of ten 16-bit numbers could be defined by:
0 VARIABLE ARRAY 18 ALLOT (18 bytes + 2 bytes assigned by VARIABLE). Execution of the word 'ARRAY' will also place the address of the parameter field (the first element of the array) on the stack, but the word 'ARRAY could be redefined to access all the elements thus:
: ARRAY 1 - 2 * (to work out the byte offset)
ARRAY (uses the previous definition to get the address)
Now, for example, 3 ARRAY will put the address of the third element on the stack. There are other ways of doing this with only one definition, using one of the other methods of creating a dictionary entry, but this is perhaps the easiest to understand.
The usual control structures are available, with the exception of a CASE construction, though there are a number of published versions of this. The major ones are:
IF (true clause) ELSE (false clause) ENDIF where the ELSE and the false clause may be omitted;
DO (routine to be repeated) LOOP which is the equivalent of a FOR .... NEXT loop in BASIC. with a variation using +LOOP for an increment which is not 1;
BEGIN (condition) WHILE (routine) AGAIN
BEGIN (routine) (condition) UNTIL which should be self-explanatory.
Here is an example which illustrates the IF and DO..LOOP constructions, and also shows the way in which a program may be built up in modules, Suppose our ARRAY contains ten marks in an exam, and results must be printed out as PASS (45 per cent or over) or FAIL. First we define a word 'GRADE' which will test the number on top of the stack and print the appropriate message.
: GRADE 45 < (pulls the top two numbers and pushes a 1
if the second is less than the top, 0 otherwise)
IF ." FAIL"
ELSE " PASS"
This can now be tested by, for example:
62 GRADE (return) PASS OK
and it can be then incorporated in:
: GRADES 11 1 (the DO LOOP index, performed ten times,
11 is the value at which it will exit)
I ARRAY @ (I pushes the index onto the stack)
DUP . (to print the mark) 5 SPACES
GRADE CR (to do a carriage return)
To sum up, Forth is not a language for absolute beginners, but it has so many advantages over Basic and similar languages that it should be seriously considered by anyone else. There are now versions of Forth available for most popular micros and a thriving user group, the Forth Interest Group (FIG), publishes a newsletter in the UK. For more information write to: The Hon Sec, Forth Interest Group UK, c/o 38 Worsley Road, Frimley, Camberley, Surrey, GUI 6 5AU.
A very good introductory book, which not only tells you all you need to know about Forth, but also gives an insight into the workings of computers is Starting Forth by Leo Brodie, available for £11.95 from Computer Solutions. Treway House, Hanworth Lane, Chertsey, Surrey, which also supplies a lot of the more sophisticated (and expensive) Forth material.
FIG in the States publishes a magazine Forth Dimension and distributes a lot of material, including Assembler listings for all major microprocessors, Its address is Forth Interest Group, PO Box 1105, San Carlos, CA 94070, USA.