Abundance : Java Glossary

*0-9ABCDEFGHIJKLMNOPQRSTUVWXYZ (all)
I have left this tombstone entry for historical interest.

Abundance
A public domain, DOS-based experimental computer language designed in 1979 and first implemented in 1981 that in many ways is still more advanced than Java. It was featured in Byte Magazine in 1986-10. The language was named by Esther Palivoda of the Canadian Hunger Project. I originally planned to call it Enough. It invented it to tackle a huge project I had volunteered for. I knew I would never complete it in reasonable time with conventional tools.

Purpose

This document gives you a broad overview of the more exotic features of Abundance. These exotic features must be understood as they are used in even the most mundane programs. This document is roughly what I submitted to Byte Magazine back in 1986-04. They edited it severely and published it in 1986-10. They own the copyright on both this version and the published version, so if you wish to publish any part of this, you will have to get permission from them.

What Is Abundance

Abundance is a Forth-based, data-entry, data-base and screen-handling language. It automatically handles the routine housekeeping that normally accounts for 90% of interactive application code. All Abundance programs can Jaunt — run backward in time. Abundance is not an acronym. It was originally designed to serve charities working to create an Abundance of food water and shelter on the planet; but because it has such an Abundance of features, it has now become an excellent business programming language.

What Is a Rich Language?

Abundance is a rich language. It has 600 verbs of its own, 400 inherited from Forth-83, 300 inherited from assembler and 900 hidden verbs. Conventional wisdom posits that languages should be lean. For example Pascal has about 20 keywords. Working with lean computer languages is like speaking with someone who understands only 20 words of English. Even Esperanto, an artificial human language designed for simplicity, has 15,000 root words.

Why a Rich Language?

We would laugh at a robot that broke through a door simply because we forgot to tell it to open the door first. We expect robots to know that doors need opening. I think compilers should be equally brilliant and remember to do things without being explicitly asked to, such as opening files, validating data entry, converting values back and forth between binary and ASCII (American Standard Code for Information Interchange), keeping track of how many elements are used so far in an array, reading and writing to disk, or laying out fields in columns on the screen appropriately labeled. If I recompute a variable that happens to be currently displayed on the screen I expect the compiler to automatically refresh the screen with the new value just as a spreadsheet would.

I expect my compiler to understand the Zip Code system, the telephone numbering system and the States of the union; and be able to cross check all three. Furthermore, I expect my compiler to know this information not only for the USA, but for other countries as well. I want it to know that phone numbers need a dash in the middle and area codes are surrounded in parentheses. It should even know that 555-1212 is not the phone number of any real person.

I expect my compiler to know the calendar. It must know that 1900 was not a leap year and that 2000 will be. (Lotus take note!) It should know that the people in India use DD/MM/YY and Swedes use YY.MM.DD. But most of all, I want my compiler to take the initiative and use this knowledge without my having to explicitly ask it.

I expect it to understand the limitations, quirks and control sequences of at least 20 brands of printer. I don’t want to be bothered with such detail. As a programmer I want to pretend I have a perfect printer that can print in any pitch, in any typestyle, any of the 256 accented and special characters. I want to be able to use words like ITALIC, BOLD, WP-QUALITY and have the compiler do the best it can. (Windows has since taken over this task.) It should be able to number my pages 1 of 20.

I expect my compiler to speak to end users in English, French, Swedish or Esperanto. I should be able key all the accented characters without resorting to the numeric keypad. I want my compiler to be able to interface elegantly with other packages such as Btrieve, Lotus-123, VP-Planner, Microsoft Word Mail Merge, Ready!, Opt-Tech Sort, Superkey and Prokey.

Abundance — Rich Language

Abundance is such a compiler. It has been performing these feats in a production environment since 1981. It handles the bulk of the programmer’s housekeeping chores implicitly. It does not use artificial intelligence techniques; it simply performs extra work as a side effect of the work you explicitly ask it to do. However, Abundance is not paternalistic. If you want explicit control of any of these housekeeping tasks, you can take as much control as you want. Because Abundance is a superset of both 8086 Assembler and 32-bit Forth-83 and because all the hidden verbs that form the compiler itself are always available, you can interface at any level you want.

What Abundance is like for the End User

Abundance was originally designed in 1981 for The Hunger Project in Canada, a charity committed to ending world hunger by the year 2000. Now charities in Australia, Canada, India, Sweden, and the USA are running public-domain custom-written Abundance application programs. Volunteers (including my 66-year-old mother) can do data entry into Abundance applications after only 5 minutes of training. The end user sees a traditional full-screen layout indistinguishable from one hand-crafted in C, sometimes with pretty boxes, but more commonly in columns or rows with data labeled with the corresponding variable names. Abundance makes full use of all the highlighting or color capabilities of the screen. Every time an Abundance application wants the user to keyin data, it highlights the field in inverse video and plops a oversized blinking cursor on the first character of the field. It then produces a uniform prompt message across the bottom two lines of the screen. The prompt always contains the name of the variable being keyed, the lower and upper acceptable bounds, (or a list of possible choices), what sort of data is wanted (a Name, a Zip Code, a date, a number, a dollar value etc.) and usually some additional explanatory information. In addition Abundance maintains CapsLock, Shift and Numeric keypad indicators.

The user can use the backspace, arrow keys and the function keys in a way that mimics his favorite word processor to edit the data. If he gets lost, he can hit the Oops key that puts the field back the way it was. Any errors in keying are usually detected the instant they are made. Abundance makes various polite sounds for different classes of warnings and errors. From these auditory clues the experienced user does not even have to look at the error messages to figure out what he did wrong. Abundance works in the background, hitting the shift key for the user when he forgets to, jumping over the dash in a phone number and keeping numbers right justified (calculator style) as they are entered.

If the user realises he should have entered some different value in a prior field, he can hit the Up-arrow key and make the program run backward in time. He can then enter a new value for the prior field and use the Down-arrow key to run the program forward in time and carry on where he left off. Later on in the article I will explain how this magical, but totally necessary feature, called jaunting is implemented. The user can also hit the Escape key at any time. In general this will cause the application to gracefully stop what it is doing in such a way that all files are logically consistent and no data are lost. Abundance was designed with the presumption the end user would be a naïve volunteer, but it is responsive enough that it can keep up with even the fastest professional data entry clerk.

Jaunting

Jaunting is the ability that all Abundance programs have to run backward in time. Jaunting sounds like an esoteric and frivolous feature, something I dreamt up after a late night TV Dr. Who marathon. A little history about the invention of jaunting may dispel this notion. I wrote Medics, a proprietary billing program for physicians to deal with the socialized medicine bureaucracy; as expected the data entry rules were Byzantine. I first considered the IBM (International Business Machines) Cobol or Macintosh Pascal approach, namely let the user wander all over the screen entering data in any order he wants, doing only minimal field edits. Only after he has entered a whole screenful of data, does the program perform the cross field checks and ensure all necessary fields have been entered. I rejected this approach because it was user-hostile, so I elected to use another approach favored by (shudder) Basic, namely lead the user by the hand field by field.

Then the embarrassment started. During a demo a doctor asked, "How do I go back two fields and enter 3333 instead of 100 for the Fee-Code field? I then had to humor" the computer by finishing off the current entry with dummy data. My extensive error checks beeped and blatted at me as I tried to drag the program around to a point where I could re-enter the Fee-Code field. Needless to say, the doctor did not buy the package. I needed a way of being able to easily back up two fields and keyin different data and then carry on where I had left off. The doctor knew computers were capable of such a triviality.

Jaunting was invented to solve this problem. I first invented a half-hearted form of jaunting similar to the one used by Forms-11 for the DEC (Digital Equipment Corporation) PDP-11. Abundance application constantly monitored whether the user had recently hit the Up-arrow key. When he hit the Up-arrow key the program jumped back to allow the user to rekey the previous field. This solved the problem for the user, but created a nightmare for the programmer. My source code turned into a rat’s nest of undebuggable backward branches and nested loops. To get around the problem of rat’s nest code, I invented true jaunting similar to the approach used in FDL (Forms Development Language) (Forms Development Language) that ran on the BMT (Burroughs Modular Terminal). Abundance application programs are written as though the user entered perfect data the first time every time. An Abundance application is perfectly unaware that sometimes it runs backwards in time.

How jaunting is implemented

Jaunting is simply a very streamlined version of the IBM OS/370 checkpointing facility. Every time the user keys in a field, the Abundance compiler secretly takes a snapshot of the state of the application program. When the user hits the Up-arrow key, the Abundance compiler finds the appropriate old snapshot of how the application used to look, inserts it as reality and wakes up the application. The application then carries on with amnesia as if it had never been any further than that. The implementation has no perceptible overhead. It is quick because there is no need to take a snapshot of all of RAM (Random Access Memory). Just the tiny Data Stack, the Return Stack and a few critical Abundance internal state variables need be saved. As all Forth programmers know, the Data Stack holds temporary variables and parameters passed to procedures; and the Return Stack keeps track of which procedure called which procedure. Surprisingly, the values of the variables are not saved as part of the snapshot. If the Abundance compiler did save the variables and then restored them to the old state after jaunting back in time, the end user would be furious because his newly entered data would have been thrown away. When an application program wakes up after its jaunt back in time, the values of the variables keyed just prior to jaunting are intact. You might think it would hopelessly confuse the application program to wake up after the jaunt and find the variables it is just about to request to be keyed are already entered, but in practice this rarely causes trouble.

MUSTs and WARNs

Once jaunting was invented I discovered it had some wonderful fringe benefits. An Abundance application can assert that a certain expression just MUST be true no matter what e.g. that three fields simply have to add up to 100%. The Abundance compiler, on detecting that one of these MUSTs has failed, puts the blame on some earlier keyin and jaunts the program back in time to let the user have another go at keying the culprit field. The programmer can optionally give the compiler hints as to which field he thinks the culprit might be, but even if he guesses incorrectly, the user can use the Up and Down Arrow keys to correct the real culprit. There is a variant of the MUST called the WARN that makes an eh? noise (I am Canadian) and asks him to confirm that this unusual condition is indeed OK. If the user answers No, the program jaunts back in time just the way a MUST would. here is an example of an Abundance application program that uses jaunting and MUSTs. Jaunting allows you to exaustively test programs by exercising a bit of code, jaunt back a few steps and test another flow of control.

(Figure 1 Abundance )
( This program queries your motives for joining a health club. )
( It demonstrates the use of Jaunting back in time. )
( Anything in parentheses is a comment )
( Note : the space after the " is intentional! ).
<<<DEFINE
                                        MFB CHOICE  Sexual-Preference
                                    ME ( Must Enter )
 M=prefer Males   F=prefer Females   B=prefer Both
                                              EXPLAIN
 ( Declare a 1-byte variable that can have only the )
                                  ( values M F or B )
                                          0 100 SMALL  %-For-Health
 What % of your reason for joining the club was to improve your health
                                              EXPLAIN
                ( declare a 1-byte numeric variable )
             ( Abundance transparently enforces the )
                                    ( limits 0..100 )
                                          0 100 SMALL  %-For-The-Males
 What % of your reason for joining was to meet handsome males?
                                              EXPLAIN
                                          0 100 SMALL  %-For-The-Females
 What % of your reason for joining was to meet beautiful females?
                                              EXPLAIN
DEFINE>>>
<<< VALIDATE-Percentages
    ( a procedure to validate all three percentages. )
    CULPRIT Sexual-Preference
    ( Hint to compiler that misunderstanding the sexual preference )
    ( question is likely the culprit if any subsequent MUST fails.)
    FROM %-For-Health %-For-The-Males + %-For-The-Females +
    ( postfix addition leaves the sum on the stack )
    100 = ( postfix comparison operator leaves True if the sum=100 )
    Percentages must add up to 100 MUST
    ( If MUST sees a false it jaunts back in time )
    ( to where the culprit Sexual-Preference was keyed )
    ( in the routine HEALTH-Club, [not to the CULPRIT statement] )
    ( and issues the error message,  otherwise it does nothing. )
    ( The end user can go still further back in time than we )
    ( take him, by hitting the Up arrow key.  If we take him back )
    ( too far, he can come forward in time by hitting the Down )
    ( arrow key. )
>>>
<<< HEALTH-Club
    ( The mainline procedure. )
    ( At any point the end user can hit the Up-Arrow key and )
    ( run the program back in time to the previous question.  He )
    ( can then answer differently.)
    ( Depending on how the end user answers the sexual )
    ( preference question, he is asked different percentages )
    KEYIN %-For-Health
       ( Abundance generates a prompt using the variable name )
       ( %-For-Health, the EXPLAIN string " What % of your )
       ( reason for joining the club was to improve your )
       ( health" and the limits 0..100.  It invokes a mini word )
       ( processor to help the user enter the number.  The )
       ( number automatically stays right justified as it is )
       ( entered.  All conceivable validations are performed. )
    ASK Sexual-Preference
       ( Similarly Abundance prompts for one of the letters )
       ( M F or B leaving the result on the stack )
        CASE ( examine character on the data stack )
             _ M OF ( prefers males )
                   KEYIN %-For-The-Males CLEAR %-For-The-Females ENDOF
             _ F OF ( prefers females )
                   KEYIN %-For-The-Females CLEAR %-For-The-Males ENDOF
             _ B OF ( prefers both )
                   KEYIN %-For-The-Males %-For-The-Females ENDOF
        ENDCASE
     VALIDATE-Percentages ( invoke cross-field verification )
 >>>

Implicit Array Subscripts

In a traditional programming language, for every ArrayOfRecords Xyou declare, you need to declare three other variables. ArrayMax M: the maximum size the array can ever be (usually a constant), ArrayHighWater N : the number of slots in the array currently containing data and ArrayIndex J: the element of the array we are currently working on. Then you refer to X(J) over and over again. You rarely use any other subscript other than (J). Every once in a while you do use some other index by mistake and then spend 3 days trying to find the bug in your program! You have to manually maintain ArrayHighWater N and make sure ArrayIndex J stays safely in bounds. You have to explicitly mention J and N in every FOR J := 1 TO N loop that runs through the elements of the array (yet another place for bugs to creep in.) Abundance’s approach is to dispense with all but the array index J. X N and M all go. Only J is used. Abundance invisibly maintains the ArrayHighWater N and corrals an errant index J back into bounds. There is no need to say (J), this is just presumed. There is no need to mention anything other than the Array index in a <<<FOR J loop since Abundance keeps track itself of the array high water mark. A program to handle a single record can be converted to handle an array of records simply by changing the declaration. No procedural code need be changed. All that need be added is one line of code to set the implicit subscript. The equivalent transformation in a Pascal program would change nearly every line of code. The best way to understand implicit subscripts is to scrutinize Figure 2.

( Figure 2 Abundance implied subscripts )
( How Abundance uses implied subscripts in arrays. )
( This program stores the Names and Birthdates of two )
( dependent children in an array big enough to hold up to 15 )
( dependents.  Then it prints them out. )
   <<<DEFINE
                                    1 15 <<<FLEX  Dependent-Number
      ( Declare an array with 0 to 15 elements )
( indexed 1 .. 15 implicitly by Dependent-Number. )
     ( Abundance transparently tracks the High )
        ( Water mark of the implicit subscript.)
        ( This way it always knows how many of )
        ( the 15 slots currently contain data. )
 ( Abundance transparently enforces the limits )
           ( 1 .. 15 on the implicit subscript. )
  ( Note that the array itself does not have a )
                                       ( name. )
                                          30 ULS  Child’s-Name
  ( Declare a upper/lower case string variable )
        ( as one of the elements of the array. )
          ( Abundance transparently enforces a )
                ( no-accented-characters rule. )
               1950 01 01 JULIAN ( lower bound )
                           Today ( upper bound )
                                          MMDDYY  Child’s-BirthDate
                     ( Declare a date variable )
        ( as one of the elements of the array. )
( Displayed as MM/DD/YY externally, but stored )
( as a 16-bit unsigned Julian Date internally. )
  ( Abundance transparently enforces the upper )
         ( and lower bounds and date validity. )
                                         FLEX>>>
                          ( marks end of array )
DEFINE>>>
<<< SETUP-Dependents
    ( procedure to initialize the elements of the array )
    1 TO Dependent-Number ( set the implicit subscript )
        Bruce TO Child’s-Name
        ( implied [1] subscript )
        1954 03 26 JULIAN TO Child’s-BirthDate
    2 TO Dependent-Number
        Brock TO Child’s-Name
        ( implied [2] subscript )
        1961 07 18 JULIAN TO Child’s-BirthDate
 >>>
<<< PRINT-Dependents
    ( procedure to print all existing dependents )
    EJECT ( start a fresh page if not on one already )
    <<<FOR Dependent-Number
        ( Loop to run through all existing dependents. )
        ( Abundance has transparently tracked the highwater mark )
        ( so it knows the loop should run from 1 .. 2. )
        ( Each time through the loop <<<FOR )
        ( increments the implicit subscript Dependent-Number )
        WRITE Dependent-Number SPACE Child’s-BirthDate 2 SPACES
             Child’s-Name NL
        ( implied [Dependent-Number] subscripts )
        ( From the variable declarations, Abundance knows how )
        ( to format the printout.)
   FOR>>>
   EJECT ( start a fresh page )
 >>>
<<< DEPEND
    ( mainline procedure to initialize and print )
    SETUP-Dependents
    PRINT-Dependents
>>>

File Handling

To an Abundance application, a file is just a big array that is a little too fat to fit in RAM. You as a programmer read and write the records simply by changing the implicit array subscript which indexes which record you want to work on. Smalltalk style, Abundance automatically handles blocking and deblocking, reading, writing, opening, closing, caching and dirty bits. Abundance does everything it can to avoid doing physical disk I/O. Abundance handles standard DOS (Disk Operating System) files with fixed length records, but it has other tricks up its sleeve if you want higher performance. The program in Figure 2 can be converted to one that keeps the data in a file instead of an array simply by changing the word <<<FLEX to <<<SEQ and adding an external DOS file name and logical record length. i.e. C:Dep.Dat 256 1 15 <<<SEQ Dependent-Number. The equivalent changes to Pascal program would necessitate a complete rewrite.

( Figure 4 How to handle arrays/files in Abundance )
( How Abundance uses Implied subscripts to handle files. )
( This program stores the Names and Birthdates of two )
( dependent children in a standard  DOS
  file allowed to grow )
( big enough to hold up to 15 dependents. )
( Then it prints them out. )
   <<<DEFINE
             C:Dep.Dat ( external file name )
             32 ( logical record size in bytes )
                ( Usually you would leave room )
         ( for new fields to be added in place )
                                     1 15 <<<SEQ  Dependent-Number
         ( Declare a file with 0 to 15 records )
( indexed 1 .. 15 implicitly by Dependent-Number. )
   ( Note that the File itself does not have a )
                                       ( name. )
                                          30 ULS  Child’s-Name
               1950 01 01 JULIAN ( lower bound )
                           Today ( upper bound )
                                          MMDDYY  Child’s-BirthDate
                                          SEQ>>>
DEFINE>>>
<<< SETUP-Dependents
    ( procedure to initialize the elements of the array )
    1 TO Dependent-Number
        ( as a side effect record 1 is read )
        Bruce TO Child’s-Name
           ( as a side effect, record 1 is marked Dirty )
           ( Abundance thus knows to write it sometime later. )
        1954 03 26 JULIAN TO Child’s-BirthDate
    2 TO Dependent-Number
        ( as a side effect record 1 is written and 2 is read )
        1961 07 18 JULIAN TO Child’s-BirthDate
        Brock TO Child’s-Name
 >>>
<<< PRINT-Dependents
    ( procedure to print all existing dependents )
    EJECT
    <<<FOR Dependent-Number
        ( as a side effect, the appropriate record is read )
    WRITE Dependent-Number SPACE Child’s-BirthDate 2 SPACES
             Child’s-Name NL
    FOR>>>
    EJECT
 >>>
<<< DEPEND
    ( mainline procedure to initialize and print )
    SETUP-Dependents
    PRINT-Dependents
>>>
{ Figure 3 Abundance Pascal Arrays }
Program Depend;
{ How Pascal uses explicit subscripts in arrays }
{ This program stores the Names and Birthdates of two }
{ dependent children in an array big enough to hold up to 15 }
{ dependents.  Then it prints them out. }
Const MaxDependents = 15;
   { the maximum number of dependents we could ever possibly have }
Type
  Dependent =
        Record
        ChildsName : String[30];
        ChildsBirthDate : Packed Array [1 .. 8] OF Char
          { stored MM/DD/YY as character }
          { should be between 1950 Jan 01 and Today }
          { this program does not enforce this }
        End; { Record }
Var
HighWaterDependents : 0 .. MaxDependents;
   { how many dependents we currently have }
DependentNumber : 1 .. MaxDependents;
   { index of the dependent we are looking at now }
Dependents : Array [1 .. MaxDependents] of Dependent;
Procedure MaintainHighWater;
   Begin
   { corral a bad subscript back safely in bounds }
   If DependentNumber < 1
      Then DependentNumber := 1;
   If DependentNumber > MaxDependents
      Then DependentNumber := MaxDependents;
   { Keep track of the largest subscript used so far }
   If DependentNumber > HighWaterDependents
      Then HighWaterDependents := DependentNumber
   End; { MaintainHighWater }
Procedure SetupDependents;
   Begin
      DependentNumber := 1;
         MaintainHighWater;
         Dependents [DependentNumber].ChildsName := 'Bruce';
         Dependents [DependentNumber].ChildsBirthDate := '03/26/54';
      DependentNumber  := 2;
         MaintainHighWater;
         Dependents [DependentNumber].ChildsName := 'Brock';
         Dependents [DependentNumber].ChildsBirthDate := '31/12/61'
   End { SetupDependents };
Procedure PrintDependents;
   Begin
   For DependentNumber := 1 To HighWaterDependents DO
       Begin
           Writeln (Lst,DependentNumber:2, ' ',
              Dependents [DependentNumber].ChildsBirthDate, '  ',
              Dependents [DependentNumber].ChildsName)
       End; { For }
   Write(Lst, Char(12)) { eject the paper — works on most printers }
   End; { PrintDependents }
  Begin { Depend }
     HighWaterDependents := 0;
     SetupDependents;
     PrintDependents
  End. { Depend }
{ Figure 5 pascal files }
Program Depend;
{ How Pascal uses explicit seeks/reads/writes to handle files. }
{ This program stores the Names and Birthdates of two }
{ dependent children in a standard  DOS
  file allowed to grow }
{ big enough to hold up to 15 dependents. }
{ Then it prints them out. }
Const MaxDependents = 15;
   { the maximum number of dependents we could ever possibly have }
Type
  Dependent =
        Record
        ChildsName : String[30];
        ChildsBirthDate : Packed Array [1 .. 8] OF Char
          { stored MM/DD/YY as character }
          { should be between 1950 Jan 01 and Today }
          { this program does not enforce this }
        End; { Record }
Var
HighWaterDependents : 0 .. MaxDependents;
   { how many dependents we currently have }
DependentNumber : 1 .. MaxDependents;
   { index of the dependent we are looking at now }
ADependent : Dependent;
   { working storage record for current dependent }
Dependents : File of Dependent;
Procedure MaintainHighWater;
   Begin
   { corral a bad subscript back safely in bounds }
   If DependentNumber < 1
      Then DependentNumber := 1;
   If DependentNumber > MaxDependents
      Then DependentNumber := MaxDependents;
   { Keep track of the largest subscript used so far }
   If DependentNumber > HighWaterDependents
      Then HighWaterDependents := DependentNumber
   End; { MaintainHighWater }
Procedure ReadRecord;
   { reads record indexed by DependentNumber into ADependent }
   Begin
      MaintainHighWater;
      If DependentNumber > FileSize (Dependents)
         Then  { Record does not yet exist — fake it }
            Begin
            ADependent.ChildsName := ' ';
            ADependent.ChildsBirthDate := '        '
            End
         Else  { Record already exists }
            Begin
            Seek (Dependents, DependentNumber-1);
            Read (Dependents, ADependent)
            End
   End; { ReadRecord }
Procedure WriteRecord;
   { writes record indexed by DependentNumber from ADependent }
   Begin
      MaintainHighWater;
      Seek (Dependents,DependentNumber-1);
      Write (Dependents,ADependent)
   End; { WriteRecord }
Procedure SetupDependents;
   Begin
      DependentNumber := 1;
         ReadRecord;
         ADependent.ChildsName := 'Bruce';
         ADependent.ChildsBirthDate := '03/26/54';
         WriteRecord;
      DependentNumber  := 2;
         ReadRecord;
         ADependent.ChildsName := 'Brock';
         ADependent.ChildsBirthDate := '18/07/61';
         WriteRecord
   End { SetupDependents };
Procedure PrintDependents;
   Begin
   For DependentNumber := 1 To HighWaterDependents DO
       Begin
           ReadRecord;
           Writeln (Lst,DependentNumber:2, ' ',
              ADependent.ChildsBirthDate, '  ',
              ADependent.ChildsName)
       End; { For }
   Write(Lst, Char(12)) { eject the paper — works on most printers }
   End; { PrintDependents }
  Begin { Depend }
     HighWaterDependents := 0;
     Assign (Dependents,'C:Dep.Dat');
     Reset (Dependents);
     SetupDependents;
     PrintDependents;
     Close (Dependents)
  End. { Depend }

Scaffolds

There is never enough room on the screen to simultaneously display everything you want to show. You may only have room to show the detail of 4 transactions, when you would like to show 40. You need to be able to scroll so that you show any of the 40, but only 4 at a time. In traditional languages handling this scrolling is very complex. Scaffolds come to the rescue. All the programmer has to do is write the name of a particular scaffold as part of the declaration of a variable element in an array. Scaffolds might be names such as 2x6 for two rows of six columns, or 4Deep for rows with a maximum 4 elements at a time displayed. From then on Abundance monitors the implicit subscript of the array. It makes sure that the current element is always visible on the screen. As the subscript changes, Abundance scrolls the display as a side effect so that the end user can always see the current element, some preceding and some succeeding elements of the array. Other than the declaration, the application code is totally unaware that this scrolling is going on. It simply comes out in the wash that the element of the array you are keying or computing is always visible. Scaffolds can be any shape you have the mathematical ingenuity to describe — not just simple rowed windows.

Other Features

This article has barely touched on the main features of Abundance. Abundance has scores of other novel features with colorful names like humps, jives, combos, anchors, gauntlets, living fields, fast forwards, variable variables (note to editor: Yes you read it correctly variable variables), moods, promises, safes, riktnummers and graceful bailouts. It even uses a number of four-letter verbs of Anglo-Saxon origin.

Hardware Needed

If you want to experiment with Abundance you will need Microsoft or IBM PC (Personal Computer) DOS 3.2 or later running on an IBM PC, XT or AT (Advanced Technology) or a close clone. You will need at least 384K of RAM and a hard disk. The applications you write can run on floppy disk systems however

What You Get

I am no longer shipping Abundance. You would have to get a copy elsewhere. It is still running in production though I am gradually moving Abundance apps to SQL/Java so that they can be maintained by other programmers after I die.

Abundance source and documentation comes diskettes in IBM Backup/Restore format. You are strongly encouraged to copy the diskettes and give them away to your friends. There are no restrictions on how you may use Abundance, other than that you may not use it for any military purpose. You can create your own dialects of Abundance, sell it, or cannibalize it. The source code and machine-readable documentation includes:- Source code for the BBL (Big Black Lady) 32-bit Forth compiler written in Microsoft Assembler. BBL uses absolute Segment:Offset addressing for speed and hashed dictionaries for fast compilation.- Source code for PASM, a Post Fix Forth-style assembler written in BBL Forth.- Source code for Ned, a Forth-style full-screen source-code editor written in BBL Forth. It uses two monitors simultaneously if you have them. — Source code for the Abundance compiler written in BBL Forth.- Source code for some sample applications written in Abundance. They allow you to maintain a mailing list with extract, sort and print.- Machine readable documentation and tutorials in both Microsoft Word and vanilla DOS text file format.- Btrieve Run-time package.- a list of technical questions and answers submitted by Abundance programmers.- QDOS-II, a text editor and utility to browse, copy and delete files.- miscellaneous other useful public domain and shareware utilities.

What Else Will You Need?

Sooner or later you will want an assembler such as Microsoft Assembler or Optasm to generate customized versions of the BBL Forth compiler. To edit the assembler source code you will need a text editor such as the Norton Editor. Although you can get by without one, I would strongly recommend buying a keyboard enhancer such as Superkey or Prokey for editing Abundance source code. If you want to be able to do large external sorts, you will need Opt-Tech Data Sort. If you want Btrees (lookup by name as well as account number) then you will need Btrieve. If you want to do form letters, you will need Microsoft Word version 3. The pretty version of the Abundance documentation comes in Microsoft Word format. If you have an existing large database, then Ready! lets you semi-automatically re-key it into your new Abundance application though the improved edit checks. While you are waiting for Abundance to arrive in the mail, pick up a copy of Leo Brodie’s book Starting Forth and a 16-bit Forth compiler. You will need to learn Forth before you learn Abundance. Get the new Forth-83 revision of his book rather than the older Forth 79 version.

download: BBL and Abundance source
FORTH
RPN

This page is posted
on the web at:

http://mindprod.com/jgloss/abundance.html

Optional Replicator mirror
of mindprod.com
on local hard disk J:

J:\mindprod\jgloss\abundance.html
Canadian Mind Products
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.

IP:[65.110.21.43]
Your face IP:[18.97.14.84]
You are visitor number