FGL: Fifth Generation Language
Vector 1:1, page 89
Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 89
Abstract: FGL (Fifth Generation Language) has been the world-wide norm for most computer programs since the late 1980’s, when it replaced BASIC as the de-facto industry standard. Equally suitable for business, scientific and knowledge-based expert systems applications (which represent of course the main use of computers these days), FGL was first implemented in 1984 and quickly rose to prominence as a language of unmatched elegance, economy, and program development speed. Running on almost any computer and using only the industry standard ASCII character set, FGL nevertheless bears a striking structural resemblance to a little-known and now obsolete computer language called APL (A Programming Language). Students of the history of computing may be interested to see how FGL developed from its foundations in APL and how it was influenced by the success of BASIC.
* * * * *
Some of our older readers may have been taught BASIC at school in the early 1980’s and it’s worth remembering why that language became so popular around that time. In the mid-1970’s the first practical implementations of von Neumann architecture computers on silicon microprocessors became available. The prevailing architecture at the time was ‘bit-parallel’; the hardware quickly moved through 4-bit, 8-bit, 16-bit, 32-bit and by 1985, 64-bit CPU generations. By today’s standards these 64-bit processors were of course primitive: the concept of today’s highly parallel architectures composed of over 20 Giganodes of SHEEP (synapto-heuristic evolutionary expert processors) was of course a little over the horizon.
It’s difficult to remember that in the 1970’s, computer power was still finite and limited, and the random access memory (RAM) capacity for personal computer users was an incredibly confined maximum of 64k storage units, or “bytes” as they were called. Even by 1985 the average personal computer user had as little as 1024k bytes or a “megabyte” of space to play with. No small wonder, then, that the objectives of the languages that people were using then still included the quaint old ideas of:
- minimising the space used by the language interpreter/compiler
- maximising the efficiency of the machine code produced
- making it reasonably easy to create the interpreter/compiler
A project group at a location called Dartmouth (believed by some to be in the county of Devon in latter-day Britain, now part of New Thatcherland) developed BASIC in response to these goals. You can find out about BASIC’s capabilities in any good reference book on the history of science; here we will describe its main shortcomings by the standards of the day.
Some BASIC Drawbacks
- Only one program in memory at any one time.
- All subroutines had to become a physical part of this program.
- Data was either stored in ‘files’ or was declared in the program.
- Data could not be inspected without a program.
- No array-handling features in the standard language.
- Virtually no standardised text or string-handling facility.
- A pathetic selection of arithmetic and other functions.
- Bizarre limitations on variable names.
- Inability to pass data to subroutines via parameters.
- No concept of ‘workspace’ for developing programs and data.
- No built-in screen and printer control standards.
- Fixed-length record-oriented file structures.
- No concept of personalised command languages.
- User-defined functions limited to one line in length.
- Maximum of two dimensions in an array.
The list goes on. By today’s standards, BASIC can hardly be classed as a computer language; it’s more like an ingenious extension to binary notation. However, BASIC did do one thing: it made computers available on microprocessors to millions of people who would otherwise have missed the opportunity to use them. Now some may say, of course, that it would have been a better thing for mankind if this had never happened. No Third Industrial Revolution, no gangs of neo-Luddites roaming the streets with their PROMsniffers, no AIDS riots (Artificial Intelligence Destroys Society), and no fatal cases of Syndrome 2480, the tragic mystery illness that’s filling our hospital beds today with zombie-like patients suffering from an apparently irreversible degradation of vision into a series of rectangular cells. But the picture isn’t all black. Without computers — and Fifth Generation Language in particular — we wouldn’t have solved the world’s energy crisis, stabilised the global weather map, put an end to Third World poverty, brought the national economy under perfect control, etc. So let’s take a look at how FGL made it all possible. What follows isn’t a formal definition of the language: you can find that in the 1986 edition of the proceedings of the FGL User Group Meeting.
FGL Concepts¶
There are only ten concepts in FGL. These are:
| Names | The rules for composing an FGL object’s name |
| Modes | The different ways in which FGL can be used |
| Workspaces | Where a user’s data and programs are developed |
| Variables | Text or numeric, single or multi-dimensional data |
| Intrinsics | Built-in data manipulation facilities |
| Operators | A way to apply intrinsics more powerfully |
| Functions | Users’ programs and subroutines |
| Commands | Instructions affecting the FGL environment |
| Extensions | Implementation-dependent additional facilities |
| Files | Optional external storage of variables or programs |
FGL Names¶
Workspaces, variables and functions are assigned names by the user. These may be of any practical length and are drawn from the alphabet and the digits. Various reserved upper-case names are used by intrinsics. The first character of a name must be alphabetic. Users are encouraged to use lower-case for their names.
FGL Modes¶
You can only be doing one of three things at any particular time in FGL. In ‘function execution mode’ you are running a program that you or somebody else has written; in ‘function editing mode’ you are writing or modifying a program yourself; and in ‘immediate execution mode’ you are trying out FGL expressions by using the language as a kind of super-calculator. FGL’s rich repertoire of built-in intrinsic operations allows you to do a great deal of work in immediate execution mode without even bothering to write a program. The data resulting from program runs are available for inspection at any time, including the contents of multi-dimensional arrays; they don’t perish when the programs stop running.
FGL Workspaces¶
An FGL workspace is an area in the machine (historically RAM, now multi-processed in SHEEP) in which FGL programs and variables are created and in which they normally reside, both when they are in use and when they are stored away somewhere (historically spinning around on ‘disc’! — now kept in BUBPAK, LASERCARD or CRAMPAK). An FGL workspace might typically contain some thirty or forty functions and perhaps ten or twenty variables. Some of the functions would act as subroutines to others in the same workspace. The whole workspace can be saved somewhere when not in use or recovered with a single command. With our modern technology there is no limit to the physical size of this workspace and for most applications this makes files redundant.
Table 1: FGL Intrinsics
| Intrinsic | Monadic Case | Dyadic Case |
|---|---|---|
+ |
Force display | Add |
- |
Prefix to negative number | Subtract |
# |
Sign (+1, 0 or −1) | Multiply |
% |
Reciprocal | Divide |
MAX |
Round up | Select maximum |
MIN |
Round down | Select minimum |
| |
Absolute value | Remainder |
* |
e to the power | raise to the power |
LOG |
log to the base e | log to any base |
! |
factorial | combination |
TRIG |
pi times | sin, cos, tan etc. (15 options) |
LIST |
list from 1 to … | find position in a list |
? |
Random selection | Random without duplicates |
INV |
Invert a matrix | Least squares matrix solution |
< |
Less than | |
LEQ |
Less than or equal to | |
= |
Equal to | |
NEQ |
Not equal to | |
GEQ |
Greater than or equal to | |
> |
Greater than | |
SET |
Is a member of | |
AND |
True if both true | |
OR |
True if either true | |
NAND |
False if both true | |
NOR |
False if either true | |
NOT |
True if false | |
SIZE |
Request dimension of | Create with dimension of |
, |
Turn into a vector | Join together |
FLIP |
Reverse order of elements | Rotate elements as specified |
SWAP |
Transpose an array | Selective transpose |
TAKE |
Select from start or end | |
DROP |
Discard from start or end | |
/ |
Select if true, else compress | |
\ |
Select if true, else expand | |
SORT |
Ascending sort | Asc. sort by collation sequence |
TROS |
Descending sort | Des. sort by collation sequence |
ENC |
Encode into a new number base | |
DEC |
Decode from a new number base | |
FORM |
Default numeric format | Specific numeric format |
$ |
Default numeric i/o | Specific numeric i/o |
IO |
Default text i/o | Specific text i/o |
EX |
Execute text as numeric | Execute conditional on error |
FGL Variables¶
An FGL variable may be either text or numeric, and of any dimension. Zero-dimensional variables correspond to single characters or numbers. The numbers may be stored internally as binary, integer or floating point types, but that is transparent to the user. One-dimensional variables are lists or vectors; two-dimensional are tables or matrices; higher dimensions are allowed with no practical limit for more complex data storage needs. Data can be manipulated and inspected casually within the workspace. The underline symbol “_” causes the data on its right to be assigned to the location named on its left, while the use of the symbols “( ; )” allows indexing. Arrays of more dimensions use more “;” symbols to separate the axes. A single quote is used to delimit entered text. If entered text should itself contain a quote, two adjacent quotes are used instead.
FGL Intrinsics¶
Most intrinsics can be applied directly to all or part of an array, in which case each term in the array is affected. Most intrinsics also have two uses: ‘monadic’, in which a variable is supplied as the right-hand argument, and ‘dyadic’, where a left and a right variable are supplied. Table 1 presents a fairly complete list of FGL intrinsics, divided into seven groups: arithmetic, algebraic, comparative, logical, manipulative, sorting/coding, and input/output. FGL intrinsics work on numeric and text arguments wherever possible, and as we said, you can throw multi-dimensional arrays at them and they’ll respond appropriately.
FGL expressions may be compounded of intrinsics to any degree of complexity, the result from one operation being passed to the next as an argument. FGL lines are scanned from right to left. There is no precedence in order of execution between different intrinsics, even between multiply and add! The symbols “()” may be used to force execution to occur in any particular order. Unless the result of an operation is assigned to a name or used as the argument of another expression, it is displayed by default.
FGL intrinsics allow the user to do a great deal of serious work on data without ever writing a program. They’ve been carefully chosen so that you can do almost anything with them. Space doesn’t permit a detailed discussion of each, to Table 2 presents some examples to give you the flavour.
FGL Operators¶
The syntax of the FGL intrinsics is that they can be ‘monadic’ or ‘dyadic’, taking data either as a right argument or on the right and on the left too. FGL operators are even more cunning. Instead of merely working on data as a right or left argument, they accept one or more intrinsics as right or left arguments, causing that intrinsic to be applied repeatedly to successive terms of an array. This sounds complicated, but actually the concept is very simple. There are five operators in FGL. They are called: reduction, scan, inner product, outer product, and axis.
There are about 40 intrinsics in FGL, and most can be applied either monadically or dyadically, giving about 70 possibilities. By using these intrinsics with operators, several hundred data manipulations can be specified without bothering to write a program. One of the most elegant aspects of FGL is the ‘orthogonality’ of its rules. In a sense an FGL operator is the high level language analogue of a machine code memory addressing mode, while an FGL intrinsic corresponds to a machine code instruction. Like a well-designed machine code instruction set, FGL lets you employ (almost) any intrinsic with (almost) any operator on (almost) any array of data.
Table 2 Examples of FGL Intrinsics
+ eric _ 10?100
34 12 57 89 39 4 67 33 79 44
+ eric _ eric - 19.5
14.5 ¯7.5 37.5 69.5 19.5 ¯15.5 47.5 13.5 59.5 24.5
# eric
1 -1 1 1 1 -1 1 1 1 1
MAX eric
15 ¯7 38 70 20 ¯15 48 14 60 25
MIN eric
14 ¯8 37 69 19 ¯16 47 13 59 24
ABS eric
14.5 7.5 37.5 69.5 19.5 15.5 47.5 13.5 59.5 24.5
eric LIST 37.5 47.5
3 7
bill _ 'the name of this language is FGL'
bill LIST 'name'
5 6 7 3
eric LEQ 20
1 1 0 0 1 1 0 1 0 0
(eric LEQ 20) AND (eric GEQ 0)
1 0 0 0 1 0 0 1 0 0
SIZE eric
10
+ tony _ 2 6 SIZE 'hallo mother'
hallo
mother
FLIP tony
ollah
rehtom
2 FLIP tony
llo ha
thermo
Table 2 (continued)
SWAP tony
hm
ao
lt
lh
oe
r
0 2 DROP tony
llo
ther
0 ¯2 DROP tony
hall
moth
1 0 DROP tony
mother
2 ¯3 TAKE tony
lo
her
+ paul _ LIST 10
1 2 3 4 5 6 7 8 9 10
1 0 0 2 0 0 3 0 0 1 / paul
1 4 4 7 7 7 10
1 0 0 1 5 1 0 0 0 1 3 1 0 0 0 1 1 1 \ paul
1 0 0 2 3 3 3 3 3 4 0 0 0 5 6 6 6 7 0 0 0 8 9 10
+ paul _ 10 ? 100
23 68 99 45 17 36 27 49 87 77
SORT paul
5 1 7 6 4 8 2 10 9 3
paul[SORT paul]
17 23 27 36 45 49 68 77 87 99
paul[TROS paul]
99 87 77 68 49 45 36 27 23 17
3 + EX '2+2'
7
7 2 FORM 4.519 6.7
4.52 6.70
FGL Functions¶
An FGL function is composed of zero or more lines, each containing a valid FGL expression. Most programs in FGL are very short, up to about ten lines as a maximum. This contrasts strongly with the thousands of lines in programming languages such as BASIC (believed to stand for Boring And Senselessly Infantile Concept) or — and this one is very much for the history boys — some even more forgotten dialects such as COBOL (historians now think that this meant Central Official Bastion of Obsolete Languages). There are two reasons for this brevity. One is that the ability of the native FGL intrinsics and operators to work on whole arrays at a time means that loops, control structures and DO…WHILE instructions are hardly ever needed. The other is that instead of combining all a project’s needs into one huge monolithic program, FGL breaks the job down into a set of sub-tasks, with a different and free-standing program responsible for each area.
FGL is rather like FORTH in this respect. You can define a vocabulary of your own FGL “verbs”, “nouns” and “adjectives” to produce a personalised command syntax appropriate for any particular job. It takes about three minutes of programming in FGL to construct the functions which make the following line of English text a valid expression in FGL immediate execution mode:
Average Salary where (Sex is Female) and (Department is Accounts)
and which will produce the correct answer to this and any similar information request. The response will be almost instantaneous irrespective of the size of the personnel file, because this data consists of FGL vectors sitting in main memory all the time — there are no files involved.
FGL functions are in some respects similar to intrinsics. They may be monadic or dyadic, but they may also be ‘niladic’ — using no arguments at all. A niladic FGL program corresponds to the idea of a BASIC program. A monadic or dyadic program corresponds to the idea of a BASIC subroutine, but the FGL versions are free-standing and much more flexible. The following additional symbols may be used in FGL programs:
^ |
To start or end function editing |
" |
The rest of the line is a comment |
@ |
Branch to indicated line/label, or ignore if none specified |
& |
Statement separator |
Lines may be prefaced with text labels terminated by a “:” symbol. Label names are automatically assigned their run-time line numbers as integer values, so these become pseudo-variables that may be referenced but not altered in the user’s expressions.
Branching in FGL is of interest. The “@” branch expects to see an integer argument representing a valid line number. This integer may be calculated any way the user wishes. Multiple conditional branches similar to the CASE constructs of other languages become trivial in FGL. If the integer is not presented (by providing an “empty vector” of zero length) then FGL will ignore the branch instruction. The user may use any one of many FGL techniques to implement a conditional branch using this feature. Table 3 contains some examples of FGL functions.
Table 3 Examples of FGL Functions
^ result _ average data
[1] "This function will average a vector of numeric values
[2] result _ (+/data) % SIZE data
[3] ^
average 1 2 3 4
2.5
3#average 1 2 3 4
7.5
^ analysis
[1] "This function will do some statistics on typed-in data
[2] "Notice that it in turn uses the pre-written function 'AVERAGE'
[3] 'Please enter your data, separated by space(s), terminated by RETURN'
[4] hisdata _ $
[5] 'Thank you'
[6] 'There were ';SIZE hisdata;' values entered'
[7] 'The largest was ';MAX/hisdata
[8] 'The smallest was ';MIN/hisdata
[9] 'The average was ';average hisdata
[10] 'Goodbye'
[11] ^
analysis
Please enter your data, separated by space(s), terminated by RETURN
$: 50 30 40 20 60
Thank you
There were 5 values entered
The largest was 60
The smallest was 20
The average was 40
Goodbye
^ newtab _ crosstab oldtab
[1] "This function cross-tabulates a table (row and column sums)
[2] newtab _ oldtab,[1]+/[1]oldtab
[3] newtab _ newtab,[2]+/[2]newtab
[4] ^
crosstab 4 4 SIZE LIST 16
1 2 3 4 10
5 6 7 8 26
9 10 11 12 42
13 14 15 16 58
28 32 36 40 136
^ r _ factorial b
[1] "Recursive function for calculating factorials
[2] @(1 = r _ b)/0
[3] r _ b # factorial b - 1
[4] ^
FGL Commands¶
An FGL command generally acts immediately on the workspace or the long-term storage medium and affects the environment within which the FGL programmer is working. Aspects such as changing the number of columns in the display device line width, inquiring after the names of variables and functions etc. are typical uses of these system commands. Commands are prefaced with a leading “)” symbol which acts as a delimiter to distinguish them from user objects which might have the same name. Commands are not generally included inside user’s functions, but they may be so incorporated by enclosing them inside quotation marks and executed at run-time using the “EX” intrinsic.
FGL Extensions¶
The “$” symbol is used by FGL for two tasks: as primitive input-output intrinsic for numeric data, and also as a delimiting prefix to introduce an implementation-dependent additional FGL facility. The FGL syntax has been standardised by the ISO but vendors may offer any number of extra “goodies” in their own FGL interpreters. In order to minimise the problem of name clashes, these extensions are prefaced by “$”, hence the name “dollar-functions” and “dollar-variables”.
FGL Files¶
Because typical workspaces of 20 Giganodes (comparable in 1980’s terms to a user having 200 Megabytes of physical RAM driven by about 10 dedicated 32-bit processors) are the norm these days, files play a rather minor role in FGL. Dedicated applications tend to store all the data in the workspace, while multi-user tasks employ the concept of the ‘shared rodent interface’ to squirt data between other active workspaces and user I/O devices such as mice, without bothering to use files. However, files can be used if required.
An FGL file is best thought of as a collection of adjacent elastic boxes. The boxes are numbered sequentially, starting at 1, with no maximum limit. A box can contain any FGL object of any size: a single number, a vector of 100,000 numbers, a text matrix of 10,000 rows by 100 columns, or a function. Depending on the implementation, dollar-functions may exist to allow a heterogeneous assortment of variables and functions to be grouped into a single package and filed as a single object. Filed objects may be replaced by larger or smaller ones without restriction. Acess is by box number: direct and sequential access of any type is therefore supported.
Whereas the conventional languages of the 1980’s expected data records to be stored as ‘horizontal’ slices of a table, with one stored record per person or product in the data file, FGL records are normally stored ‘vertically’, with one boxed object per parameter in the data file. All the SALARIES go into box number 1; all the DEPARTMENTS into box 2; all the JOINING DATES into box 3, and so on. Files are therefore typically ‘inverted’ all the time, which usually obviates the need for a database.
Why FGL overtook BASIC¶
The overriding advantages of FGL were as follows:
- Extremely fast project development time
- A workspace in which to bring together programs and data
- A rich set of standard data handling primitives
- Ability to work on arrays without looping
- Modular function style with elegant control flow
- No limit to the range of applications that could be handled
- Sophisticated features like recursion for expert systems
- Standardised full-screen controls
- Standardised printer attribute handling
- Standardised colour graphics routines
- Shared rodent interface for control of mice
- Shared stereo interface for voice recognition and output
- Required no special hardware for its character set
- Upper & lower case characters for commercial applications
- Numeric precision to 15 significant figures
- A structure which made database handlers unnecessary
- Parallel processing as an integral part of the language
In addition, the existence of the earlier APL language meant that there was no need to create a new language interpreter for each implementation: simple modifications to the character input/output routines were all that was needed to convert APL into FGL.
Why FGL was well suited for fifth generation projects¶
The flirtation with knowledge-based expert systems which began at the start of the 1980’s produced proposals for the deployment of other languages for expert systems applications, such as LOGO, LISP and PROLOG. These languages were strong on inference but weak on arithmetic. For example, PROLOG was good at solving the following types of problem:
‘If time flies like an arrow, do fruit flies like a banana?”
In PROLOG this would be stated as:
LISP was good at jobs like proposing robust hyphenation rules for word processing spelling checkers, rules which helped one to avoid infelicitous proposals for hyphen insertion in a word such as “toadstool”. In LISP the code to do this would be stated in the user-friendly formulation:
LOGO excelled at helping people create random artwork designs using turtles; in fact it wiped out all competition in this field and ended up being referred to the Anti-Trust (Monopolies) Commission in the Galapagos Islands.
However, it eventually dawned on people that the basis for good expert systems design had to be a good general purpose computer language: one that was strong on logic and text manipulation while also being extremely fast at computation by the use of parallel processing. As parallel array processors emerged, moving away from the so-called “pipeline” processing concept to the aptly-named “dense-pack” synchronous computation field, the advantages of array-oriented languages for expert system design soon became irrestible. Declarative subsets of FGL soon emerged which modelled all the best features of the specialised expert systems languages without throwing away the indigenous ability to calculate (for example) antilogarithms.
The implications of Ashby’s Law (“The variety of a controller must be as great as that of the system under control”) meant that any attempt at artificial intelligence in the strict sense required the creation of an artificial model of reality that was robust for the uses to which it was being put. Digital implementations of this concept were inappropriate because of the sequential, clocked nature of their computations: even at sub-picosecond switching speeds, the variety was just not there. By the 1980s we had learnt that the answer lay in marrying microelectronic fabrication disciplines to the highly parallel, asynchronous nature of mental processes as implemented via neurons, axons and synapses in the human brain in an essentially analogue fashion. This was first done by a small company in Rockville in 1986, using protein instead of silicon as a semiconducting substrate. The rest, of course, is history.
However, the acceptance that true artificial intelligence required designers to step outside the sequential von Neumann architecture was enough to encourage the development of pseudo-intelligent systems. The goal of genuine understanding was set aside for the more prosaic (but commercially desirable) aim of flexibility and knowledge. FGL turned out be an excellent vehicle for specifying heuristics drawn from fuzzy set theory, from catastrophe theory and from Bayesian statistics. These were robust means of integrating the large body of detailed knowledge that was available to the “domain specialists” who were implementing the systems. In particular the creation of off-shoots of FGL such as ESP (Expert System Producer), ESPRIT (Expert System Producer for Rapid Integration of Thoughts) and ESPION (Expert System Producer for Intelligence, Observation and Neutralisation) were formative in FGL’s rapid penetration of this huge arena.
FGL was fast, flexible and mature. It was very good at Boolean logic. It handled recursion elegantly. It coped beautifully with problems requiring very rapid computation over vast memory areas. FGL programs could with trivial ease modify themselves or other FGL programs while executing. Most important of all, it was there and it worked. In retrospect, there was no other choice.
The reaction from the BASIC community¶
The response from existing BASIC users represented one of the decade’s most fascinating examples of techno-cultural re-adjustment. Fortunately the accounts of this process were well documented at the time and we now know fairly precisely what happened. The first paper on FGL entitled simply “FGL: Fifth Generation Language” was published in a magazine of the time called ‘BYTE’ (now replaced by the hourly circulation electronic journal ‘GNAW’ — Gripping News Adventurously Written) in the 1983-84 period and the first implementations of the language became available early in 1984. To users of BASIC, who had been fiddling around with things like PASCAL, ADA, PROLOG, LISP, LOGO, FORTH, HOPE, SNOBOL, FORTRAN, RPG, COBOL, ALGOL, PL/1 etc. in the hope of finding something useful, the response was overwhelming.
Massed bands of cheerleaders ran through the streets of the world’s major capitals holding placards with FGL programs written on them. Spectacular May Day parades in Red Square featured elaborate floats in the form of FGL 5-dimensional arrays. The Space Shuttle (not to be confused with the recently introduced no-reservation required Venus shuttle) was employed to blanket the ionosphere with FGL Reference Guides multiple-independently targeted on a re-entrant orbit to the world’s computer conurbations. No resistance was encountered anywhere, except from those who had previously encountered APL. It was a landslide.
The reaction from the APL hostility¶
The first formal presentation of FGL to the APL hostility took place with the submission of the same paper to the annual APL conference held in Helsinki, Finland, June 11th — 15th 1984. Despite the better judgement of several of the paper’s referees, the paper was accepted as part of the formal proceedings. This was a pity in many ways since previous conferences had tended to indicate that the pirate presentation of a rejected paper attracted a larger audience than one that had been accepted. Nevertheless, at least two people were observed to enter the room in which the paper was being delivered, one of whom was known not to be the paper’s author. After the paper had been presented, the following questions were posed:
- Q.
- “We already have proposals for an ASCII notation for APL. Why make such a big thing of it?”
- A.
- “Because if APL is to take over in the disguise of FGL, we must kill APL notation completely for all except academic and research purposes. Nobody is prepared to rush out and buy new APL screens if they already own ASCII versions — and by now, they all do!”
- Q.
- “Why not adopt one of the existing ASCII mnemonic standards?”
- A.
- “You’re missing the point! FGL will be used by people who have never seen APL notation and who never will! Who wants to talk about $RHO?”
- Q.
- “You’ve destroyed the whole spirit of APL”
- A.
- “FGL training books will contain references to APL notation in an appendix at the back. People who want to play with APL will still be able to. Most APL users care far less about the notation than most of the people who set APL standards. Try actually using FGL for a bit — you’ll find that the APL spirit is still very much there.”
- Q.
- “What is the main objective behind such a major change?”
- A.
- “First and foremost, to stop APL inexorably disappearing. This is happening partly because commercial pressures increasingly preclude the implementation of an overstruck character set, and partly because APL’s funny symbols simply put most people off. As a percentage based on the language used per installed computer (including microcomputers), APL usage has been declining exponentially for 7 years and is now indistinguishable from the zero axis. If we don’t adopt something like FGL now, APL will sink without trace.”
- Q.
- “Are there any other advantages?”
- A.
- “Of course. FGL lets you use uppercase and lowercase in a standard fashion — vital for business applications. Suddenly, you can choose any screen or printer you want. It’s now implemented on virtually any computer you want. And the hardware is ridiculously cheap, because everyone is using it. Also since you know APL already, you’ve already learnt FGL.”
- Q.
- “What about nested arrays?”
- A.
- “This has to be the world’s most irrelevant question! APL is already so much more powerful than BASIC that any further features would virtually constitute overkill. However, it has to be admitted that list structures come in handy for expert systems, so (provided no new symbols are needed) there’s no reason why FGL cannot adopt whichever nested array syntax APL eventually decide on.”
- Q.
- “My IBM 3270-type terminal creates APL characters without overstrikes, so what’s the problem?”
- A.
- “IBM’s EBCDIC code does include APL and non-APL characters in a single character set. However, IBM and plug-compatible manufacturers are the only companies that use EBCDIC; IBM has already started selling an ASCII-type screen, and it’s now only a question of time before ASCII-based protocols start to muscle EBCDIC code away.”
- Q.
- “If the next generation of microcomputers are going to have memory-mapped screens, what’s the problem?”
- A.
- “You still won’t get APL characters without a big struggle. Let’s change now while there’s still time.”
- Q.
- “What can I do in practice to help FGL emerge?”
- A.
- “Write to the FGL Action Group, care of the author.”
Table 4 depicts the relationship of the defunct APL symbols to the FGL versions that we all now use. The few APL fanatics who remained unconvinced were eventually discovered in their caves in the Adirondacks and the Hebrides. Lucrative offers were made to them and you can still visit them now; either as part of the ‘living history’ permanent exhibition in Williamsburg, Virginia, for the entertainment of heads of state, or (in the more traditional British style) in glass cases at the Science Museum in London. You can find them there located next door to James Watt’s steam engine; if you press the button on the outside of the stand, they wake up and demonstrate APL characters in semaphore — as a one-line function with no comments.
Footnote: This article was written by an FGL module entitled ESCRIT, Expert Systems Creation of Random Intelligent Text. For this reason any views expressed herein remain those of the system and do not necessarily represent opinions held by the author or any organisation with which it is associated.
Table 4 — APL/FGL Equivalents¶
The standard APL character set was evolved for paper printing terminals for which no penalty (apart from print speed) is attached to the concept of backspacing and overstriking a character to form a new composite symbol. The APL character set therefore contains more than the standard 96 ASCII printing characters. Despite this, APL does not contain the lower case alphabet, a serious deficiency. Furthermore, various punctuation symbols which also exist in ASCII are located in non-standard positions in the APL code table. The mapping of APL to FGL characters is as follows:
a. APL A-Z becomes FGL a-z
b. APL A-Z becomes FGL A-Z
c. APL 0-9 stays as FGL 0-9
d. APL punctuation is replaced by ASCII versions in FGL, if they exist
e. ASCII punctuation which is undefined in APL is redeployed in FGL
f. Reserved FGL upper case (APL underlined) names replace remaining symbols
This mapping can be installed on an APL interpreter without making any changes to the interpreter itself provided the following extensions exist:
- Ability to reconfigure input and output translate tables.
- Ability to create ambivalent user-defined functions.
- User-defined funtions allowed as arguments to operators.
This approach allows the current set of recommeded reserved words such as SIZE, LIST etc. to be replaced by national language variants if desired.
“…” indicates that the APL symbol is not supported in FGL. These cases do not affect any APL symbols in serious active use. The surprising aspect is how little change is actually required to APL; many of the APL symbols are a part of standard ASCII and hence FGL.
This first draft of the standard was part of the 1983 paper and some changes were of course made following comments on particular choices. Overall, however, the final standard bore a close resemblance.
APL FGL APL FGL APL FGL
-------------------------------------------------
¨ ... ? ? ⍀ \[1]
¯ ¯ ⍵ ... ⌿ /[1]
< < ∊ SET ! !
≤ LEQ ⍴ SIZE ⍪ ,[1]
= = ~ NOT ⍝ "
≥ GEQ ↑ TAKE ⍎ EX
> > ↓ DROP ⍕ FORM
≠ NEQ ⍳ LIST ⍟ LOG
∨ OR ○ TRIG ⌹ INV
∧ AND * * ⍲ NAND
- - ⍺ ... ⍱ NOR
+ + ⌈ MAX O-U-T ...
× # ⌊ MIN ⍫ LOCK
÷ % (?) ... ⍞ IO
⌶ ... ∇ ^ ⌽ FLIP
→ @ ∆ ... ⍒ TROS
← _ ∘ ` ⍋ SORT
( ( ' ' ⊖ FLIP[1]
) ) ⎕ $ ⍉ SWAP
[ [ ⊂ ...
] ] ⊃ ...
/ / ∩ ...
\ \ ∪ ...
; ; ⊥ DEC
, , ⊤ ENC
: : | |
⊢ ... 0-9 0-9
⊣ ... A-Z a-z
⋄ & A̲-Z̲ A-Z