Nial
Nial, the Nested Interactive Array Language, is the array language Mike Jenkins of Queen's University and Trenchard More of IBM built on More's array theory between 1979 and 1983 - APL's whole-array programming rewritten in ASCII words with Lisp-style nesting, functional combinators called transformers, and Pascal-like control structures - implemented by the portable C interpreter Q'Nial, sold by Nial Systems Limited from 1982, open-sourced as Version 6.3 in 2006 and re-released as the 64-bit Q'Nial 7 on GitHub in 2017
Created by Michael A. (Mike) Jenkins, professor of computing at Queen's University, Kingston, Ontario (Stanford PhD 1969, co-author of the Jenkins-Traub polynomial root-finding algorithm, and a former member of the IBM APL project at Yorktown Heights), and Trenchard More (1930-2019) of the IBM Cambridge Scientific Center, originator of array theory and a participant in the 1956 Dartmouth AI workshop; the Q'Nial interpreter was built by Jenkins's team at Queen's (Carl McCrosky, Lynn Sutherland and others), commercialised through Jenkins's company Nial Systems Limited, and brought to GitHub as Q'Nial 7 by Jenkins with John Gibbons
Nial - the Nested Interactive Array Language - is what you get when a mathematician with a formal theory of nested arrays meets a numerical analyst who has spent a decade implementing APL. Trenchard More of the IBM Cambridge Scientific Center supplied array theory, a one-sorted mathematics in which every item of an array is itself an array; Mike Jenkins of Queen’s University in Kingston, Ontario supplied the programming-language design and a portable C interpreter, Q’Nial. The result, designed between 1979 and 1983, is an APL-family language that abandons APL’s special character set for ASCII words, adds Lisp-style nested data and functional combinators, and wraps the whole thing in Pascal-like control structures so that ordinary programmers can use it. Q’Nial was sold commercially by Nial Systems Limited from 1982, became a research vehicle for artificial intelligence and parallel computing in the late 1980s, was released as open source in 2006, and survives today as Q’Nial 7 on GitHub - a small, quiet community, but a language that has been continuously runnable for more than forty years.
History and origins
Array theory
The story begins not with Jenkins but with Trenchard More (1930-2019). More had taught at MIT and Yale, had attended the 1956 Dartmouth summer workshop that gave artificial intelligence its name, and by the early 1960s was thinking about a mathematical theory of arrays in which the items of an array could themselves be arrays - combining the multi-axis arrays of Iverson and Falkoff’s APL with the nesting of Zermelo-Fraenkel set theory and Quine’s controversial idea of self-containing atoms. In 1968 he joined the APL Design Group at IBM’s Yorktown Heights research centre to work on the theory full time, and in March 1973 he published its founding paper, ‘Axioms and Theorems for a Theory of Arrays’, in the IBM Journal of Research and Development. In 1974 he moved to the IBM Cambridge Scientific Center in Massachusetts, where successive refinements of the theory were tested against implementations. His 1979 APL conference paper ‘The nested rectangular array as a model of data’ set out the case for nested arrays that shaped both IBM’s APL2 and Nial.
Jenkins and Queen’s
Michael A. Jenkins came to arrays from numerical analysis. He took his PhD at Stanford in 1969 - the Jenkins-Traub algorithm for polynomial roots, published with Joseph F. Traub in 1970, still bears his name - and went straight to the IBM APL project at Yorktown before joining Queen’s University in 1969. Through the 1970s he worked on APL translation techniques, on an extensible language based on APL concepts (with Jean Michel) and on extending APL with recursive, tree-like data. He met More at the early APL conferences and the Minnowbrook APL implementers’ workshops, and in 1979 he went to the Cambridge Scientific Center as an IBM Visiting Scientist to begin a collaboration: More’s array mathematics married to Jenkins’s knowledge of language design and implementation.
The name was suggested by Ole Franksen of the Technical University of Denmark, who wanted an acronym that captured the language’s features - interactive, with nested arrays and nested control structures - and that hinted at its motivation. Njal’s Saga, the oldest of the Icelandic sagas, tells of the coming of the rule of law to the Viking settlements around the year 1000; since Njal is sometimes spelled Nial, the name was chosen to remind users of the universal laws of data built into the design. Q’Nial’s logo is a Viking ship, chosen to reflect the Nordic origin of the name.
Q’Nial
With support from IBM and Queen’s, Jenkins assembled a team - Carl McCrosky, Lynn Sutherland and others - to build an interpreter. Two decisions shaped it. First, the language would use ASCII: the APL character set had been a serious obstacle on the hardware of the day, and Nial would spell its primitives as English words. Second, the interpreter had to be portable enough to run on both the newly released IBM PC and IBM mainframes, which, with the C compilers of 1982, severely constrained what could be implemented directly. The portable interpreter, designed under Unix, was ‘ready for release in late 1983’ as Q’Nial Version 4 (later 4.1). Nial Systems Limited had been set up in Kingston in 1982 to license the interpreter from the university and sell it, and Jenkins spent 1983-84 as a visiting professor at MIT.
Design philosophy
Nial’s designers described it as a hybrid: a functional array language, based on More’s theory, inside a procedural language with familiar control structures. Two principles guided the work - the expression language would follow array theory, and the programming constructs would reflect the practice of the time (Pascal, structured programming). More’s own view, recorded on the old Nial Systems website, was that the initial Q’Nial ‘reflected the desire to stay close to More’s theoretical ideas, while providing procedural control, flexible file handling and interactive input/output’.
The mathematical heart of the language is that everything is an array. An integer is a zero-dimensional array whose sole item is itself; a string is a list of characters; a table is a two-dimensional array; and any item of any array may be another array of any shape and depth. Because the rules of array theory are stated as universally valid equations - identities that hold for every array, empty or not - the behaviour of primitives on edge cases is derived rather than chosen. The most notorious consequence, in More’s version of the theory, was that there are as many different empty arrays of a given shape as there are arrays: ‘a list of no 2s differs from a list of no 3s’. Version 4 of Q’Nial implemented this faithfully; Version 6 gave it up.
Jenkins’s own summary of what Nial borrowed is that it combined ’the strengths of APL array-based programming with implementation concepts borrowed from LISP, structured programming ideas from Algol, and functional programming concepts from FP’ - Backus’s FP supplying the idea of building programs by combining functions with second-order operators.
Key features
Atoms, strands and nested arrays
Nial has six atomic types: booleans (displayed as l and o), integers, reals, characters (written with a backquote, `x), phrases - indivisible symbols written "Hello - and faults, error values written with a question mark such as ?div, ?eof or ?conform. Faults are ordinary data: 27/0 evaluates to ?div, and a program can test for it rather than crash. Juxtaposing expressions forms a strand, so 5 3 4 -2 is a list of four integers and `a `b `c is the string 'abc'; bracket notation [3, 42, 27] builds the same lists and can mix types and nest freely. Q’Nial displays nested results as box diagrams:
(3 4 5) (8 9 10) (11 12 13)
+-----+------+--------+
|3 4 5|8 9 10|11 12 13|
+-----+------+--------+
[ [1, 2], [ [3, 4], 5] ]
+---+-------+
|1 2|+---+-+|
| ||3 4|5||
| |+---+-+|
+---+-------+
Operations and pervasive arithmetic
Functions are called operations; every operation takes exactly one array argument, and an infix use like 2 + 3 is simply the operation + applied to the pair 2 3. Expressions evaluate strictly left to right with no operator precedence: 3+5*4 is 32. Arithmetic is pervasive - it distributes through nesting automatically, so X + X on a list adds item by item and abs -3.5 27 -8 gives 3.5 27 8. A session from Jenkins’s 2009 NYU lecture:
X := 5 3 4 -2
5 3 4 -2
X * X
25 9 16 4
sum X
10
X OUTER * X
25 15 20 -10
15 9 12 -6
20 12 16 -8
-10 -6 -8 4
A := 4 6 reshape count 24
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
count 10 generates 1 2 ... 10, tell 5 generates 0 1 2 3 4, reshape builds tables, mix turns a list of equal-length lists into a table, pack transposes a list of records into a record of lists, and gradeup random 10 produces a random permutation.
Transformers and atlases
Second-order functions are transformers: they take operations and return operations. EACH f applies f to every item of an array; EACHBOTH, REDUCE, FOLD, SORT and OUTER are others, and users can define their own. An atlas such as [sum, tally] is a list of operations that, applied to an argument, yields the list of their results, so the average of a list can be written point-free:
average IS / [sum, tally]
[sum, tally] 3 18 27 45 7 23
123 6
average 3 18 27 45 7 23
20.5
Nial Systems’ own documentation is candid that, elegant as this is, ’the explicit argument form of definition is what is used in practice by most Nial programmers because it is easier to comprehend’. That form looks like this:
average IS OPERATION Numbers {
sum Numbers / tally Numbers }
get_averages IS OPERATION Records {
Nms Stnos Marks := pack Records;
Avgs := EACH average Marks;
pack Nms Avgs }
Definitions use IS; assignment is := (or the word gets), and a strand of names on the left destructures a list. Variables inside an operation body are local by default, which - as Jenkins noted in the interpreter’s design paper - makes the heap behave like a stack and let Q’Nial dispense with garbage-collection compaction altogether.
Control structures and the environment
The procedural half of the language provides IF ... THEN ... ELSEIF ... ELSE ... ENDIF, WHILE ... DO ... ENDWHILE, REPEAT ... UNTIL, FOR ... WITH ... DO ... ENDFOR over the items of an array, CASE ... FROM ... ENDCASE, expression sequences separated by semicolons, and blocks with LOCAL and NONLOCAL declarations. Q’Nial is a workspace system in the APL tradition: an interactive loop reads a program fragment, evaluates it and displays a picture of the result (in framed ‘diagram’ or compact ‘sketch’ mode), and definitions and data live in a workspace that can be saved and reloaded. Source files carry the extension .ndf.
| Concept | Nial term | Example |
|---|---|---|
| Zero-dimensional array | single / atom | 357, `x, "word, ?div |
| Symbol | phrase | "Hello or phrase 'Hello, world!' |
| Error value | fault | 27/0 gives ?div |
| Sequence of expressions | strand | 18 -2 (25 * 4) gives 18 -2 100 |
| Function | operation | sum, reshape, average IS OPERATION A { ... } |
| Function of functions | transformer | EACH, REDUCE, OUTER |
| List of operations | atlas | [sum, tally] |
| Empty list | Null | Null = count 0 is l (true) |
Evolution
Version 4 (1983). The original Q’Nial, developed jointly with More, followed array theory closely: multiple empty arrays, an elaborate algorithm for reshaping mismatched arithmetic operands to a common shape, and the full V4 syntax. It ran on Unix, MS-DOS (the surviving tutorial begins ‘Getting Started with Q’Nial on a Fixed Disk IBM PC’) and IBM mainframes, and Jenkins’s CV from the late 1990s reports it distributed to about 200 sites in 15 countries. The 1980s research output was substantial: the 1984 ACM ‘fifth generation’ paper argued that Nial’s whole-array operations were a natural way to describe parallel computation; Programming Styles in Nial (IEEE Software, 1986) showed functional, procedural and array solutions to the same problems; and Janice Glasgow’s work with Jenkins extended the language toward logic programming, producing the Nial AI Toolkit (1988) and Logic programming with arrays (1991). Carl McCrosky even designed a processor architecture for array-theoretic computation (1989).
Version 6 (1990s). After roughly ten years of feedback from programmers, Jenkins undertook a major redesign that ‘sacrificed some of the generality of the functional model’. Version 6 has a single empty array per shape - Null = '' holds - returns a ?conform fault where V4 would have silently reshaped, and restricts the syntax to a subset of V4’s. This is the Nial that survives today; Jenkins’s 2013 monograph compares ‘an abstract Version 4 of array theory with a more conventional, conformal Version 6’. On this base Nial Systems built Q’Nial for Windows, with a session-manager window and editor windows for definitions; the Nial Data Engine, an embeddable interpreter with a small C interface; and CGI-Nial for web applications.
Open source (2006). Queen’s transferred the intellectual property in Q’Nial to Jenkins in 2001, and in 2006 Nial Systems released Version 6.3 - source and binaries - under a copy of the Perl Artistic License 1.0 modified only to name NIAL Systems Limited as copyright holder. The manuals from this release (Introduction to Q’Nial, The Language Definition, The Nial Dictionary, Using Q’Nial for Windows, Using the Nial Data Engine, Using CGI-Nial) are dated August 2005 and August 2006 and remain the fullest description of the language. Robert Lefkowitz preserved the whole 6.3 distribution on GitHub as PlanetAPL/nial in 2013.
Q’Nial 7 (2017). In 2014 Jenkins began working with John Gibbons on a 64-bit version. Q’Nial 7, published on GitHub on 26 July 2017 under the GPLv3 with a companion paper, ‘The Design of the Q’Nial’, re-targets the interpreter at ’the execution of scripts written in Nial in a Unix environment’: 32- and 64-bit builds, the removal of the old multi-platform front ends in favour of Linux, macOS, Raspbian and Windows console builds, a reduced role for workspaces, interactive mode as an explicit choice, and a documented mechanism for adding extensions. The extensions shipped with it are aimed at multiprocessor data analysis: associative arrays, process creation and management, byte streams and serialisation, socket pairs and pipes, shared memory with process coordination, and dynamic loading of C libraries. The examples directory shows TCP worker servers, shared-memory atomics and a simulated-annealing N-queens solver written in Nial.
Current relevance
Nial is dormant but not dead. In November 2021 the project moved to a niallang GitHub organisation whose Nial_Development repository added FreeBSD support and a makefile build in 2022 before falling quiet in October of that year; sibling repositories hold Nial libraries, editor tooling, the nial-array-language.org website (last updated in late 2023) and a work-in-progress WebAssembly runner that executes Nial in the browser. Prebuilt ‘Originals’ binaries for 64-bit Linux and Windows, macOS and Raspbian date from January 2022, and building from source needs only a C compiler, make and cmake. The project website points to a Nial channel on the APL-family Discord server, a Matrix room and the r/apljk subreddit for discussion, and Try It Online still offers a Nial interpreter. There is no Docker image.
Jenkins’s free monograph Array Theory and the Design of Nial (2013), the 2017 design paper and the V6 manuals give the language an unusually complete paper trail for something this small, and the source - a stack-based abstract array machine with a first-fit heap, a parse-tree evaluator and an object table for phrases and faults, all in portable C - is compact enough to read in an afternoon.
Why it matters
Nial occupies a distinctive place in the APL family. It put Trenchard More’s array theory directly into programmers’ hands, and it did so in a way APL2 - the other child of that theory - never attempted: with ASCII keywords instead of a special character set, with Lisp-like nested data displayed as box diagrams, with FP-style combinators as first-class syntax, and with the IF/WHILE/FOR of structured programming alongside them. Its designers argued, as early as 1984, that whole-array operations were the right way to express parallelism, and Nial became a testbed for that idea, for array-based logic programming and for fuzzy inference. The V4-to-V6 transition is also a rare, well-documented case study of a language designer deliberately trading mathematical purity (many empty arrays) for practicality (one), and explaining why. For anyone trying to understand how APL’s ideas were re-imagined for the personal-computer era - or simply looking for a readable, runnable nested-array language whose whole implementation fits in one repository - Nial rewards the visit.
Timeline
Notable Uses & Legacy
Molecular Scene Analysis project, Queen's University
Janice Glasgow's Molecular Scene Analysis project at Queen's, an AI approach to determining molecular structure from crystallographic data, used Nial; Jenkins's faculty page described Nial as 'in active use' there and at several other sites
The Nial AI Toolkit and logic programming with arrays
Queen's researchers (Jenkins, Glasgow, Blevis, Feret, Hache, Lawson) built an AI toolkit in Nial, presented at Avignon in 1988, and extended the language to support logic programming directly - work published as 'Logic programming with arrays' in IEEE Transactions on Knowledge and Data Engineering in 1991; Nial was listed as an AI tool in Bundy and Wallen's 1984 Springer catalogue
Technical University of Denmark - array-based logic and fuzzy control
Ole Franksen's group at DTU collaborated with Queen's from 1982, using Nial and array theory in systems science and 'array-based logic'; Jan Jantzen used Nial for fuzzy control, publishing 'Fuzzy Inference using Array Theory and Nial' in 1991
Nial Systems Limited - commercial Q'Nial and web prototyping
The Kingston company sold Q'Nial for Unix, DOS, Windows and IBM mainframes from 1982 for decision support, knowledge-based systems, scientific computing and data analysis, later adding the embeddable Nial Data Engine and CGI-Nial, which Jenkins used to prototype web-based applications
Q'Nial 7 extensions - process and stream programming
The 2017 open-source release bundles examples in which Nial scripts drive TCP worker servers and clients, shared-memory process coordination and simulated-annealing solvers for the N-queens problem, reflecting John Gibbons's use of the language for multiprocessor data-analysis work