Abundance Overview

Last updated 1997 October 28 by Roedy Green .

Abundance: A Data Base language that can run backward in time

By: Roedy Green

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 April 1986. They edited it severely and published it in October 1986. 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, 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 labelled 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 realizes 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 naive 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 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 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) 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. 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. See Figure 1 for 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.

Implicit Array Subscripts

In a traditional programming language, for every ArrayOfRecords X you 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.

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 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. See Figure 4 for how you handle arrays/files in Abundance versus Figure 3 for Pascal Arrays and Figure 5 for Pascal files.

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 DOS 3.2 or later running on an IBM PC, XT or AT 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 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.

HTML Checked!
Canadian Mind Products You can get an updated copy of this page from http://mindprod.com/article.html