APL (A Programming Language) is an array programming language based on a notation invented in 1957 by Kenneth E. Iverson while at Harvard University. It originated as an attempt to provide consistent notation for the teaching and analysis of topics related to the application of computers. Iverson published his notation in 1962 in a book titled A Programming Language. By 1965, a subset of the notation was implemented as a programming language, then known as IVSYS. Later, prior to its commercial release, APL got its name from the title of the book. Iverson received the Turing Award in 1979 for his work.
Iverson's notation was later used to describe the IBM System/360 machine architecture, a description much more concise and exact than the existing documentation and revealing several previously unnoticed problems. Later, a Selectric typeball was specially designed to write a linear representation of this notation. This distinctive aspect of APL, the use of a special character set visually depicting the operations to be performed, remains fundamentally unchanged today.
The APL language features a rich set of operations which work on entire arrays of data, like the vector instruction set of a SIMD architecture. While many computer languages would require iteration to, for example, add two arrays together, functions in APL typically deal with entire arrays at once. In conjunction with a special character set where glyphs represent operations to be performed, this drastically reduces the potential number of loops and allows for smaller, more concise and compact programs.
As with all programming languages that have had several decades of continual use, APL has evolved significantly, generally in an upwards-compatible manner, from its earlier releases. APL is usually interpretive and interactive, and normally features a read-evaluate-print loop (REPL) for command and expression input. Today, nearly all modern implementations support structured programming while several dialects now feature some form of object oriented programming constructs.
In the early 1990s Iverson, along with Roger Hui redesigned the APL language, calling the update the J programming language. J removed the requirement for the special character set, fixed some ambiguous syntax, and added support for John Backus' functional programming ideas.
IBM was chiefly responsible for the introduction of APL to the marketplace. In 1965, a portion of the notation was reworked and implemented as a programming language. APL was first available in 1967 for the IBM 1130 as APL1130. APL gained its foothold on mainframe timesharing systems from the late 1960s through the 1980s. Later, when suitably performing hardware was finally available starting in the early to mid-1980s, many users migrated their applications to the personal computer environment.
Early IBM APL interpreters for IBM 360 and IBM 370 hardware implemented their own multi-user management instead of relying on the host services, thus they were timesharing systems in their own right. First introduced in 1966, the APL360 system was a multi-user interpreter. In 1973, IBM released APL.SV which was a continuation of the same product, but which offered shared variables as a means to access facilities outside of the APL system, such as operating system files. In the mid 1970s, the IBM mainframe interpreter was even adapted for use on the IBM 5100 desktop computer, which had a small CRT and an APL keyboard, when most other small computers of the time only offered BASIC. In the 1980s, the VSAPL program product enjoyed widespread usage with CMS, TSO, VSPC, and CICS users.
Several timesharing firms sprang up in the 1960s and 1970s which sold APL services using modified versions of the IBM APL360 interpreter. In North America, the better-known ones were I. P. Sharp Associates, Scientific Time Sharing Corporation, and The Computer Company (TCC). With the advent first of less expensive mainframes such as the IBM 4331 and later the personal computer, the timesharing industry had all but disappeared by the mid 1980s.
Sharp APL was available from I. P. Sharp Associates, first on a timesharing basis in the 1960s, and later as a program product starting around 1979. Sharp APL was an advanced APL implementation with many language extensions, such as packages (the ability to put one or more objects into a single variable), file system, nested arrays, and shared variables.
As other vendors were busy developing APL interpreters for new hardware, notably Unix-based microcomputers, APL2 was almost always the standard chosen for new APL interpreter developments. Even today, most APL vendors cite APL2 compatibility, which only approaches 100%, as a selling point for their products.
APL2 for IBM mainframe computers is still available today, and was first available for CMS and TSO around 1980. The APL2 Workstation edition (Windows, OS/2, AIX, Linux, and Solaris) followed much later in the early 1990s.
In 1977, was released a business level APL known as TIS APL, based on the Z80 processor. It featured the full set of file functions for APL, plus a full screen input and switching of right and left arguments for most dyadic operators by introducing ~. prefix to all single character dyadic functions such as - or /.
Vanguard APL was available for Z80 CP/M-based processors in the late 1970s. TCC released APL.68000 in the early 1980s for Motorola 68000-based processors, this system being the basis for MicroAPL Limited's APLX product. I. P. Sharp Associates released a version of their APL interpreter for the IBM PC and PC/370 - for the IBM PC, an emulator was written which facilitated reusing much of the IBM 370 mainframe code. Arguably, the best known APL interpreter for the IBM Personal Computer was STSC's APL*Plus/PC.
In the early 1980s, the Analogic Corporation developed The APL Machine, which was an array processing computer designed to be programmed only in APL. There were actually three processing units, the user's workstation, an IBM PC, where programs were entered and edited, a Motorola 6800 processor which ran the APL interpreter, and the Analogic array processor which executed the primitives. At the time of its introduction The APL Machine was likely the fastest APL system available. Although a technological success, The APL Machine was a marketing failure. The initial version supported a single process at a time. At the time the project was discontinued, the design had been completed to allow multiple users. As an aside, an unusual aspect of The APL Machine was that the library of workspaces was organized such that a single function or variable which was shared by many workspaces existed only once in the library. Several of the members of The APL Machine project had previously spent a number of years with Burroughs implementing APL700.
At one stage, Microsoft Corporation planned to release a version of APL, but these plans never materialized.
An early 1978 publication of Rodnay Zaks from Sybex was A microprogrammed APL implementation ISBN 0895880059 which is the complete, total source listing for the microcode for a PDP / LSI-11 processor implementing APL. This may have been the substance of his PhD thesis.
Unlike traditionally structured programming languages, code in APL is typically structured as chains of monadic or dyadic functions and operators acting on arrays. As APL has many nonstandard primitives (functions and operators, indicated by a single symbol or a combination of a few symbols), it does not have function or operator precedence. Early APL implementations did not have control structures (do or while loops, if-then-else), but by using array operations, usage of structured programming constructs was just not necessary. For example, the iota function (which yields a one-dimensional array, or vector, from 1 to N) can replace for-loop iteration. More recent implementations of APL generally include comprehensive control structures, thus data structure and program control flow can be clearly and cleanly separated.
The APL environment is called a workspace. In a workspace the user can define programs and data, i.e. the data values exist also outside the programs, and the user can manipulate the data without the necessity to define a program. For example,
assigns the vector values 4 5 6 7 to N;
adds 4 to all values (giving 8 9 10 11) and prints them (a return value not assigned at the end of a statement to a variable using the assignment arrow is displayed by the APL interpreter);
prints the sum of N, i.e. 22.
The user can save the workspace with all values, programs and execution status.
APL is well-known for its use of a set of non-ASCII symbols that are an extension of traditional arithmetic and algebraic notation. Having single character names for SIMD vector functions is one way that APL enables compact formulation of algorithms for data transformation such as computing Conway's Game of Life in one line of code (example). In nearly all versions of APL, it is theoretically possible to express any computable function in one expression, that is, in one line of code.
Because of its condensed nature and non-standard characters, APL has sometimes been termed a "write-only language", and reading an APL program can at first feel like decoding Egyptian hieroglyphics. Because of the unusual character set, many programmers use special keyboards with APL keytops for authoring APL code. Although there are various ways to write APL code using only ASCII characters, in practice, it is almost never done. (This may be thought to support Iverson’s theses about notation as a tool of thought.) Most if not all modern implementations use standard keyboard layouts, with special mappings or Input Method Editors to access non-ASCII characters. Historically, the APL font has been distinctive, with uppercase italic alphabetic characters and upright numerals and symbols. Most vendors continue to display the APL character set in a custom font.
Advocates of APL claim that the examples of so-called write-only code are almost invariably examples of poor programming practice or novice mistakes, which can occur in any language. Advocates of APL also claim that they are far more productive with APL than with more conventional computer languages, and that working software can be implemented in far less time and with far fewer programmers than using other technology. APL lets an individual solve harder problems faster. Also, being compact and terse, APL lends itself well to larger scale software development as complexity arising from a large number of lines of code can be dramatically reduced. Many APL advocates and practitioners view programming in standard programming languages, such as COBOL and Java, as comparatively tedious. APL is often found where time-to-market is important, such as with trading systems.
The following expression sorts a word list stored in matrix X according to word length:
The following function "life", written in Dyalog APL, takes a boolean matrix and calculates the new generation according to Conway's Game of Life:
In the following example, also Dyalog, the first line assigns some HTML code to a variable "txt" and then uses an APL expression to remove all the HTML tags, returning the text only as shown in the last line.
The following expression finds all prime numbers from 1 to R. In both time and space, the calculation is O(R²).
From right to left, this means:
A widely cited paper "An APL Machine" (authored by Phil Abrams) perpetuated the myth that APL made pervasive use of lazy evaluation where calculations would not actually be performed until the results were needed and then only those calculations strictly required. An obvious (and easy to implement) lazy evaluation is the J-vector : when a monadic iota is encountered in the code, it is kept as a representation instead of being calculated at once, thus saving some time as well as memory.
Although this technique was not generalized, it embodies the language's best survival mechanism: not specifying the order of scalar operations. Even as eventually standardized by X3J10, APL is so highly data-parallel, it gives language implementors immense freedom to schedule operations as efficiently as possible. As computer innovations such as cache memory, and SIMD execution became commercially available, APL programs ported with little extra effort spent re-optimizing low-level details.
APLNow (formerly APL2000) offers an advanced APL interpreter which operates under Linux, Unix, and Windows. It supports Windows automation, supports calls to operating system and user defined DLLs, has an advanced APL File System, and represents the current level of APL language development. APL2000's product is an advanced continuation of STSC's successful APL*Plus/PC and APL*Plus/386 product line.
Dyalog APL is an advanced APL interpreter which operates under Linux, Unix, and Windows. Dyalog has aggressive extensions to the APL language which include new object oriented features, numerous language enhancements, plus a consistent namespace model used for both its Microsoft Automation interface, as well as native namespaces. For the Windows platform, Dyalog APL offers tight integration with Microsoft .Net, plus limited integration with the Microsoft Visual Studio development platform.
IBM offers a version of IBM APL2 for IBM AIX, Linux, Sun Solaris and Windows systems. This product is a continuation of APL2 offered for IBM mainframes. IBM APL2 was arguably the most influential APL system, which provided a solid implementation standard for the next set of extensions to the language, focusing on nested arrays.
Soliton Associates offers the SAX interpreter (Sharp APL for Unix) for Unix and Linux systems, which is a further development of I. P. Sharp Associates' Sharp APL product. Unlike most other APL interpreters, Kenneth E. Iverson had some influence in the way nested arrays were implemented in Sharp APL and SAX. Nearly all other APL implementations followed the course set by IBM with APL2, thus some important details in Sharp APL differ from other implementations.
In the past, APL compilation was regarded as a means to achieve execution speed comparable to other mainstream languages, especially on mainframe computers. Several APL compilers achieved some levels of success, though comparatively little of the development effort spent on APL over the years went to perfecting compilation into machine code.
As is the case when moving APL programs from one vendor's APL interpreter to another, APL programs invariably will require changes to their content. Depending on the compiler, variable declarations might be needed, certain language features would need to be removed or avoided, or the APL programs would need to be cleaned up in some way. Some features of the language, such as the execute function (an expression evaluator) and the various reflection and introspection functions from APL, such as the ability to return a function's text or to materialize a new function from text, are simply not practical to implement in machine code compilation.
A commercial compiler was brought to market by STSC in the mid 1980s as an add-on to IBM's VSAPL Program Product. Unlike more modern APL compilers, this product produced machine code which would execute only in the interpreter environment, it was not possible to eliminate the interpreter component. The compiler could compile many scalar and vector operations to machine code, but it would rely on the APL interpreter's services to perform some more advanced functions, rather than attempt to compile them. However, dramatic speedups did occur, especially for heavily iterative APL code.
Around the same time, the book An APL Compiler by Timothy Budd appeared in print. This book detailed the construction of an APL translator, written in C, which performed certain optimizations such as loop fusion specific to the needs of an array language. The source language was APL-like in that a few rules of the APL language were changed or relaxed to permit more efficient compilation. The translator would emit C code which then be compiled and run well outside of the APL workspace.
Today, execution speed is less critical and many popular languages are implemented using virtual machines - instructions that are interpreted at runtime. The Burroughs/Unisys APLB interpreter (1982) was the first to use dynamic incremental compilation to produce code for an APL-specific virtual machine. It recompiled on-the-fly as identifiers changed their functional meanings. In addition to removing parsing and some error checking from the main execution path, such compilation also streamlines the repeated entry and exit of user-defined functional operands. This avoids the stack setup and take-down for function calls made by APL's built-in operators such as Reduce and Each.
APEX, a research APL compiler, is available from Snake Island Research Inc. APEX compiles flat APL (a subset of ISO N8485) into SAC, a functional array language with parallel semantics, and currently runs under Linux. APEX-generated code uses loop fusion and array contraction, special-case algorithms not generally available to interpreters (e.g., upgrade of permutation vector), to achieve a level of performance comparable to that of Fortran.
The APLNext VisualAPL system is a departure from a conventional APL system in that VisualAPL is a true .Net language which is fully inter-operable with other .Microsoft .Net languages such as VB.Net and C#. VisualAPL is inherently object oriented and Unicode-based. While VisualAPL incorporates most of the features of legacy APL implementations, the VisualAPL language extends legacy APL to be .Net-compliant. VisualAPL is hosted in the standard Microsoft Visual Studio IDE and as such, invokes compilation in a manner identical to that of other .Net languages. By producing .Net common language runtime (CLR) code, it utilizes the Microsoft just-in-time compiler (JIT) to support 32-bit or 64-bit hardware. Substantial performance speed-ups over legacy APL have been reported, especially when (optional) strong typing of function arguments is used.
An APL to C# translator is available from Causeway Graphical Systems. This product was designed to allow the APL code, translated to equivalent C#, to run completely outside of the APL environment. The Causeway compiler requires a run-time library of array functions. Some speedup, sometimes dramatic, is visible, but happens on account of the optimisations inherent in Microsoft's .Net framework.
A source of links to existing compilers is at APL2C
APL also identifies those features built into the language, and represented by a symbol, or a fixed combination of symbols, as primitives. Most primitives are either functions or operators. Coding APL is largely a process of writing non-primitive functions and (in some versions of APL) operators. However a few primitives are considered to be neither functions nor operators, most noticeably assignment.
From a user's standpoint, the additional characters can give APL a special elegance and concision not possible in other languages, using symbols visually mnemonic of the functions they represent. Or it can lead to a ridiculous degree of complexity and unreadability, typically when the symbols are strung together into a single mass without any comments. Or it can be unreasonably difficult and time consuming to enter then later edit those APL statements.
A more up to date keyboard diagram, applicable for APL2 and other modern implementations, is available: Union layout for windows
All APL symbols are present in Unicode, although some APL products may not yet feature unicode, and some APL symbols may be unused or unavailable in a given vendor's implementation:
Additional APL characters were available by overstriking one character over another. For example, the log symbol was formed by overstriking shift-P with shift-O. This complicated correcting mistakes and editing program lines. This may have ultimately been the reason for early APL programs to have a certain dense style - they were difficult to edit.
Many overstrikes shown in the above table, although appealing, are not actually used. New overstrikes were introduced by vendors as they produced versions of APL tailored to specific hardware, system features, file system, and so on. Further, printing terminals and early APL cathode-ray terminals were capable of displaying arbitrary overstrikes, but as personal computers rapidly replaced terminals as a data-entry device, APL character support was now provided as an APL Character Generator ROM or a soft character set rendered by the display device. With the advent of Windows, APL characters were defined as just another complete font, thus the distinction between overstruck characters and standard characters having been eliminated.
Later IBM terminals, notably the IBM 3270 display stations, had an alternate keyboard arrangement which is the basis for some of the modern APL keyboard layouts in use today. Better terminals, namely display devices instead of printers, encouraged the development of better full screen editors, which had a measurable improvement in productivity and program readability.
APL has been used for rapid development of interactive Domain Specific Languages. Until as late as the mid-1980s, APL timesharing vendors offered applications delivered in the form of domain specific languages. On the I. P. Sharp timesharing system, a workspace called 39 MAGIC offered access to financial and airline data plus sophisticated (for the time) graphing and reporting, in the form of a domain specific language. Another example is the GRAPHPAK workspace supplied with IBM's APL2; a demonstration version of both APL2 and GRAPHPAK can be downloaded for Windows. APL has been used to generate Fortran, COBOL, and Java code, replacing legacy systems written in those languages.
Interest in APL has steadily declined since the 1980s. This was partially due to the lack of a migration path from performant mainframe implementations to early low-cost personal computer alternatives and the availability of high-productivity end-user computing tools such as Microsoft Excel and Microsoft Access. These are appropriate platforms for what may have been mainframe APL applications in the 1970s and 1980s. Some APL users migrated to the J programming language, which offers more advanced features. Lastly, the decline was also due in part to the growth of MATLAB, GNU Octave, and Scilab. These scientific computing array-oriented platforms provide an interactive computing experience similar to APL, but more resemble conventional programming languages such as Fortran, and use standard ASCII.
Notwithstanding this decline, APL finds continued use in certain fields, such as accounting research (Stanford Accounting PhD requirements)
Some words in the APL vocabulary have usage or meaning which is at variance with usage in mathematics or computer science.
|function||1. symbols for built-in facilities in the language to perform such things like addition and subtraction, i.e. + and -. (These are often called "operators" elsewhere in the computer science community)|
|2. a typical APL program|
|niladic||a function which takes no arguments,|
|monadic||a function which requires only a right argument, or an operator which requires only a left argument, unary|
|dyadic||a function (or operator) which requires both a left and right argument, binary|
|nomadic||a function which takes an optional left argument and is thus able to be used in a monadic or dyadic context|
|operator||a construct in APL which takes as a function argument and returns a new function. The monadic / operator (reduction) takes as its sole left argument the addition function +, which results in the function +/, which adds up the elements of a vector|
|vector||a one-dimensional array|