J
J is an array language that continues Ken Iverson's work on SHARP APL, designed with Roger Hui beginning in 1990. It breaks from APL in using only ASCII characters for primitive functionality, with multiple characters per primitive allowing for a much larger primitive set than classic APL. J takes leading axis theory and tacit programming (with the then-new function trains) as foundational design principles. Its approach to these ideas, along with some specific primitives, has been brought to the APL mainstream through Dyalog APL starting in 2014; the BQN and Uiua languages are also influenced by J.
Language overview
J focuses heavily on flat array programming using the boxed array model (as in SHARP APL), as well as tacit programming. Its syntax is an extension of APL expressions, and is described using terms from English grammar as in A Dictionary of APL. Arrays are called nouns, functions are called verbs, and operators are called adverbs if monadic and conjunctions if dyadic. Each primitive is spelled with a single ASCII character possibly followed by a period (.) or colon (:), and rarely another of these two suffixes (e.g. F:.). Primitives may come from Iverson's earlier work but may be simplified or regularized in ways not backwards compatible with APL. Examples include removing last-axis forms of primitives and function axis, and disentangling reduction from scans and windowed reductions with the prefix and infix operators.
An area of focus for J is mathematics, particularly number theory, combinatorics, matrix algebra, and calculus. Complex float, extended integer, and rational number types are available, and multi-function primitives for prime numbers and factorization (p:, q:), polynomials (C.), and permutations (C.) are defined. Calculus-specific primitives such as derivative and Taylor series support were removed in 2019 in favor of libraries, due to lack of use and maintenance concerns.
Tacit programming is supported primarily through function trains and a range of function-manipulating conjunctions like Over. Unlike later APL implementations, the 2-train forms a hook where the leftmost function is always dyadic. The train allows most common types of expressions to be written tacitly, and a special form exists to convert explicit source code to a tacit function automatically. Many kinds of operator-level train are defined as well; they were mostly removed early in J's history, leaving only a few forms, before being re-added in 2021.
J also supports an explicit style to define functions and operators with named arguments. Since 2020, dfn-inspired direct definition syntax with double braces {{ }} is the preferred way to write them, superceding a : operator that takes source code either as a string or from following lines terminated by ). Explicit functions use local lexical scope, where a variable defined with =. is local to its containing function (and not accessible to others inside it) and one defined with =: is defined more globally in the current locale. Many control structures are supported, including for and while loops, labels and goto, and try, throw, and catch.
The namespace-like locale is used to organize code and to support objects in the sense of object-oriented programming. A locale is not a first-class value, but instead is referenced by a string name or number, depending on how it was defined. At any given time a current locale is active; it may also have an inheritance path of other locales whose names are accessible. Locales are not garbage-collected and can only be freed by the program.
History
J was initially designed primarily by Ken Iverson and Roger Hui, with input from Arthur Whitney and Eric Iverson. Ken had been considering a new language based on A Dictionary of APL but without the backwards compatibility constraints of APL and the custom character set (which was a major technical issue at the time). In "A Personal View of APL"[1] he gives the following as the most important goals for a new language:
- Is available as “shareware”, and is inexpensive enough to be acquired by students as well as by schools
- Can be printed on standard printers
- Runs on a wide variety of computers
- Provides the simplicity and the generality of the latest thinking in APL
Iverson's phrase "the latest thinking in APL" refers to two major breakthroughs made that decade: the invention of the Rank operator by Arthur Whitney in 1982 and subsequent development of leading axis theory, and the invention of function trains by Iverson and Eugene McDonnell in 1988.
In the summer of 1989 Whitney visited Iverson, who discussed with Whitney his plans for a new array language. Whitney wrote a one-page prototype for the language in a single afternoon using C. Iverson shared the program with Roger Hui, who began working on J on August 27 and quickly produced a more complete prototype.[1][2][3] The name "J", chosen by Hui when saving the first source code file,[4] is meaningless: in An Implementation of J, Hui remarks "Why 'J'? It is easy to type."[5] J was first presented by Hui and Iverson, including a live demo, at a meeting of the Toronto APLSIG in February 1990.[6]
In 1990 Hui and Iverson joined Iverson Software Inc. (now Jsoftware), which had been founded that year by Eric Iverson to sell a SHARP APL product. Eric converted his SHARP session to use with J as Hui continued on the core language's implementation. The J language, including Eric's session environment, was first released at APL90 in Copenhagen August 1990.[6] Hui, both Iversons, and new hire Chris Burke continued working on the J's implementation, and applications, in the following years.
The J source code was made open under the GPL in March 2011.[7] However, this move did not immediately bring in outside developers; rather, as Ken Iverson had died in 2004, and Roger Hui started a new job at Dyalog Ltd. in 2008, this was a time of little development for J. Eric Iverson continued work on the development environment including new Qt- and browser-based IDEs. Since 2016,[8] Henry Rich has lead development of the interpreter, making performance improvements as well as extending and adding primitives and other functionality.
Influence
J has had a substantial influence on APL and other array languages since the 2010s, particularly in promoting the leading axis model and tacit programming with function trains.
Many J features have been taken into Dyalog APL through Roger Hui's work on the dialect, with various changes to adapt to APL or account for J experience. Version 14.0 in 2014 introduced function trains, the Rank operator, major cell search, Tally, and Key, and version 16.0 added Where, Interval Index, and Stencil (from Cut). Version 18.0 added Unique Mask, Atop, and Over, which had come from SHARP APL to J. Some of these (trains, Tally, Where, Over) were added to NARS2000 around 2010, preceding Dyalog. Most have been taken up quickly by hobbyist dialects, although the operators Key and Stencil are less often supported and sometimes modified, and Interval Index has also seen somewhat slower adoption. The Square Root primitive, while not yet seen in Dyalog, has been added to NARS2000, dzaima/APL, Kap, and TinyAPL.
BQN's designer Marshall Lochbaum was previously a long-term J programmer (and made I exploring another approach to its tacit programming). BQN adopts the broad ideas of leading-axis and tacit programming as well as various details such as multi-axis Rotate, and the idea that operators like Power and Rank can apply the right operand to the arguments for a dynamic value. BQN rejects other J changes in favor of older APL ideas, for example using an APL-style Scan and dyadic Transpose, and array-partitioning functions rather than J's operators (Lochbaum called the use of APL-style rather than J-style Reshape a "blunder"[9]).
Uiua, as well as TinyAPL, use J ideas primarily through the influence of BQN. However, both languages have also taken features passed over by BQN directly from J, most notably with Uiua's use of the boxed array model. Uiua shares J's looser approach to inverses, taking for example prime factorization for the inverse of times-reduce from J. TinyAPL implements many primitives from J, such as On Prefixes, as well as ideas related to modifier trains like Lev and Dex.
J's tacit programming and primitive set inspired the code golfing language Jelly, which as one of the most successful golfing languages of the 2010s had a significant influence on many subsequent ones.
Versions
J has used multiple numbering systems. Releases prior to 1994 used a single decimal and the naming scheme "Version X.Y", while those after used two decimals and are called "Release X.YY", or "JXYY" as in "J807". Since version 9.4, or "J9.4", they again remove the leading zero and use a third decimal to indicate revisions within a version (as in "9.4.2"; revision 0 indicates beta or pre-release revisions).
| Version | Date | Features |
|---|---|---|
| 2.0 | 1990-08-09 | (APL90) |
| 2.7 | 1990-10-22 | Rank with a function right operand, Under |
| 2.8 | 1990-11-15 | |
| 2.9 | 1991-02-15 | Monadic +: (double), -: (halve), *: (square), dyadic ": (Format), constant functions 0: and 1:
|
| 3.0 | 1991-03-17 | Changes to spellings, Reverse with Variant to specify fill |
| 3.1 | 1991-05-17 | Determinant (.)
|
| 3.2 | 1991-06-02 | ,. for ravel items (like Table) and append lists, ; for Raze and Link, @. for agenda, non-close compositions
|
| 3.3 | 1991-06-25 | Dyadic ,. changed to append items, more types of trains
|
| 3.4 | 1991-07-15 | NB. for comments
|
| 4.0 | 1991-11-23 | Monadic +. and *. for complex components and phase/magnitude with j. and r. to recombine, ^:_ for power limit
|
| 4.1 | 1992-02-02 | ^!.p for rising/falling factorials
|
| 4.2 | 1992-03-19 | |
| 5.0 | 1992-06-22 | Variant to specify comparison tolerance and fill for Take |
| 5.1 | 1992-07-28 | f. to expand a tacit function containing names, constant functions 2: to 9:
|
| 5.1a | 1992-08-11 | |
| 6.0 | 1992-10-24 | Error handling with ::, additional system functions
|
| 6.1 | 1992-11-26 | Amend operator }
|
| 6.2 | 1992-12-20 | Derivative operator D.
|
| 7.0 | 1993-11-14 | Taylor series operators t. and T.
|
| Release | Date | Features |
|---|---|---|
| 2.01 | 1994-09-01 | Control structures, many additional system functions |
| 2.03 | 1994-09-21 | |
| 2.04 | 1994-11-28 | |
| 2.05 | 1995-02-26 | Additional inverses, primitive array a: ("ace")
|
| 2.06 | 1995-05-30 | More inverses, hypergeometric operator H., and prime functions p., p:, and q:
|
| 3.01 | 1996-01-16 | Repeatable Roll/Deal ?., Depth L. and Depth operator L:, total array ordering
|
| 3.02 | 1996-06-24 | Pick variant {::, extended precision types
|
| 3.03 | 1996-12-13 | Multiple assignment using a string target |
| 3.04 | 1997-05-19 | More operators with gerund operands, for. and select. control structures
|
| 3.05 | 1997-09-27 | Extended dyad q: (Factor) to take a negative left argument
|
| 4.01 | 1998-03-22 | Find (E.) and Index of Last (i:)
|
| 4.02 | 1998-11-07 | Symmetric range monad (i:), infinite left arguments to Take
|
| 4.03 | 1999-04-21 | |
| 4.04 | 2000-01-02 | Sparse array support |
| 4.05 | 2000-09-05 | Comparison tolerance for Key |
| 4.06 | 2001-05-09 | assert. and throw., Symbols (s:) and Unicode (u:), multiple axes in Cut operator
|
| 5.01 | 2002-09-10 | Non-close Under &.:, Bitwise Operations (b.), Polynomial Derivative (p..), Head ({.) and Tail ({:) allow empty arguments
|
| 5.02 | 2003-05-21 | |
| 5.03 | 2004-03-19 | Indices (I.), Sequential Machine (;:)
|
| 5.04 | 2005-03-18 | J64 (64-bit version) introduced, boxed right argument for Power operator, scalar extension for left argument of Cut (;.)
|
| 6.01 | 2006-07-21 | Noun left arguments in trains (N0 V1 V2), dots removed from explicit argument names (y. to y, etc.), Interval Index (I.)
|
| 6.02 | 2008-02-29 | Index Of (i.) extended to allow unmatched cell shapes, Memoize adverb (M.)
|
| 7.01 | 2010-08-05 | GTK IDE |
| 7.02 | ||
| 8.01 | 2014-02 | Qt IDE |
| 8.02 | 2014-08-02 | Qt IDE improved |
| 8.03 | 2014-12-09 | Native read/write of jpeg and png images |
| 8.04 | 2016-01-04 | |
| 8.05 | 2016-12-19 | Improved UTF-8 handling, memory allocator rewritten with more in-place argument usage |
| 8.06 | 2017-11-12 | Allow array right operands to Atop and Adverse (::), treating as constant functions, improved vector instruction usage
|
| 8.07 | 2018-10-08 | Removed support for dot-style explicit arguments (e.g. y.)
|
| 9.01 | 2019-12-15 | Iteration primitives F.., F.:, F., F:., F::, F:; Remove calculus operators d., D., D:, t., t:, T., .., .:; gerund"r
|
| 9.02 | 2020-12-13 | "Direct definition" syntax for explicit functions, special semidual form u&.:(a:`v) added, minor incompatible changes
|
| 9.03 | 2021-12-17 | Modifier trains and other combinations, foreigns to enable nameref caching, Kahan summation with +/!.0[10]
|
| 9.4 | 2023-03-01 | Threading using T. and t.,[11] Key-like /.., reimplementation of exact integers and rationals with GMP[12]
|
| 9.5 | 2023-12-20 | Modular arithmetic (m.), changes and restrictions to Select ({) and Amend (}), limited structural Under support[13]
|
| 9.6 | 2025-02-24 | 8+8-byte float, 2- and 4-byte int datatypes, type conversion (c.), Indices inverse (I.^:_1), _ to compute length in Reshape ($)
|
References
- ↑ 1.0 1.1 Iverson, K.E. "A Personal View of APL". IBM Systems Journal, Volume 30, Number 4. 1991-12.
- ↑ Hui, Roger. "Incunabulum". From An Implementation of J, Appendix A: Incunabulum, 1992-01-27.
- ↑ McIntyre, Donald. "A Tribute to Roger Hui, presented at APL96". 1996.
- ↑ Roger Hui and Morten Kromberg. APL since 1978. §10.2 What's in a Name?. ACM HOPL IV. 2020-06.
- ↑ Hui, Roger. An Implementation of J (pdf), Preface. 1992-01-27.
- ↑ 6.0 6.1 Hui, Roger. "Remembering Ken Iverson". 2004-11.
- ↑ Eric Iverson. "J Source GPL". 2011-03-02.
- ↑ Eric Iverson. "j805-beta-11 release candidates". 2016-08-23.
- ↑ Marshall Lochbaum. Five-year review of BQN design § Flat arrays. 2025-05-10.
- ↑ Array Cast episode 18: Henry Rich presents J903
- ↑ Array Cast episode 48: Henry Rich Reveals J with Threads J9.4
- ↑ Array Cast episode 59: Raul Miller - Precision
- ↑ Array Cast episode 73: Henry Rich and the Release of J9.5
| APL dialects [edit] | ||
|---|---|---|
| Maintained | APL+Win ∙ APL2 ∙ APL64 ∙ APL\iv ∙ Aplette ∙ April ∙ Co-dfns ∙ Dyalog APL ∙ Dyalog APL Vision ∙ dzaima/APL ∙ GNU APL ∙ Kap ∙ NARS2000 ∙ Pometo ∙ TinyAPL | |
| Historical | A+ (A) ∙ APL# ∙ APL2C ∙ APL.68000 ∙ APL-10 ∙ APL*PLUS ∙ APL.jl ∙ APLX ∙ Extended Dyalog APL ∙ I-APL ∙ ngn/apl ∙ openAPL ∙ Parrot APL ∙ Rowan ∙ SAX ∙ SHARP APL ∙ VisualAPL (APLNext) ∙ VIZ::APL | |
| Mainframe | APL\360 ∙ APL/700 ∙ APL\1130 ∙ APL\3000 ∙ APL/B5500 ∙ APLB ∙ APL.SV ∙ APLGOL ∙ APLUM ∙ CDC APL 2 ∙ IVSYS/7090 ∙ NARS ∙ PAT ∙ UMASS-APL ∙ VS APL ∙ Xerox APL ∙ York APL | |
| Publications | A Programming Language ∙ Iverson notation ∙ Operators and Functions ∙ Rationalized APL | |
| Derivatives | AHPL ∙ APL/S ∙ Apple ∙ BQN ∙ CoSy ∙ ELI ∙ EMPL ∙ Glee ∙ I ∙ Ivy ∙ J ∙ Jelly ∙ K (Goal, Klong, Q) ∙ KamilaLisp ∙ Lang5 ∙ Lil ∙ Nial ∙ RAD ∙ Uiua | |
| Overviews | Comparison of APL dialects ∙ Timeline of array languages ∙ Timeline of influential array languages ∙ Family tree of array languages | |