Array notation: Difference between revisions
(3 intermediate revisions by the same user not shown)  
Line 9:  Line 9:  
== Examples ==  == Examples ==  
Mediumsized array constants are often needed in code. Due to the lack of a native multiline notation, programmers have resorted to various adhoc methods of approximating such, usually at the cost of reduced [[readability]]. A very common technique is repeated [[concatenateconcatenation]]  Mediumsized array constants are often needed in code. Due to the lack of a native multiline notation, programmers have resorted to various adhoc methods of approximating such, usually at the cost of reduced [[readability]]. A very common technique is repeated [[concatenateconcatenation]] resulting in the desired value being held in a variable (<syntaxhighlight lang=apl inline>z</syntaxhighlight> in the below examples), as opposed to array notation which can express the final value directly. In addition, the traditional technique sometimes involves the creation of helper variables as a side effect.  
<syntaxhighlight lang=apl>  
=== Basic arrays ===  
{ class=wikitable  
! Traditional method !! Array notation !! Description  
  
<syntaxhighlight lang=apl>(0 6 1 8)(1 4 1 4 2)(2 7 1 8 2 8)(3 1 4 1 5)</syntaxhighlight>  
<syntaxhighlight lang=apl>(0 6 1 8 ⋄ 1 4 1 4 2 ⋄ 2 7 1 8 2 8 ⋄ 3 1 4 1 5)</syntaxhighlight>  
Vector of numeric vectors on a single line.  
  
<syntaxhighlight lang=apl>z← (0 6 1 8)(1 4 1 4 2)  
z,←(2 7 1 8 2 8)(3 1 4 1 5)</syntaxhighlight>  
<syntaxhighlight lang=apl>(0 6 1 8 ⋄ 1 4 1 4 2  
2 7 1 8 2 8 ⋄ 3 1 4 1 5)</syntaxhighlight>  
Vector of numeric vectors split over two lines.  
  
<syntaxhighlight lang=apl>z←,⊂'Three'  
z,←⊂'Blind'  
z,←⊂'Mice'</syntaxhighlight>  
<syntaxhighlight lang=apl>('Three'  
'Blind'  
'Mice')</syntaxhighlight>  
Vector of character vectors, one on each line. (The traditional method includes an unnecessary <syntaxhighlight lang=apl inline>,</syntaxhighlight> to indicate that <syntaxhighlight lang=apl inline>z</syntaxhighlight> will be a vector.)  
  
<syntaxhighlight lang=apl>z←⍉⍪0 6 1 8  
z⍪← 1 4 1 4  
z⍪← 2 7 1 8  
z⍪← 3 1 4 2</syntaxhighlight>  
<syntaxhighlight lang=apl>[0 6 1 8  
1 4 1 4  
2 7 1 8  
3 1 4 2]</syntaxhighlight>  
Numeric matrix.  
  
<syntaxhighlight lang=apl>z←⍪10  
z⍪←20  
z⍪←30  
z⍪←40</syntaxhighlight>  
<syntaxhighlight lang=apl>[10  
20  
30  
40]</syntaxhighlight>  
Column matrix.  
}  
=== Involved arrays ===  
{ class=wikitable  
! Traditional method !! Array notation !! Description  
  
<syntaxhighlight lang=apl>a←⍉⍪0 0 1  
a⍪← 1 0 1  
a⍪← 0 1 1  
z←,⊂a  
a←⍉⍪0 1 1  
a⍪← 1 1 0  
a⍪← 0 1 0  
z,←⊂a  
a←⍉⍪0 1 1 1  
a⍪← 1 1 1 0  
z,←⊂a  
a←⍉⍪0 1 1 0  
a⍪← 1 0 0 1  
a⍪← 0 1 1 0  
z,←⊂a</syntaxhighlight>  
<syntaxhighlight lang=apl>([0 0 1  
1 0 1  
0 1 1]  
[0 1 1  
1 1 0  
0 1 0]  
[0 1 1 1  
1 1 1 0]  
[0 1 1 0  
1 0 0 1  
0 1 1 0])</syntaxhighlight>  
Vector of matrices.  
  
<syntaxhighlight lang=apl>z←⍉⍪0 'OK'  
z⍪← 1 'WS FULL'  
z⍪← 2 'SYNTAX ERROR'  
z⍪← 3 'INDEX ERROR'  
z⍪← 4 'RANK ERROR'</syntaxhighlight>  
<syntaxhighlight lang=apl>[0 'OK'  
1 'WS FULL'  
2 'SYNTAX ERROR'  
3 'INDEX ERROR'  
4 'RANK ERROR']</syntaxhighlight>  
Table with numeric and text columns.  
  
<syntaxhighlight lang=apl>a←⍉⍪3 1 4  
a⍪← 1 5 0  
a←↑a  
b←⍉⍪2 7 0  
b⍪← 2 0 0  
z←a,[0.5] b</syntaxhighlight>  
<syntaxhighlight lang=apl>[[3 1 4  
1 5 0]  
[2 7 0  
2 0 0]]</syntaxhighlight>  
Rank 3 numeric array.  
  
<syntaxhighlight lang=apl>a←,⊂3 1 4  
a,←⊂1 5  
a←↑a  
b←,⊂2 7  
b,← 2  
b←↑b  
z←↑a b</syntaxhighlight>  
<syntaxhighlight lang=apl>[[3  
1 5 9]  
[2 7  
2]]</syntaxhighlight>  
Rank 3 numeric array relying on automatic padding with [[fill element]].  
  
<syntaxhighlight lang=apl>  
z←⍉⍪'fns' ((0 1)(0.7 0)(0.7 0)×size)  
z⍪← 'fnd' ((0 1)(0 0)(0 0)×size)  
z⍪← 'lines'((0 0)(0.7 0)(0.7 0)×size)  
z⍪← 'lnd' ((0 0)(0 0)(0 0)×size)  
</syntaxhighlight>  </syntaxhighlight>  
<syntaxhighlight lang=apl>  
<syntaxhighlight lang=apl>  ['fns' ((0 1 ⋄ 0.7 0 ⋄ 0.7 0)×size)  
'fnd' ((0 1 ⋄ 0 0 ⋄ 0 0)×size)  
'lines'((0 0 ⋄ 0.7 0 ⋄ 0.7 0)×size)  
'lnd' ((0 0 ⋄ 0 0 ⋄ 0 0)×size)]  
</syntaxhighlight>  </syntaxhighlight>  
Matrix of simple and nested vectors, with dynamic values.  
}  
=== Namespaces ===  
{ class=wikitable  
! Traditional method !! Array notation !! Description  
  
<syntaxhighlight lang=apl>⎕NS⍬</syntaxhighlight>  
<syntaxhighlight lang=apl>()</syntaxhighlight>  
Empty namespace.  
  
<syntaxhighlight lang=apl>⎕NS¨⍬⍬⍬</syntaxhighlight>or<syntaxhighlight lang=apl>(⎕NS⍬)(⎕NS⍬)(⎕NS⍬)</syntaxhighlight>  
<syntaxhighlight lang=apl>()()()</syntaxhighlight>  
Vector of namespaces.  
  
<syntaxhighlight lang=apl>z←⎕NS⍬  
z.x←'hello'</syntaxhighlight>  
<syntaxhighlight lang=apl>(x:'hello')</syntaxhighlight>  
Namespace with character vector member.  
  
<syntaxhighlight lang=apl>z←⎕NS⍬  
z.x←⍉⍪'hello'  
z.x⍪← 'world'</syntaxhighlight>  
<syntaxhighlight lang=apl>(x:['hello'  
'world'])</syntaxhighlight>  
Namespace with character matrix member.  
  
<syntaxhighlight lang=apl>z←⎕NS⍬  
z.y←⎕NS⍬  
z.y.x←⍉⍪'hello'  
z.y.x⍪← 'world'</syntaxhighlight>  
<syntaxhighlight lang=apl>(y:(x:['hello'  
'world']))</syntaxhighlight>  
Nested namespace structure with matrix member.  
  
<syntaxhighlight lang=apl>z←⎕NS⍬  
z.f←+  
a←⎕NS⍬  
a.f←  
z,←a  
a←⎕NS⍬  
a.f←×  
z,←a  
a←⎕NS⍬  
a.f←÷  
z←z.f</syntaxhighlight>  
<syntaxhighlight lang=apl>((f:+)(f:)(f:×)(f:÷)).f</syntaxhighlight>  
[[Function array]].  
}  
[[File:Array notation syntax.pngthumbright[[wikipedia:Railroad diagramRailroad diagram]].]]  [[File:Array notation syntax.pngthumbright[[wikipedia:Railroad diagramRailroad diagram]].]]  
== Specification ==  == Specification ==  
The notation consists of syntax that was invalid before its introduction, thus causing no issues for [[backwards compatibility]]. The added syntax consists of three constructs that are currently [[SYNTAX ERROR]]s:  The notation consists of syntax that was invalid before its introduction, thus causing no issues for [[backwards compatibility]]. The added syntax consists of three constructs that are currently [[SYNTAX ERROR]]s:  
Line 66:  Line 233:  
* [https://mlochbaum.github.io/BQN/doc/arrayrepr.html#arrayliterals BQN] (as <code>⟨⋄⟩</code>, <code>[⋄]</code>, and <code>{key⇐val⋄}</code>)  * [https://mlochbaum.github.io/BQN/doc/arrayrepr.html#arrayliterals BQN] (as <code>⟨⋄⟩</code>, <code>[⋄]</code>, and <code>{key⇐val⋄}</code>)  
* [https://www.nialarraylanguage.org/ndocs/NialDict2.html#bracketcommanotation Nial] (as <code>[,]</code> for vectors)  * [https://www.nialarraylanguage.org/ndocs/NialDict2.html#bracketcommanotation Nial] (as <code>[,]</code> for vectors)  
== External links ==  
* [https://abrudz.github.io/aplan Evaluate APL Array Notation] sandbox  
== References ==  == References ==  
<references/>  <references/>  
{{APL syntax}}[[Category:APL syntax]][[Category:Nested array model]]  {{APL syntax}}[[Category:APL syntax]][[Category:Nested array model]] 
Latest revision as of 08:24, 12 October 2022
Dyalog Ltd requests community feedback on the array notation in the hope of ending up with a notation that is shared with other dialects.^{[1]} Head to the design considerations article for details! 

(⋄) [⋄]

Array notation ((⋄)
, [⋄]
) 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 some tools for Dyalog APL, where it is planned as an eventual language feature.
Array notation generally consists of a vector notation written with parentheses ()
, roughly equivalent to stranding, and a highrank 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
Mediumsized array constants are often needed in code. Due to the lack of a native multiline notation, programmers have resorted to various adhoc methods of approximating such, usually at the cost of reduced readability. A very common technique is repeated concatenation resulting in the desired value being held in a variable (z
in the below examples), as opposed to array notation which can express the final value directly. In addition, the traditional technique sometimes involves the creation of helper variables as a side effect.
Basic arrays
Traditional method  Array notation  Description 

(0 6 1 8)(1 4 1 4 2)(2 7 1 8 2 8)(3 1 4 1 5)

(0 6 1 8 ⋄ 1 4 1 4 2 ⋄ 2 7 1 8 2 8 ⋄ 3 1 4 1 5)

Vector of numeric vectors on a single line. 
z← (0 6 1 8)(1 4 1 4 2)
z,←(2 7 1 8 2 8)(3 1 4 1 5)

(0 6 1 8 ⋄ 1 4 1 4 2
2 7 1 8 2 8 ⋄ 3 1 4 1 5)

Vector of numeric vectors split over two lines. 
z←,⊂'Three'
z,←⊂'Blind'
z,←⊂'Mice'

('Three'
'Blind'
'Mice')

Vector of character vectors, one on each line. (The traditional method includes an unnecessary , to indicate that z will be a vector.)

z←⍉⍪0 6 1 8
z⍪← 1 4 1 4
z⍪← 2 7 1 8
z⍪← 3 1 4 2

[0 6 1 8
1 4 1 4
2 7 1 8
3 1 4 2]

Numeric matrix. 
z←⍪10
z⍪←20
z⍪←30
z⍪←40

[10
20
30
40]

Column matrix. 
Involved arrays
Traditional method  Array notation  Description 

a←⍉⍪0 0 1
a⍪← 1 0 1
a⍪← 0 1 1
z←,⊂a
a←⍉⍪0 1 1
a⍪← 1 1 0
a⍪← 0 1 0
z,←⊂a
a←⍉⍪0 1 1 1
a⍪← 1 1 1 0
z,←⊂a
a←⍉⍪0 1 1 0
a⍪← 1 0 0 1
a⍪← 0 1 1 0
z,←⊂a

([0 0 1
1 0 1
0 1 1]
[0 1 1
1 1 0
0 1 0]
[0 1 1 1
1 1 1 0]
[0 1 1 0
1 0 0 1
0 1 1 0])

Vector of matrices. 
z←⍉⍪0 'OK'
z⍪← 1 'WS FULL'
z⍪← 2 'SYNTAX ERROR'
z⍪← 3 'INDEX ERROR'
z⍪← 4 'RANK ERROR'

[0 'OK'
1 'WS FULL'
2 'SYNTAX ERROR'
3 'INDEX ERROR'
4 'RANK ERROR']

Table with numeric and text columns. 
a←⍉⍪3 1 4
a⍪← 1 5 0
a←↑a
b←⍉⍪2 7 0
b⍪← 2 0 0
z←a,[0.5] b

[[3 1 4
1 5 0]
[2 7 0
2 0 0]]

Rank 3 numeric array. 
a←,⊂3 1 4
a,←⊂1 5
a←↑a
b←,⊂2 7
b,← 2
b←↑b
z←↑a b

[[3
1 5 9]
[2 7
2]]

Rank 3 numeric array relying on automatic padding with fill element. 
z←⍉⍪'fns' ((0 1)(0.7 0)(0.7 0)×size)
z⍪← 'fnd' ((0 1)(0 0)(0 0)×size)
z⍪← 'lines'((0 0)(0.7 0)(0.7 0)×size)
z⍪← 'lnd' ((0 0)(0 0)(0 0)×size)

['fns' ((0 1 ⋄ 0.7 0 ⋄ 0.7 0)×size)
'fnd' ((0 1 ⋄ 0 0 ⋄ 0 0)×size)
'lines'((0 0 ⋄ 0.7 0 ⋄ 0.7 0)×size)
'lnd' ((0 0 ⋄ 0 0 ⋄ 0 0)×size)]

Matrix of simple and nested vectors, with dynamic values. 
Namespaces
Traditional method  Array notation  Description 

⎕NS⍬

()

Empty namespace. 
⎕NS¨⍬⍬⍬
(⎕NS⍬)(⎕NS⍬)(⎕NS⍬)

()()()

Vector of namespaces. 
z←⎕NS⍬
z.x←'hello'

(x:'hello')

Namespace with character vector member. 
z←⎕NS⍬
z.x←⍉⍪'hello'
z.x⍪← 'world'

(x:['hello'
'world'])

Namespace with character matrix member. 
z←⎕NS⍬
z.y←⎕NS⍬
z.y.x←⍉⍪'hello'
z.y.x⍪← 'world'

(y:(x:['hello'
'world']))

Nested namespace structure with matrix member. 
z←⎕NS⍬
z.f←+
a←⎕NS⍬
a.f←
z,←a
a←⎕NS⍬
a.f←×
z,←a
a←⎕NS⍬
a.f←÷
z←z.f

((f:+)(f:)(f:×)(f:÷)).f

Function array. 
Specification
The notation consists of syntax that was invalid before its introduction, thus causing no issues for backwards compatibility. The added syntax consists of three constructs that are currently SYNTAX ERRORs:
 broken round parentheses:
(
…)
 broken square brackets:
[
…]
 empty round parentheses:
()
where broken means interrupted by one or more diamonds (⋄
) or line breaks (outside of dfns).
 A broken round parenthesis creates a namespace if every diamond/line breakseparated statement is a namevalue pair.
 A broken round parenthesis creates a vector if every diamond/line breakseparated statement is a value expression. In that case, every such statement forms an element in the resulting vector.
 A broken square bracket creates a an array where every diamond/line breakseparated statement forms a major cell in the resulting array.*
()
creates a new namespace — equivalent to(⎕NS 0⍴⊂'')
 A namevalue pair consists of a valid APL identifier, followed by a colon (
:
) and a value expression.
* This rule is followed strictly in dzaima/APL, while Dyalog APL considers each statement to have a rank of at least 1, even if it is a scalar.
Formal syntax
The array notation can be described using Extended Backus–Naur form, where an expression
is any traditional APL expression:
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
Onedimensional 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 squarebracket 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.
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 highrank 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. He also used the design in Acre Desktop, a project manager for Dyalog APL, to support storing constant arrays and namespaces in text files. Following the conference presentation, Adám Brudzewsky began work on array notation and presented on it in a series of conferences, initially using parentheses for the highrank notation^{[4]} and later returning to square brackets.^{[5]}^{[6]} Because Last's use of ←
to separate namespace keys from values prevented lists from including arbitrary expressions (which might contain assignment), he proposed a change to :
as in JSON. 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]}
The project manager Acre Desktop added support for the nonnamespace parts of the notation in early 2018, together with Phil Last's original namespace notation, using square brackets and assignment arrow. dzaima/APL added support for vector notation with parentheses in 2018, namespaces and function arrays in 2019, and highrank arrays with square brackets in 2020. BQN supported lists with angle brackets (⟨
…⟩
) in its initial implementation in 2020; square brackets ([
…]
) were reserved for highrank array notation, which was implemented in 2022.
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  Highrank  Namespaces  Function arrays  Assignable 

Nial  [,] 
No  N/A  Special  No 
A+  (;) 
No  N/A  Firstclass  Yes 
K  (;) 
N/A  [key:val;] 
Firstclass  Yes 
BQN^{[9]}  ⟨⋄⟩ 
[⋄] 
{key⇐val⋄} 
Firstclass  Yes 
dzaima/APL  (⋄) 
[⋄] 
(key:val⋄) 
Special  No 
Dyalog Link  (⋄) 
[⋄] 
(key:val⋄) 
No  No 
Acre Desktop^{[10]}  (⋄) 
[⋄] 
[key←val⋄] 
No  N/A 
Nial and A+ do not support namespaces, while K does not support highrank 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
External links
 Evaluate APL Array Notation sandbox
References
 ↑ Dyalog Ltd/Adám Brudzewsky. Re: Deserialise does it work as expected?. Dyalog Forums. 20220905.
 ↑ 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. APLJournal, Volume 2020, number 12. APLGermany e.V. 2020.
 ↑ Dyalog Ltd. Link User Guide: Creating APL Source Files and Directories. Retrieved 20220824.
 ↑ Adám Brudzewsky. Array Notation RC1 (slides). Dyalog '20.
 ↑ Lochbaum, Marshall. BQN: Array notation and display; Array literals. Retrieved 20220901.
 ↑ The Carlisle Group. APL Array Notation. Acre Desktop Wiki. GitHub. Retrieved 20220901.