Array notation
(⋄) [⋄]
|
Array notation ((⋄), [⋄]), abbreviated APLAN parallel to JSON, is a way to write most arrays literally, with no or minimal use of primitive functions, possibly over multiple code lines. It differs from the strand notation existing since APL\360 in that it can be used to write arrays of rank greater than one. Array notation is supported in dzaima/APL, BQN (using angle brackets ⟨⋄⟩ instead of round parentheses (⋄)), and Dyalog APL.
Array notation generally consists of a vector notation written with parentheses (), roughly equivalent to stranding, and a high-rank notation using square brackets [], indicating the Mix of a vector. It also supports namespaces, using name:value syntax in round parentheses. Statement separators must appear between elements and between name–value pairs.
Examples
An array notation vector is written in parentheses, with separators between elements. A separator can be a diamond ⋄ or newline (that is, the same characters used to separate APL expressions). Any expression can be used to compute an element.
(10 20 ⋄ ⍳4 ⋄ 'string') ┌─────┬───────┬──────┐ │10 20│1 2 3 4│string│ └─────┴───────┴──────┘
For a one-element vector, use an extra leading or trailing separator, as otherwise it will be interpreted simply as a parenthesized value. Leading and trailing separators are allowed (and ignored) in a vector of any length, as are duplicate separators between elements.
⍴ (5 ⋄) 1
Using newlines for the separators places each element on its own row, as in the following vector of three strings.
('Three'
'Blind'
'Mice')
This way of formatting is particularly useful when writing higher-rank arrays with square brackets, as in the two-row matrix below. In general, the entries in square brackets are mixed together, forming an array with rank one higher than the largest cell.
[1 2 3 4
5 6 7 8]
1 2 3 4
5 6 7 8
['string'
[9
1 2 3]]
s t r i n g
9 0 0 0 0 0
1 2 3 0 0 0The meaning of () differs among dialects: in dzaima/APL it is the empty vector, while in Dyalog APL it is an empty namespace.
Namespaces
To form a namespace, use parentheses with key-value pairs separated by a colon : rather than plain elements. Unlike a one-element vector, a one-field namespace can be written with no separator because the colon distinguishes it from ordinary parentheses.
(x:1 ⋄ y:2).y 2
The values in a namespace can again use array notation, as in the following namespace, which contains another namespace containing a character matrix.
(y:(x:['hello'
'world']))
Description
In order to maintain backwards compatibility, array notation uses previously invalid syntax. Its expressions all fall into one of the following cases, which are otherwise SYNTAX ERRORs.
- broken round parentheses:
(…) - broken square brackets:
[…] - empty round parentheses:
()
Here, broken means interrupted by one or more separators (diamonds ⋄ or line breaks) not enclosed by additional parentheses, brackets, or dfn braces. These separators break the contents into any number of statements, which are interpreted according to the following rules.
- A broken round parenthesis creates a namespace if every statement is a name-value pair.
- A broken round parenthesis creates a vector if every statement is a value expression. In that case, every statement's result becomes an element in the resulting vector.
- A broken square bracket creates an array where every statement result contributes a major cell to the resulting array.
()creates a new namespace, equivalent to(⎕NS 0⍴⊂'')- A name-value pair consists of a valid APL identifier, followed by a colon (
:) and a value expression.
To form an array from bracketed statement results, the values are placed in a list, then mixed. In Dyalog APL but not dzaima/APL, any scalar values are promoted to rank 1 beforehand, so that the resulting array has rank at least 2.
BNF syntax
The allowed syntax can be described using Extended Backus–Naur form, where an expression is any traditional APL expression (however, this description omits that array notation can be used within ordinary expressions):
value ::= expression | list | block | space
list ::= '(' ( ( value sep )+ value? | ( sep value )+ sep? ) ')'
block ::= '[' ( ( value sep )+ value? | ( sep value )+ sep? ) ']'
space ::= '(' sep? ( name ':' value ( sep name ':' value )* )? sep? ')'
sep ::= [⋄#x000A#x000D#x0085]+
History
- See also the Array notation design considerations#Timeline
One-dimensional list syntax with surrounding brackets and delimiters, matching sequence notation in mathematics, is common in programming. It appears as early as ALGOL 68 with parentheses, and square-bracket lists feature in languages from the 1970s such as ML and Icon. MATLAB uses matrix syntax with square brackets, semicolons to separate rows, and commas to separate elements within a row. FP uses angle brackets for lists, and square brackets for function "construction", with behavior like function arrays. A 1982 article by Randall Mercer[1] proposed a syntax with curly braces and semicolons and compared it favorably to strand notation, pointing out its ability to represent zero- and one-element lists, its lack of ambiguity when used on the left-hand side of assignment, and the possibility of creating lists of functions.
List notation appears in Nial using brackets and commas like [a,b,c], and allowing function arrays called "atlases". A+ and K have a list notation using parentheses and semicolons like (a;b;c). In A+ this is related to bracket indexing and an "expression group" notation written with curly braces and semicolons. It allows line breaks, but in addition to rather than in place of semicolons. The later K version corresponds more closely to APL: the semicolon is a statement separator and is interchangeable with a line break, and because K represents arrays with nested lists, it corresponds to both vector and high-rank array notation.
The first published proposals that influenced Dyalog APL's array notation were made by Phil Last at Dyalog '15 and later in Vector Journal.[2][3] Last cited the syntax of dfns as a sequence of expressions with enclosing braces, as well as APL#'s namespace notation enclosed in double brackets [[]], as precursors. His design used square brackets and assignment arrows for namespaces; in 2018 he implemented it in Acre Desktop, a project manager for Dyalog APL. Following Last's 2015 presentation, Adám Brudzewsky began work on array notation and presented on it in a series of conferences, initially using parentheses for the high-rank notation[4] and later returning to square brackets.[5][6] He suggested to change Last's ← to : (as in JSON) to allow arbitrary expressions, including those containing assignment, for namespace values. Dyalog APL 18.0, released in 2020, included support for array notation in source files loaded by Link,[7] but not in the language itself.[8] Morten Kromberg published a formal proposal for Dyalog and request for feedback in 2023,[9] which was amended the next month according to a suggestion by Dyalog employee Peter Mikkelsen: a dfn-like auto-localisation feature was removed from namespace scoping, making assignments in value expressions affect the surrounding scope—localisation can be achieved by wrapping the expression in an anonymous dfn. Dyalog APL 20.0, released in 2025, added support for array notation, with session and editor enhancements to take advantage of it.
Preceding Dyalog, dzaima/APL added support for vector notation with parentheses in 2018, namespaces and function arrays in 2019, and high-rank arrays with square brackets in 2020. BQN supported lists with angle brackets (⟨…⟩) in its initial implementation in 2020; square brackets ([…]) were reserved for high-rank array notation, which was implemented in 2022. TinyAPL follows the same convention, while Uiua, released in 2023, uses curly braces ({…}) rather than angle brackets, and takes advantage of its stack-based execution to leave separators implicit.
Comparison of array notations
The following systems support list or vector notation in some form, beyond simple strand notation. The separators ; in A+ and K, and ⋄ in APL and BQN, indicate any separator, including a line break.
| System | Vectors | High-rank | Namespaces | Function arrays | Assignable |
|---|---|---|---|---|---|
| Nial | [,] |
No | N/A | Special | No |
| A+ | (;) |
No | N/A | First-class | Yes |
| K | (;) |
N/A | [key:val;] |
First-class | Yes |
| BQN[10] | ⟨⋄⟩ |
[⋄] |
{key⇐val⋄} |
First-class | Yes |
| TinyAPL | ⟨⋄⟩ |
[⋄] |
⦃key←val⋄⦄ |
First-class | Yes |
| dzaima/APL | (⋄) |
[⋄] |
(key:val⋄) |
Special | No |
| Acre Desktop[11] | (⋄) |
[⋄] |
[key←val⋄] |
No | N/A |
| Dyalog APL | (⋄) |
[⋄] |
(key:val⋄) |
No | Vectors |
Nial and A+ do not support namespaces, while K does not support high-rank arrays, so any such notation is not applicable. The "Function arrays" column indicates whether functions can be placed in array notation. "First class" indicates that functions are first class, so this is possible without special consideration. "Special" indicates creating a special vectors of functions that can be applied to arguments to return a list of results. The "Assignable" column indicates that array notation can be used as an assignment target to perform destructuring. BQN's namespaces don't use a dedicated construction; instead, any block (like a dfn) with ⇐ statements returns a namespace reference. Acre Desktop only uses array notation for storing literal arrays; it cannot appear in executable code.
Documentation
- Dyalog APL
- BQN (as
⟨⋄⟩,[⋄], and{key⇐val⋄}) - Nial (as
[,]for vectors)
External links
- Formal Proposal document
- Evaluate APL Array Notation sandbox
References
- ↑ Randall Mercer. Strands or Lists?. APL Quote-Quad Volume 12, Number 4. 1982-06.
- ↑ Phil Last. APL Array Notation (transcript). Dyalog '15.
- ↑ Phil Last. A Notation for APL array Embedding and Serialization. Vector Journal, Volume 26, number 4. British APL Association. 2016.
- ↑ Adám Brudzewsky. Literal Notation for Arrays and Namespaces (slides). Dyalog '17.
- ↑ Adám Brudzewsky. Array Notation Mk III. Dyalog '18.
- ↑ Adám Brudzewsky. A Notation for APL Arrays. APL-Journal, Volume 2020, number 1-2. APL-Germany e.V. 2020.
- ↑ Dyalog Ltd. Link User Guide: Creating APL Source Files and Directories. Retrieved 2022-08-24.
- ↑ Adám Brudzewsky. Array Notation RC1 (slides). Dyalog '20.
- ↑ Kromberg, Morten. Formal Proposal for APL Array Notation – Seeking Feedback. Formal Proposal for APL Array Notation – Seeking Feedback. April 21, 2023.
- ↑ Lochbaum, Marshall. BQN: Array notation and display; Array literals. Retrieved 2022-09-01.
- ↑ The Carlisle Group. APL Array Notation. Acre Desktop Wiki. GitHub. Retrieved 2022-09-01.